I have a server process, and this server process can be given a command to update itself. What it does is store the update and then use system() to run an update script in the background. The update script kills the parent process, deletes the binary, replaces it, and then restarts it.
The restarted process has failed for various reasons as I have tried to debug it, but this time, it's because a TCP port I'm trying to allocate is already in use. I'm guessing that the child process inherits the open port, which is then inherited by the updated server process, and as a result, the port isn't free for the process to allocate it again.
The way the update script is launched is this:
system("/usr/local/bin/update_script.sh > /dev/null 2>&1 &");
Then the script does this:
killall server_process
rm /usr/local/bin/server_process
cp /tmp/update/server_process /usr/local/bin
server_process > /dev/null 2>&1 &
Any suggestions on how I might make this work? Is there some way I can detach the update script so that the server process is no longer its parent before it performs the update? Or make the child process not inherit any of the parent's resources?
Thanks.
Addendum: A solution would be to set FD_CLOEXEC
on every open file descriptor. Unfortunately, some of those fd's are buried in libraries, which I'd have to seriously hack up in order to make them set FD_CLOEXEC
. Somehow, I need to make FD_CLOEXEC
the default. Or I need to do something drastic, like iterate over all open fd's (how?) and set FD_CLOEXEC
.
Change the way the update script is started.
switch(fork()) {
case -1: /* error */
break;
default: /* parent */
break;
case 0: /* child */
for (i=3; i<1000; i++) close(i);
system("/usr/local/bin/update_script.sh > /dev/null 2>&1");
exit(0);
}
That should do it.