Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

select failed: Interrupted system call

69 views
Skip to first unread message

Patrick Coghlan

unread,
Mar 24, 1994, 9:27:10 AM3/24/94
to
I have a 1-second interval timer running in my application and I catch
the SIGALRM signal for it.

The documentation for signal says that the process will resume
execution at the point where it was interrupted, although some
READ/WRITE etc. to SLOW devices (not files) will fail.

Well, I am using SELECT to suspend my application for 100 ms
while polling and I get "select failed: Interrupted system call"
messages every time the interval timer goes off (my application is
usually suspended). I don't mind the select() failing, but I don't
want this silly message being displayed.

How do I get rid of it?

Guenther Kramer

unread,
Mar 24, 1994, 12:01:56 PM3/24/94
to
In article <1994Mar24.1...@bcarh54a.bnr.ca>,

Who is displaying the message? It sounds like that your code is doing the
select() and hence issuing a perror() if select failed. The suggested way to
structure select code is as follows:

while (...) {
if ((n = select(....)) < 0) {
/* Anything but EINTR is bad. */
if (errno != EINTR) {
perror("select");
... do your error handling ...
}
... fall through ...
}
else if (n == 0) {
... timeout handling ...
}
else {
... file descriptor activity handling ...
}
}

You will probably need simillar code to handle any network read or write
calls since read()/write() are considered SLOW on networks. For example,
read() would be something like:

/* socket read which handles EINTR. */
int
sreadn(int fd, void *vptr, int n)
{
int left, bytes;
char *ptr = vptr;

left = n;
while (left > 0) {
if ((bytes = read(fd, ptr, left)) < 0) {
if (errno == EINTR)
continue;
return bytes;
}
else if (bytes == 0)
break;

left -= bytes;
ptr += bytes;
}
return (n - left);
}


Similar code would be required for write(). Also watch out for: pause(),
wait() and friends, and lots of the SYSV IPC functions.

If you are uncertain about a system call, check the ERRORS section of the
corresponding man page and see if EINTR is possible.

All of this stuff would be so much simpler if HP-UX supported the SA_RESTART
flag to sigaction(). Oh well.

--
Guenther Kramer, 4C31 IDE core development
Internet: kra...@bnr.ca Bell-Northern Research, Ottawa, Canada.
#include <std.disclaimer.h>

John Hascall

unread,
Mar 24, 1994, 12:28:24 PM3/24/94
to


Presumably, you have code something like this:

switch (select(...)) {
case -1:
perror("select failed");
:

Try something like this:

switch (select(...)) {
case -1:
if (errno != EINTR) perror("select failed");
:

(be sure to #include <errno.h> too).

John
--
John Hascall ``An ill-chosen word is the fool's messenger.''
Systems Software Engineer
Project Vincent
Iowa State University Computation Center + Ames, IA 50011 + 515/294-9551

Hamish Macdonald

unread,
Mar 24, 1994, 2:22:06 PM3/24/94
to
>>>>> On 24 Mar 1994 12:01:56 EST,
>>>>> In message <1994Mar24.1...@bcarh54a.bnr.ca>,
>>>>> kra...@bnr.ca (Guenther Kramer) wrote:

Guenther> All of this stuff would be so much simpler if HP-UX
Guenther> supported the SA_RESTART flag to sigaction(). Oh well.

Check out sigvector(2).

Rick Johns

unread,
Mar 24, 1994, 2:37:59 PM3/24/94
to
|> Patrick Coghlan <cog...@bcarh5f8.bnr.ca> wrote:
|> I have a 1-second interval timer running in my application and I catch
|> the SIGALRM signal for it.
|>
|> The documentation for signal says that the process will resume
|> execution at the point where it was interrupted, although some
|> READ/WRITE etc. to SLOW devices (not files) will fail.
|>
|> Well, I am using SELECT to suspend my application for 100 ms
|> while polling and I get "select failed: Interrupted system call"
|> messages every time the interval timer goes off (my application is
|> usually suspended). I don't mind the select() failing, but I don't
|> want this silly message being displayed.

Try setting the sigcontext sc_syscall_action field to SIG_RESTART in
the handler. That allows the system call to restart, which should
avoid the problem. I think this is an HP-specific thing, though.

--
Cheers,
Rick Johns
BNR
rjo...@bnr.ca

Disclaimer: I said it, BNR didn't.

Rick Johns

unread,
Mar 24, 1994, 3:44:37 PM3/24/94
to

From sigvector(2):

WARNINGS
Restarting a select(2) call can sometimes cause unexpected results.
If the select() call has a timeout specified, the timeout is restarted
with the call, ignoring any portion that had elapsed prior to
interruption by the signal. Normally this simply extends the timeout
and is not a problem. However, if a handler repeatedly catches
signals, and the timeout specified to select() is longer than the time
between those signals, restarting the select() call effectively
renders the timeout infinite.

Oops.

Guenther Kramer

unread,
Mar 24, 1994, 5:43:22 PM3/24/94
to
In article <2msp8u$l...@bmerha64.bnr.ca>,

I have. 'sigaction()' provides all the functionallity of 'sigvector()'
with the added bonus of being POSIX compliant. The main difference that I
can see is that 'sigaction()' behaves as though 'SV_BSDSIG' is always set
and has a flag 'SA_NOCLDSTOP' to disable it. (POSIX made it portable by
removing the "BSD" sub-string from the name. :-)

The problem is that under HP-UX, there is no way to tell the signal system
to AUTOMATICALLY re-start all system calls for a given signal. The SA_RESTART
flag to sigaction() can be used on some systems to define this behaviour.
(Most notably SYSV4 and BSD4.3) This is a bit supprising to me since HP
decided to support 3 or 4 different signal interfaces but did not support
this very common flag.

I could use sigaction() and install handlers for the signals I cared
about and mess around with restarting the system calls by checking the
'sc_syscall' and 'sc_syscall_action' fields, but this is a mess and not
very portable. On top of that, the sigvector() man page warns that
re-starting 'select()' could be un-reliable. Since the original poster was
concerned about select(), I felt the EINTR approach would be the best.

0 new messages