signals and read blocking - EINTR
Jim Easton
jim@cs.ualberta.ca
Tue Nov 1 03:49:00 GMT 2005
Hi,
Correct me if I'm wrong but it is my understanding that a signal,
specifically SIGALRM, should free a blocked read request and,
for example, getchar() or read(), should return an EINTR error.
(viz. Interrupted system call)
This happens on Solaris, sun 4, Sgi and AIX machines but apparently
not on Cygwin, or Red Hat Linux of any release that I have tested
(Scientific Linux SL Release 4.0 and Red Hat Linux release 9).
In fact the solaris man page for read states explicitly:
If a read() is interrupted by a signal before it reads any
data, it will return -1 with errno set to EINTR.
I have no desire to turn off blocking and poll for input as
this adds one to the machine's load average. I can almost do
what I need with "select" - not quite.
I'm wondering what am I missing? Is there a flag in sigaction
or something else that I could be setting? Perhaps there is
something I can do in the service routine to break the block?
If this is discussed somewhere on the web I would be beholden if
someone would point me to it.
Following is a little demo program that will run on the afore
mentioned systems (except the sun4 needs a bit of tweeking)
The difference between, say, solaris and cygwin is that getchar
does not return unless one types in a character.
If anyone is interested this in reference to a printer driver
I am trying to port to linux.
Jim
/* a test of alarm signal and read */
#include <stdio.h>
#include <sys/time.h>
#include <signal.h>
struct itimerval tick;
struct itimerval left;
struct itimerval save;
struct itimerval zero;
struct sigaction act;
void timer (nn)
int nn;
{
fprintf (stderr, "in timer, arg is %d\n\r", nn);
signal (SIGALRM, timer);
tick.it_value.tv_usec -= tick.it_value.tv_usec/300;
setitimer (0, &tick, &save);
}
main() {
int c;
/* tick.it_interval.tv_sec = 0;
* tick.it_interval.tv_usec = 999999;
*/
tick.it_value.tv_sec = 0;
tick.it_value.tv_usec = 999999;
zero.it_value.tv_sec = 0;
zero.it_value.tv_usec = 0;
signal (SIGALRM, timer);
setitimer (0, &tick, 0);
system ("/bin/stty raw -echo");
for (;;) {
fprintf (stderr, "\n\rabout to read getchar\n\r");
c = getchar();
fprintf (stderr, "input c is %d %c\n\r", c, c);
getitimer (0, &left);
fprintf (stderr, "value in timer is %d %d\n\r",
left.it_value.tv_sec, left.it_value.tv_usec);
if (c == 's') setitimer (0, &zero, &save);
if (c == 'g') setitimer (0, &save, NULL);
if (c == 'q') break;
fprintf (stderr, "saved value is %d %d\n\r",
save.it_value.tv_sec, save.it_value.tv_usec);
getitimer (0, &left);
fprintf (stderr, "value in timer is %d %d\n\r",
left.it_value.tv_sec, left.it_value.tv_usec);
}
system ("/bin/stty -raw echo");
}
--
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
Problem reports: http://cygwin.com/problems.html
Documentation: http://cygwin.com/docs.html
FAQ: http://cygwin.com/faq/
More information about the Cygwin
mailing list