Program doesn't stop when "ctrl c" is used to terminate program - c++

I have a programme (C++ compiled) that using tcp socket to communicated. The programme is configured in two mode. Let's say mode A and mode B.
Start the programme mode A, it will give some prints like:
waiting connections on port 1234
local endpoint : 0.0.0.0:1234
//I think it is using boost for TCP socket
Then start mode B. They will find each other and run perfect.
Question is if I start mode A, and then use "ctrl c" to terminate the application with mode A. It will left the port open there.
When I start the mode B, it will also find the connection and runs with error due to A is not there.
I have a bash to run the application, I want to ask how I can force that port to close? (In bash or other possible way)
Thanks

Use this in the bash script (before calling your binary):
trap "fuser -k -n tcp 1234 && exit" SIGINT SIGTERM

Related

Sending parameters through ssh. Are there NON-BLOCKING input functions?

I am working with an embedded system in which a Linux-based OS is running. Let's say that an application is running and the behavior needs to change when some actions happen. I did it using buttons and switches on the board but I have no idea on how to do it via ssh where the output of the application is constantly prompt. Any suggestion? Is it possible to use the keyboard of the laptop to send parameters at runtime only if a keyboard-button is pressed? (let's imagine I want to press only the + and the -). Of course, the output of the application should continue to be prompt constantly.
Of course the solution cin << will not work because it stops the execution until the new parameter is set up. The aim should be "change behavior if and only if + or - are pressed".
Use signals. Register a signal handler in your program and signal it from the outside with pkill -<SIGNAL> -f <PROGRAM> or kill -<SIGNAL> <PID>. For instance:
ssh user#server pkill -USR1 -f my_program

Netcat on remote machine using ssh

I was trying to run netcat by using ssh and seems that my code always fails in my C code. Here are the commands which I am executing using system() in this order.
system("ssh machine 'nc -l 61001|dd bs=64M of=temp' &")
system("/bin/dd if=filename bs=64M|nc IP_address 61001")
I noticed that the first command works correctly as the temp file is created on the remote machine. The second dd command fails and states that 0 bytes has been written on the remote machine. These commands work correctly when executed from the terminal, but fail as soon as I put it in system() calls in C.
Short answer:
a & disown (instead of just &) should do.
Explanation:
system() spawns a shell that just executes one command and then exits. The & tells the shell to fork the command into background (means, it doesn't wait for its completion), but it's still part of the session and process group of the shell. When the group leader (the shell) exits, all children are killed. The disown causes the shell to start new process group, the child process is now owned by init (the first process in the system).
"Real" answer:
This is about programming. You are forking processes like crazy to accomplish something a C program could easily do using builtin library calls (except for the ssh but there are better ways, too). Go read on BSD sockets.

Program works in foreground, but not in background using nohup

I am currently writing a server backend for my iOS game. The server is written in C++ and compiled & run on a remove Ubuntu Server. I start the server through SSH using
sudo nohup ./mygameserver &
The server communications is written in TCP. The main function with the read-loop is written using standard C socket.h/netdb.h/in.h, and uses select() to accept many users on a nonblocking listening socket.
When I run the server in the foreground through SSH, everything seems to be working fine. It receives all packets I send in the right order, and with correct header info. When I use nohup and disconnect from SSH however... Everything seems to crash. A typical log from a user connect when the server software runs without SSH/in nohup mode looks like this:
CONNECTED TO SQL
Server starting...
Second thread initialized
Entering order loop
Got a new message of type: 0
Got a new message of type: 0
Got a new message of type: 0
Got a new message of type: 0
<this line continues ad infinitum>
I really have no idea why. I've made sure every print goes to nohup.out instead of std::cout, and the server sends an update to MySQL every 10 seconds to avoid timeouts.
Any ideas or input on what's wrong here? Let me know if you want some code samples, I just don't know which ones are interesting to this problem in particular. Thanks in advance.
I found out what was wrong.
In my server program I have a readSockets() function which is called after a call to select() in the main server loop. The readSockets() function responded to newline character pushed to stdin (for reasons I don't know) by nohup on startup, and as stdin is, in fact, also a FILE* connected to a file descriptor, my readSockets() function responded to stdin as a connecting client.
This obviously made the server crash, as stdin was never flushed (and was therefore read every time select() had returned). This again blocked the thread for other users.

socket not released after service restart

There is:
A: program that holds open socket
B: watch dog script running as service :
while true
do
if [ -z "`pidofproc $1`" ]; then
$1;
chrt -f -p 40 `pidofproc $1`
sleep 8
fi;
sleep 2
done
when service started - watch dog started
when service stopped - watch dog and program are killed (killall).
now program wants to upgrade itself, so it calls system( "upgrade.sh" );
upgrade.sh:
/sbin/service watchdog stop
.... install upgrade .....
exec /sbin/service watchdog start &
upgrade performed successfully, but when program starts - can't open socket (already in use) - on this error - program quits (to be restarted by watch dog).
lsof -i shows three programs on the port:
watchdog
program
sleep
program and sleep pids always change (i.e. quit/restart behavior)
watchdog pid persistant.
i tried to replace system(...), with
if(!fork()) exec(...) , but same problem remains.
Depending on how fast the restart happens after the shut down, the socket will be lingering around. Linux, by default, keeps sockets marked as in use for some time after they've been released (either by close() or when the process dies) to make sure that incoming connection attempts or data which is late due to network latencies won't end up at the wrong application.
This has to be fixed inside the application. It is required to set the SO_REUSEADDR sockopt. As per the manpage of socket(7):
Indicates that the rules used in validating addresses supplied
in a bind(2) call should allow reuse of local addresses. For
AF_INET sockets this means that a socket may bind, except when
there is an active listening socket bound to the address. When
the listening socket is bound to INADDR_ANY with a specific port
then it is not possible to bind to this port for any local
address. Argument is an integer boolean flag.
This has to be set using setsockopt after the socket was created.

How to unplug a USB device under Ubuntu and C/C++ without rebooting

I'm using a C program with termios to exchange information and commands between my pc with Ubuntu and a USB motor controller.
It works great and i'm able to successfully send messages over the serial port; however, sometimes it happens that if i close the program in the wrong way or something else happens, i'm not able any more to reconnect to my usb device.
To be able to connect again to the device, i have to reboot my pc and start again ubuntu.
I'd like to avoid this problem and to find a solution to enable again the usb port without have to reboot my system each time.
At the first time, i tried to kill all the processes (sudo killall -9 program_name) that were using the usb port, but the port still remains blocked and i have to reboot it.
Can you suggest me some solutions to avoid the reboot, please?
And why it happens?
I connect to the usb port (/dev/ttyACM0) in this way:
handle = open(port.c_str(), O_RDWR |O_NOCTTY | O_NDELAY);
if(handle == RQ_INVALID_HANDLE)
{
cout<<"failed."<<endl;
return RQ_ERR_OPEN_PORT;
}
To avoid making your USB-Controller unusable, you can harden your program to better deal with program termination.
Create a routine, that does your cleaning up, i.e., closing the USB connection.
Let's call it void cleanup(void) {}
You can use the atexit function from stdlib.h to register a function, that will be called when the program terminates normally. That means through either exit or return in main. See atexit man page
E.g.: int res = atexit(cleanup);
For cases, where your program is terminated irregularly, like through a signal (e.g., SIGINT when you hit Ctrl+c), you have to implement signal handlers to deal with this. Basically you can create one signal handler function, that only calls your cleanup routine and register it to all the signals you want to deal with.
More details on how to do that: signal handler tutorial
If your program was terminated in a way, that can not be handled, e.g., with SIGKILL, you'll either have to reboot or look at the methods in the post that pmg has linked to in his comment - they look promising.