diff options
author | Lennart Poettering <lennart@poettering.net> | 2014-04-13 20:00:42 -0700 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2014-04-13 20:01:41 -0700 |
commit | d96ea5048b2a901143059eecd32cb1607ceae041 (patch) | |
tree | 1f128223d1f0a19b8d3f637f465c72ab5e526f92 | |
parent | 3ebdb81ef088afd3b4c72b516beb5610f8c93a0d (diff) |
util: ignore kernel errors reported via close(), unless it is EBADF
The kernel can return pretty much anything there, even though the fd is
closed. Let's not get confused by that.
-rw-r--r-- | src/shared/util.c | 32 |
1 files changed, 19 insertions, 13 deletions
diff --git a/src/shared/util.c b/src/shared/util.c index 1a727ca40a..c8a017db86 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -166,19 +166,19 @@ int close_nointr(int fd) { assert(fd >= 0); r = close(fd); - - /* 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) + if (r >= 0) return r; + else if (errno == EINTR) + /* + * 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 + */ + return 0; else return -errno; } @@ -195,7 +195,13 @@ int safe_close(int fd) { if (fd >= 0) { PROTECT_ERRNO; - assert_se(close_nointr(fd) == 0); + + /* The kernel might return pretty much any error code + * via close(), but the fd will be closed anyway. The + * only condition we want to check for here is whether + * the fd was invalid at all... */ + + assert_se(close_nointr(fd) != -EBADF); } return -1; |