summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJörg Thalheim <joerg@thalheim.io>2021-08-18 08:16:49 +0200
committerJörg Thalheim <joerg@thalheim.io>2021-08-18 08:16:49 +0200
commit51626341b678de034699381477e1d65a761d4d49 (patch)
treebe4634a0ccaaf5076229eb527cbcb9a34b062945
parent10cd631cce92c046abcb59455c94037920b730da (diff)
downloadpatchelf-eintr.tar.gz
correct EINTR handling in writeFileeintr
-rw-r--r--src/patchelf.cc26
1 files changed, 20 insertions, 6 deletions
diff --git a/src/patchelf.cc b/src/patchelf.cc
index 0cdfbb6..d69c1f6 100644
--- a/src/patchelf.cc
+++ b/src/patchelf.cc
@@ -544,14 +544,28 @@ static void writeFile(const std::string & fileName, const FileContents & content
size_t bytesWritten = 0;
ssize_t portion;
- while ((portion = write(fd, contents->data() + bytesWritten, contents->size() - bytesWritten)) > 0)
+ while (bytesWritten < contents->size()) {
+ if ((portion = write(fd, contents->data() + bytesWritten, contents->size() - bytesWritten)) < 0) {
+ if (errno == EINTR)
+ continue;
+ error("write");
+ }
bytesWritten += portion;
+ }
- if (bytesWritten != contents->size())
- error("write");
-
- if (close(fd) != 0)
- error("close");
+ if (close(fd) >= 0)
+ return;
+ /*
+ * Just ignore EINTR; a retry loop is the wrong thing to do.
+ *
+ * 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 (errno == EINTR)
+ return;
+ error("close");
}