aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Support/raw_ostream.cpp
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2014-10-07 05:48:40 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2014-10-07 05:48:40 +0000
commit51c2afc4b65b2782307a38ce54788ac4a61ef717 (patch)
tree560f4d3980b02f8da93a1291430d9261bd1350da /llvm/lib/Support/raw_ostream.cpp
parentdfc7ed7ad0971593e44eda3bde26606f1a8e543f (diff)
downloadllvm-51c2afc4b65b2782307a38ce54788ac4a61ef717.zip
llvm-51c2afc4b65b2782307a38ce54788ac4a61ef717.tar.gz
llvm-51c2afc4b65b2782307a38ce54788ac4a61ef717.tar.bz2
Support: Don't call close again if we get EINTR
Most Unix-like operating systems guarantee that the file descriptor is closed after a call to close(2), even if close comes back with EINTR. For these systems, calling close _again_ will either do nothing or close some other file descriptor open(2)'d by another thread. (Linux) However, some operating systems do not have this behavior. They require at least another call to close(2) before guaranteeing that the descriptor is closed. (HP-UX) And some operating systems have an unpredictable blend of the two behaviors! (xnu) Avoid this disaster by blocking all signals before we call close(2). This ensures that a signal will not be delivered to the thread and close(2) will not give us back EINTR. We restore the signal mask once the operation is done. N.B. This isn't a problem on Windows, it doesn't have a notion of EINTR because signals always get delivered to dedicated signal handling threads. llvm-svn: 219189
Diffstat (limited to 'llvm/lib/Support/raw_ostream.cpp')
-rw-r--r--llvm/lib/Support/raw_ostream.cpp15
1 files changed, 4 insertions, 11 deletions
diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp
index c2c55cf..bbbbe4a 100644
--- a/llvm/lib/Support/raw_ostream.cpp
+++ b/llvm/lib/Support/raw_ostream.cpp
@@ -536,12 +536,8 @@ raw_fd_ostream::raw_fd_ostream(int fd, bool shouldClose, bool unbuffered)
raw_fd_ostream::~raw_fd_ostream() {
if (FD >= 0) {
flush();
- if (ShouldClose)
- while (::close(FD) != 0)
- if (errno != EINTR) {
- error_detected();
- break;
- }
+ if (ShouldClose && sys::Process::SafelyCloseFileDescriptor(FD))
+ error_detected();
}
#ifdef __MINGW32__
@@ -615,11 +611,8 @@ void raw_fd_ostream::close() {
assert(ShouldClose);
ShouldClose = false;
flush();
- while (::close(FD) != 0)
- if (errno != EINTR) {
- error_detected();
- break;
- }
+ if (sys::Process::SafelyCloseFileDescriptor(FD))
+ error_detected();
FD = -1;
}