patch to make script(1) exit cleanly on reciept of signal
Matthew Dillon
dillon at apollo.backplane.com
Sat Mar 27 23:23:22 PST 2004
:Subject says it all - patch is available here:
:
:http://catseye.webhop.net/DragonFlyBSD/patch/script.diff
:
:This basically means that, if you are running script(1) and you type
:'killall script' in another terminal, or otherwise kill the script
:process in a non-drastic way, the typescript file will be flushed, and
:the script program's controlling terminal will be reset to the usual
:non-raw state.
:
:I'm open to further suggestions on how to improve script(1)'s behaviour
:in these circumstances; in their absence I'll give it three days.
:
:-Chris
Signal handlers are difficult to do right. So, for example, what
happens if the signal were to occur just *BEFORE* the select() ?
The answer is: script would not exit at all.
You could interlock the select, like this:
volatile int sigcanexit;
volatile int sigtermed;
...
sigcanexit = 1;
n = select(master + 1, ...)
sigcanexit = 0;
if (sigtermed)
break;
sighndl(int signo)
{
sigtermed = signo;
if (sigcanexit) /* safe to exit from signal handler */
exit(1);
}
Another option would be to make the timeval passed to select() a
global and allow the signal handler to override it, so if the signal
occurs just before the select() the select() will timeout quickly and
fall through to the sigtermed exit case.
volatile int sigtermd_interlock;
volatile int sigtermed;
volatile struct timeval globtv;
...
sigtermd_interlock = 1;
if (flushtime) {
globtv.tv_sec = flushtime;
globtv.tv_usec = 0;
} else {
globtv.tv_sec = 30 * 60;
globtv.tv_usec = 0;
}
sigtermd_interlock = 0;
if (sigtermed)
break;
select (.... &globtv);
if (sigtermed)
break;
...
sighndl(int signo)
{
sigtermed = signo;
if (sigtermd_interlock == 0) {
globtv.tv_sec = 0;
globtv.tv_usec = 0;
}
}
Neither option is pretty but if I were to have to choose I would probably
choose option #2.
-Matt
Matthew Dillon
<dillon at xxxxxxxxxxxxx>
More information about the Submit
mailing list