Checking if errno != EINTR: what does it mean?

43,692

Solution 1

Many system calls will report the EINTR error code if a signal occurred while the system call was in progress. No error actually occurred, it's just reported that way because the system isn't able to resume the system call automatically. This coding pattern simply retries the system call when this happens, to ignore the interrupt.

For instance, this might happen if the program makes use of alarm() to run some code asynchronously when a timer runs out. If the timeout occurs while the program is calling write(), we just want to retry the system call (aka read/write, etc).

Solution 2

the answers here are really good and i want to add some internal details :

System calls that are interrupted by signals can either abort and return EINTR or automatically restart themselves if and only if SA_RESTART is specified in sigaction(2)

and the one responsible for this task is the restart_block which used to track information and arguments for restarting system calls

Solution 3

From the man page on write:

The call was interrupted by a signal before any data was written

Share:
43,692

Related videos on Youtube

Robb1
Author by

Robb1

Last time I used a Microsoft OS I was 12, since that day my life changed. My path was therefore doomed: I started studying as Computer Engineer becoming fond of languages (both programming and human ones). Love to travel, play guitar and dream about an utopic playland I will build one day.

Updated on July 09, 2022

Comments

  • Robb1
    Robb1 almost 2 years

    I've found this piece of code used several times (also a similar one where it's used open() instead of write()).

    int c = write(fd, &v, sizeof(v));
    if (c == -1 && errno != EINTR) {
        perror("Write to output file");
        exit(EXIT_FAILURE);
    }
    

    Why it is checked if && errno != EINTR here ?

    Looking for errno on man I found the following text about EINTR, but even if I visited man 7 signal that doesn't enlighten me.

    EINTR Interrupted function call (POSIX.1); see signal(7).

    • Kevin
      Kevin over 7 years
      Check the man page for write instead. It should tell you what errno is set to on certain errors.
    • Andrew Henle
      Andrew Henle over 7 years
      Note also that write() returns ssize_t, and NOT int. They are not the same.
    • Robb1
      Robb1 over 7 years
      Thank you both! @AndrewHenle I know it, I just decided to copy the piece of code as I found it :) do you think I should edit the question all the same with ssize_t instead of int?
  • R.. GitHub STOP HELPING ICE
    R.. GitHub STOP HELPING ICE over 7 years
    This answer is not really sufficient; it doesn't explain the situations under which EINTR can (or more importantly, can't) happen. I consider the latter more important because failure to understand that it usually can't happen is a cause of endless cargo-culting.
  • Andrew Henle
    Andrew Henle over 7 years
    @R.. This answer is not really sufficient; it doesn't explain the situations under which EINTR can (or more importantly, can't) happen. I consider the latter more important because failure to understand that it usually can't happen is a cause of endless cargo-culting. If you don't "cargo cult" system calls, changing something like the signal mask of a process can break things anywhere. If you like writing fragile code that can be broken by something completely unrelated, that's your choice. But please don't characterize writing robust code as "cargo-culting".
  • R.. GitHub STOP HELPING ICE
    R.. GitHub STOP HELPING ICE over 7 years
    @AndrewHenle: Installing an interrupting signal handler is an invasive and intentional thing you do when you want to error-out of blocking syscalls that get interrupted. Looping to repeat when that happens does not make sense in general, only when you know you really want that behavior.
  • bmcorser
    bmcorser over 5 years
    @R.. can you explain (or perhaps just link to an explanation of) a situation that might lead to such a signal handler being a sensible option?
  • Rick
    Rick about 5 years
    Could you tell me where does the reference come from? I would like to take a look. :)
  • zerocool
    zerocool almost 5 years
    @Rick I forget I'm very sorry but I think have to do with x86 and kernel stuff because at that time I was reading a lot of books about how stuff works so maybe Understanding the Linux Kernel book or The Linux Programming Interface book.
  • Orkhan Alikhanov
    Orkhan Alikhanov over 4 years
    Might be useful for nerds, Interrupt
  • Sahsahae
    Sahsahae about 2 years
    @R..GitHubSTOPHELPINGICE and this argument works against you, because the last thing I will do when writing a library is implement something like a signal handler. The reality is that I don't know if user will or will not install a signal handler, am I supposed to just go let them write this code by themselves in that case?
  • R.. GitHub STOP HELPING ICE
    R.. GitHub STOP HELPING ICE about 2 years
    @Sahsahae: In that case you also don't know whether their choice to install an interrupting signal handler represents an intent that the code they're calling (your library code) immediately bail out on a signal (the standard semantic for interrupting signals) or an intent that your code treat itself as special and try to resume blocking after being interrupted. Since you can't know, doing something special to satisfy an assumption they want the latter seems like a bad idea. Just doing nothing achives the former automatically.
  • Sahsahae
    Sahsahae about 2 years
    @R..GitHubSTOPHELPINGICE I hope you will one day realize that your argument can be worked all the way backwards till we're left with nothing but a single function that adds two numbers, except we don't know whether user wants the result to be printed or used anywhere so may aswell not write the function because user can just go write everything from scratch, because you're ignoring that libraries exist to solve a specific problem, instead of covering everything ever imaginable.