diff options
author | Colin Walters <walters@verbum.org> | 2013-01-25 11:21:20 -0500 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2013-02-13 04:56:28 +0100 |
commit | b0ee8068da5bc9ed949656700274bb6ff60d2073 (patch) | |
tree | 794bb5c6595917b2adbc6928a8494aa00f04abd5 | |
parent | 2a2473d89e02ccd923abc6e74cddd07798679a15 (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.c | 27 |
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) { |