summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Walters <walters@verbum.org>2013-01-25 11:21:20 -0500
committerLennart Poettering <lennart@poettering.net>2013-02-13 04:56:28 +0100
commitb0ee8068da5bc9ed949656700274bb6ff60d2073 (patch)
tree794bb5c6595917b2adbc6928a8494aa00f04abd5
parent2a2473d89e02ccd923abc6e74cddd07798679a15 (diff)
util: *DO NOT* loop for EINTR handling with close_nointr()
See the linked references for why we should not do this.
-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) {