Hacker Newsnew | past | comments | ask | show | jobs | submit | iiirogers's commentslogin

Discussion on EINTR wrt close in Linux: https://lwn.net/Articles/576478/

Glibc shows use with TEMP_FAILURE_RETRY: https://www.gnu.org/software/libc/manual/html_node/Opening-a...

Using TEMP_FAILURE_RETRY when close always deallocates the fd will at best get EBADF, at worse you close a random file descriptor.


This is the best example of how bad EINTR is as a design, in my opinion. I was painfully aware of how hard it is to write correct code when dealing with interruptible system calls, but even I didn't know that close() could potentially be interrupted.


It's not hard to write correct code in the face of EINTR. You can simply try again. Or just use libc (or another language's wrapper).

There is a real need for interrupts during a "slow" system call. I much prefer EINTR to sth. like completion ports. EINTR is simple and usable. (I don't understand well enough the problems around interrupted close())


One cannot simply try again. One has to take the byte count returned by read() and write() and deduct that from what was expected. One has to find out what time it is after returning prematurely from sleep() and nanosleep(). For a lot of the interruptible system calls, one has to write defensive code.


> For a lot of the interruptible system calls, one has to write defensive code.

Errrr, duh. Remove "interruptible" and that sentence still holds very true.

If you don't care about being interruptible, write restarting wrappers doing a simple subtraction. (Or use fread(3)/fwrite(3)). It's not hard.

nanosleep(2) gives you back the remaining time, it's about as easy to use as read(2)/write(2). Very simple. sleep(3) doesn't, but due to seconds resolution it's not a generally useful API anyway. Still useful for quick debugging. Not a system call, but a libc call, by the way.


I think we are in complete agreement that it is not hard to write defensive wrappers to work around the fact that the API is a mess.


You don’t always need TEMP_FAILURE_RETRY:

https://www.gnu.org/software/libc/manual/html_node/Interrupt...

Summary: If you define ‘_BSD_SOURCE’ or ‘_GNU_SOURCE’ before calling ‘signal’, you never get EINTR. If you use ‘sigaction’ to establish a signal handler, you can specify how that handler should behave. If you specify the 'SA_RESTART' flag, return from that handler will resume a primitive instead of returning with EINTR.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: