bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: EINTR


From: Bruno Haible
Subject: Re: EINTR
Date: Sun, 3 Jul 2011 17:36:30 +0200
User-agent: KMail/1.9.9

Hi all,

I wrote:
> ... in programs that don't install signal handlers, EINTR ... also occurs in
> MacOS X!

It is worse than that:

1) Even on Linux, even when the signal handlers have the SA_RESTART flag set,
   some system call (like msgrcv(), but not read()) can fail with EINTR.
   See [1].

2) On all systems, when a signal handler has the SA_RESTART flag cleared,
   not only the read() system call will fail with EINTR, but also an fread()
   call will fail and set the stream's error bit.

   POSIX specifies it like this: [2]

   Test case: [3]. Run it, type Hello<Return> then Ctrl-C. Result is:

   $ ./a.out
   Hello
   ^CSIGINT!
   fread: Interrupted system call
   Hello

   Tested on Linux, MacOS X, FreeBSD, OpenBSD, AIX, HP-UX, IRIX, OSF/1,
   Solaris, Cygwin.

3) On MacOS X, SIGSTOP and SIGCONT make not only read() fail with EINTR, but
   fread() as well.

   Test case: [3]. Run it, type Hello<Return> then Ctrl-Z then fg. Result is:

   $ ./a.out
   Hello
   ^Z
   [1]+  Stopped                 ./a.out
   $ fg
   ./a.out
   fread: Interrupted system call
   Hello

   $ ./a.out --unbuffered
   Hello
   Hello
   ^Z
   [1]+  Stopped                 ./a.out --unbuffered
   $ fg
   ./a.out --unbuffered
   fread: Interrupted system call

   This was also reported in [4].

   I would expect that EINTR also occurs in write() and fwrite() when writing
   to a pipe that is temporarily full, but I can't easily reproduce this.

I think we need safe_fread() and safe_fgetc() functions. What do you think?

Bruno


[1] 
http://us.generation-nt.com/sigstop-interrupted-system-call-help-183657841.html
[2] http://pubs.opengroup.org/onlinepubs/9699919799/functions/fread.html
[3]
=============================================================================
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

static void handler (int sig) { write (1, "SIGINT!\n", 8); }

int
main (int argc, char *argv[])
{
  int unbuffered = (argc > 1 && strcmp (argv[1], "--unbuffered") == 0);
  signal (SIGINT, handler);
  siginterrupt (SIGINT, 1);
  for (;;)
    {
      char buf[4096];
      size_t bufsize = (unbuffered ? 1 : sizeof (buf));
      size_t count;
      errno = 0;
      count = fread (buf, 1, bufsize, stdin);
      if (count < bufsize && errno != 0)
        perror ("fread");
      if (count > 0)
        fwrite (buf, 1, count, stdout);
      if (count < bufsize)
        break;
    }
  return 0;
}
=============================================================================
[4] 
http://factor-language.blogspot.com/2010/09/two-things-every-unix-developer-should.html
-- 
In memoriam Yuri Shchekochikhin 
<http://en.wikipedia.org/wiki/Yuri_Shchekochikhin>



reply via email to

[Prev in Thread] Current Thread [Next in Thread]