Re: Question about Ctrl-C and less - Mailing list pgsql-hackers
From | Kevin Brown |
---|---|
Subject | Re: Question about Ctrl-C and less |
Date | |
Msg-id | 20051022002848.GF14950@filer Whole thread Raw |
In response to | Re: Question about Ctrl-C and less (Andrew - Supernews <andrew+nonews@supernews.com>) |
Responses |
Re: Question about Ctrl-C and less
|
List | pgsql-hackers |
Andrew - Supernews wrote: > On 2005-10-19, Kevin Brown <kevin@sysexperts.com> wrote: > > Making assumptions about what the pager will do upon receipt of SIGINT > > is folly as well. > > > > Setting up SIGINT to be ignored may be the right answer (I don't > > believe it is -- see below), but if so then it needs to be done > > properly. If it gets ignored prior to the popen(), then the child > > will also end up ignoring it by default, because signal disposition is > > inherited by child processes. If we ignore SIGINT, it should be after > > the popen(), not before. > > I do not believe it is possible to do the signal disposition correctly > and still use popen() to run the pager. (You would need to reimplement > popen using raw syscalls.) I'm not sure I see why this is so. popen() just creates the pipeline, fork()s, closes the proper file descriptor (depending on whether it's in the parent or the child and whether the pipe was open for read or write) and then exec()s in the child. In the parent, it returns control after the fork() and file descriptor cleanup. So the parent can set up its own internal signal disposition immediately after popen() returns. This sequence of events is exactly what we'd end up doing if we did everything ourselves using raw syscalls, save for the use of stdio instead of direct syscalls for the file operations. > > So I think the right answer here is for psql to handle SIGINT > > internally by doing a pclose() first > > The chances that psql can do this safely approach zero. pclose() is not a > signal-safe function, so it can only be called from a signal handler if > you _know_ that the signal did not interrupt any non-signal-safe function. > (Nor can the signal handler longjmp out in such a case, unless the code is > never again going to call any unsafe function.) I agree. I guess I need to be a little more explicit about what I envision here. There would be two possible signal handlers. The first is the one we have now, which cleans up various things upon receipt of SIGINT. The second simply sets a flag that says that SIGINT has been received. The signal handler that gets assigned to SIGINT depends on whether or not a pager is going to be used. If it's not, then we point it to the first signal handler. If it is, then we point it to the second, and clear the flag. When a pager is being used, we check for the flag immediately after doing a write()/fwrite() to the pipe. If it's set, we pclose(), clear the flag, and then manually invoke the non-pager signal handler. SIGINT should cause the write() to return immediately, possibly with EINTR. Make sense? -- Kevin Brown kevin@sysexperts.com
pgsql-hackers by date: