Skip to content
Snippets Groups Projects
Commit e1f93e5c authored by Rob Swindell's avatar Rob Swindell :speech_balloon:
Browse files

When user hangs-up on external programs on *nix, try to terminate w/SIGTERM

Previously, when a user disconnected or ran out of time while running a
stdio-based external program on *nix, if the program was still running, we'd
send it a SIGHUP, wait up to 10 seconds for the process to terminate and if
it did not, terminate it (ungracefully) with SIGKILL. Since some programs
catch SIGTERM (and not SIGHUP) to indicate a termination request, we now will
first attempt a SIGHUP, wait up to 5 seconds for the process to terminate and
if it does not, then send a SIGTERM and wait up to another 5 seconds for it
to terminate and if it doesn't, then finally send it a SIGKILL (which cannot
be caught and always results in an ungraceful termination of the child
process).

This doesn't resolve any specific problem with any specific stdio-based
external program, but I was playing around with ESR's port of Adventure
(https://gitlab.com/esr/open-adventure) and a new auto-save/restore of game
state and noticed that we weren't using SIGTERM for this situation, though we
should have. Most modern programs, if they catch SIGHUP at all, use it to
indicate a refresh of configuration or data files, not a termination request
(or indication that a user has "hung up"). So SIGTERM is more reasonable to be
expected to be caught and initiate the graceful termination of the child
program that we're hoping for.
parent c3283568
No related branches found
No related tags found
No related merge requests found
...@@ -1847,14 +1847,23 @@ int sbbs_t::external(const char* cmdline, long mode, const char* startup_dir) ...@@ -1847,14 +1847,23 @@ int sbbs_t::external(const char* cmdline, long mode, const char* startup_dir)
if(waitpid(pid, &i, WNOHANG)==0) { // Child still running? if(waitpid(pid, &i, WNOHANG)==0) { // Child still running?
kill(pid, SIGHUP); // Tell child user has hung up kill(pid, SIGHUP); // Tell child user has hung up
time_t start=time(NULL); // Wait up to 10 seconds time_t start=time(NULL); // Wait up to 5 seconds
while(time(NULL)-start<10) { // for child to terminate while(time(NULL)-start<5 ) { // for child to terminate
if(waitpid(pid, &i, WNOHANG)!=0)
break;
mswait(500);
}
if(waitpid(pid, &i, WNOHANG)==0) { // Child still running?
kill(pid, SIGTERM); // terminate child process (gracefully)
start=time(NULL); // Wait up to 5 (more) seconds
while(time(NULL)-start<5 ) { // for child to terminate
if(waitpid(pid, &i, WNOHANG)!=0) if(waitpid(pid, &i, WNOHANG)!=0)
break; break;
mswait(500); mswait(500);
} }
if(waitpid(pid, &i, WNOHANG)==0)// Child still running? if(waitpid(pid, &i, WNOHANG)==0)// Child still running?
kill(pid, SIGKILL); // terminate child process kill(pid, SIGKILL); // terminate child process (ungracefully)
}
} }
/* close unneeded descriptors */ /* close unneeded descriptors */
if(mode&EX_STDIN) if(mode&EX_STDIN)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment