summaryrefslogtreecommitdiff
path: root/src/shared/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/shared/util.c')
-rw-r--r--src/shared/util.c27
1 files changed, 17 insertions, 10 deletions
diff --git a/src/shared/util.c b/src/shared/util.c
index aa0532a2be..d754c836f2 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -183,18 +183,25 @@ bool first_word(const char *s, const char *word) {
}
int close_nointr(int fd) {
- assert(fd >= 0);
-
- for (;;) {
- int r;
+ int r;
- r = close(fd);
- if (r >= 0)
- return r;
+ assert(fd >= 0);
+ r = close(fd);
- if (errno != EINTR)
- return -errno;
- }
+ /* Just ignore EINTR; a retry loop is the wrong
+ * thing to do on Linux.
+ *
+ * http://lkml.indiana.edu/hypermail/linux/kernel/0509.1/0877.html
+ * https://bugzilla.gnome.org/show_bug.cgi?id=682819
+ * http://utcc.utoronto.ca/~cks/space/blog/unix/CloseEINTR
+ * https://sites.google.com/site/michaelsafyan/software-engineering/checkforeintrwheninvokingclosethinkagain
+ */
+ if (_unlikely_(r < 0 && errno == EINTR))
+ return 0;
+ else if (r >= 0)
+ return r;
+ else
+ return -errno;
}
void close_nointr_nofail(int fd) {