Invoke close() again if it fails with EINTR? Think again.

posted Jan 23, 2011, 2:46 PM by Michael Safyan   [ updated Feb 19, 2012, 2:09 PM ]
One of the great things about working at Google is that we have lots of brilliant, skilled, and knowledgable people who share that knowledge in Tech Talks and code reviews. While I came to Google with a lot of programming knowledge both in general and of C++ and Java specifically, it's clear that there is a lot that I still don't know and need to learn. I've been having the pleasure to work with some very talented people, and I've been learning something new every day through our code review process.

This past week, I learned that -- even though the documentation for close() states that the function may fail due to interruption (errno == EINTR) -- one SHOULD NOT do:

int ret;
do {
     ret = close(fd);
} while ((ret == -1) && (errno == EINTR));

As discussed in this thread, many POSIX implementations, including Linux, will release the file descriptor immediately, and so if close() fails with EINTR, it is possible that the file descriptor has already been reclaimed and in use by some other component. Retrying the close call, therefore, might close some other component's descriptor.