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:

Previous
From: Kevin Brown
Date:
Subject: Re: Question about Ctrl-C and less
Next
From: "Sean Utt"
Date:
Subject: Re: Question about Ctrl-C and less