freetds AT lists.ibiblio.org
Subject: FreeTDS Development Group
List archive
- From: "James K. Lowden" <jklowden AT freetds.org>
- To: TDS Development Group <freetds AT lists.ibiblio.org>
- Subject: [freetds] EINTR bug solved
- Date: Tue, 23 Oct 2007 22:49:47 -0400
(If you didn't know there was an EINTR bug, you're not alone.)
I just committed a new version of src/tds/net.c::tds_select(). The old
version incorrectly dropped to an assert(rc == 0) when trying to handle
EINTR, such as is produced when pressing ^C (sending SIGINT) in sqsh or
fisql. The new version permits these programs to work correctly.
On receipt of a signal, select(2) returns an error and errno is set to
EINTR. The descriptor sets are unmodified, meaning select can be called
again without reinitializing anything. However, whether or not that's the
right thing to do depends on the signal caught and how the application
handles it.
When EINTR is detected, tds_select() treats it like a timeout. If an
interrupt handler was installed, it's called, and the application can
thereby indicate whether to retry or abort. If retry, select(2) is called
again, just as though nothing ever happened.
I also simplified the code somewhat. It's important we do *not* call e.g.
gettimeofday() within the poll loop. The right thing to do is simply to
count down the seconds, because the system's time can change. If it does,
we don't want to change the application's timeout. (The timeout is
counted in seconds, not as a time of day.)
db-lib interrupt handling is still a little rough around the edges. fisql
stays on its feet after ^C, but only after printing a bogus error message.
--jkl
- [freetds] EINTR bug solved, James K. Lowden, 10/23/2007
Archive powered by MHonArc 2.6.24.