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?
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>
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
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).
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.
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.
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.