2

I am writing an small application and I want to make it as portable as possible (Linux, *BSD and possibly other UNIXes). My main issue is the management of EINTR. I read that there are some systems calls on some systems that can return EINTR although it is not documented (for example stat(2) on Linux). Is this correct?

My current solution is to use a wrapper around every system call to retry on EINTR, even if it is documented to not return this error. Is this safe on all "POSIX compliant" systems? What can be wrong using this approach? It is really recommended/needed?

1
  • Solaris man pages exhaustively list every possible errno - see stat for an example. There might be differences between how Solaris and Linux implement a given system call, but generally it's good to read the Solaris man pages. Commented Sep 11, 2018 at 2:19

1 Answer 1

2

I read that there are some systems calls on some systems that can return EINTR although it is not documented (for example stat(2) on Linux). Is this correct?

Unless you’ve blocked all signals, every system call that can block on I/O can return EINTR. This is a generic behavior of the kernel, so it’s justifiable that it isn’t documented repetitively for every such syscall. You also wouldn’t expect to find repeated documentation for EIO on each I/O syscall for the same reason.

More broadly, Linux man pages don’t list the errors they can return exhaustively. Not only do you have situations like the above, there’s also a lot of layering in the kernel, so what each syscal can return depends on what drivers and such are involved. The set of possible errno values when read(2) returns -1 will be different if the fd refers to a file on an XFS filesystem than if it refers to a FIFO. It’s unreasonable to expect that the man page would give the union of all possible error return codes; it would largely recapitulate errno(3) if it did.

What can be wrong using this approach? It is really recommended/needed?

Blindly restarting syscalls might not be the right thing in your application. Syscalls return EINTR to give your application a chance to deal with the signal in the calling context, as opposed to in the signal handler’s context. This can help you avoid global variables, for instance.

For one perspective on this, see EINTR and What It Is Good For.

Note also the sigaction point brought up in that article: you can control this behavior with SA_RESTART. If your next question is whether you should set the flag to 1 or to 0, then the answer is that it depends on your application.

1
  • Saner workarounds to the hell of signals as signalfd(2) makes EINTR more a problem than a useful tool. I have chosen the path of restarting syscalls on EINTR by default. If needed, I can always recover the EINTR behavior on particular cases. Commented Sep 10, 2018 at 19:54

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.