summaryrefslogtreecommitdiffstats
path: root/lib/Support
diff options
context:
space:
mode:
authorPavel Labath <labath@google.com>2017-06-29 13:15:31 +0000
committerPavel Labath <labath@google.com>2017-06-29 13:15:31 +0000
commitd04333d38b8fd9914389c21267fa3859b9ebe0b7 (patch)
tree31b098de8d60d6ed4c77d7659450de67f13d5da3 /lib/Support
parent6b54220c086db1e88f1ae5003cf6cbb8a1fb3199 (diff)
Recommit "[Support] Add RetryAfterSignal helper function"
The difference from the previous version is the use of decltype, as the implementation of std::result_of in libc++ did not work correctly for variadic function like open(2). Original summary: This function retries an operation if it was interrupted by a signal (failed with EINTR). It's inspired by the TEMP_FAILURE_RETRY macro in glibc, but I've turned that into a template function. I've also added a fail-value argument, to enable the function to be used with e.g. fopen(3), which is documented to fail for any reason that open(2) can fail (which includes EINTR). The main user of this function will be lldb, but there were also a couple of uses within llvm that I could simplify using this function. Reviewers: zturner, silvas, joerg Subscribers: mgorny, llvm-commits Differential Revision: https://reviews.llvm.org/D33895 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@306671 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Support')
-rw-r--r--lib/Support/MemoryBuffer.cpp13
-rw-r--r--lib/Support/Unix/Path.inc12
-rw-r--r--lib/Support/Unix/Process.inc12
3 files changed, 12 insertions, 25 deletions
diff --git a/lib/Support/MemoryBuffer.cpp b/lib/Support/MemoryBuffer.cpp
index 227e792d83dc..85e782b2c048 100644
--- a/lib/Support/MemoryBuffer.cpp
+++ b/lib/Support/MemoryBuffer.cpp
@@ -240,11 +240,9 @@ getMemoryBufferForStream(int FD, const Twine &BufferName) {
// Read into Buffer until we hit EOF.
do {
Buffer.reserve(Buffer.size() + ChunkSize);
- ReadBytes = read(FD, Buffer.end(), ChunkSize);
- if (ReadBytes == -1) {
- if (errno == EINTR) continue;
+ ReadBytes = sys::RetryAfterSignal(-1, read, FD, Buffer.end(), ChunkSize);
+ if (ReadBytes == -1)
return std::error_code(errno, std::generic_category());
- }
Buffer.set_size(Buffer.size() + ReadBytes);
} while (ReadBytes != 0);
@@ -391,13 +389,12 @@ getOpenFileImpl(int FD, const Twine &Filename, uint64_t FileSize,
while (BytesLeft) {
#ifdef HAVE_PREAD
- ssize_t NumRead = ::pread(FD, BufPtr, BytesLeft, MapSize-BytesLeft+Offset);
+ ssize_t NumRead = sys::RetryAfterSignal(-1, ::pread, FD, BufPtr, BytesLeft,
+ MapSize - BytesLeft + Offset);
#else
- ssize_t NumRead = ::read(FD, BufPtr, BytesLeft);
+ ssize_t NumRead = sys::RetryAfterSignal(-1, ::read, FD, BufPtr, BytesLeft);
#endif
if (NumRead == -1) {
- if (errno == EINTR)
- continue;
// Error while reading.
return std::error_code(errno, std::generic_category());
}
diff --git a/lib/Support/Unix/Path.inc b/lib/Support/Unix/Path.inc
index b6774692595b..45097eb918b7 100644
--- a/lib/Support/Unix/Path.inc
+++ b/lib/Support/Unix/Path.inc
@@ -737,10 +737,8 @@ std::error_code openFileForRead(const Twine &Name, int &ResultFD,
#ifdef O_CLOEXEC
OpenFlags |= O_CLOEXEC;
#endif
- while ((ResultFD = open(P.begin(), OpenFlags)) < 0) {
- if (errno != EINTR)
- return std::error_code(errno, std::generic_category());
- }
+ if ((ResultFD = sys::RetryAfterSignal(-1, open, P.begin(), OpenFlags)) < 0)
+ return std::error_code(errno, std::generic_category());
#ifndef O_CLOEXEC
int r = fcntl(ResultFD, F_SETFD, FD_CLOEXEC);
(void)r;
@@ -800,10 +798,8 @@ std::error_code openFileForWrite(const Twine &Name, int &ResultFD,
SmallString<128> Storage;
StringRef P = Name.toNullTerminatedStringRef(Storage);
- while ((ResultFD = open(P.begin(), OpenFlags, Mode)) < 0) {
- if (errno != EINTR)
- return std::error_code(errno, std::generic_category());
- }
+ if ((ResultFD = sys::RetryAfterSignal(-1, open, P.begin(), OpenFlags, Mode)) < 0)
+ return std::error_code(errno, std::generic_category());
#ifndef O_CLOEXEC
int r = fcntl(ResultFD, F_SETFD, FD_CLOEXEC);
(void)r;
diff --git a/lib/Support/Unix/Process.inc b/lib/Support/Unix/Process.inc
index 1d0143c6716e..2d4662094682 100644
--- a/lib/Support/Unix/Process.inc
+++ b/lib/Support/Unix/Process.inc
@@ -207,13 +207,10 @@ std::error_code Process::FixupStandardFileDescriptors() {
for (int StandardFD : StandardFDs) {
struct stat st;
errno = 0;
- while (fstat(StandardFD, &st) < 0) {
+ if (RetryAfterSignal(-1, fstat, StandardFD, &st) < 0) {
assert(errno && "expected errno to be set if fstat failed!");
// fstat should return EBADF if the file descriptor is closed.
- if (errno == EBADF)
- break;
- // retry fstat if we got EINTR, otherwise bubble up the failure.
- if (errno != EINTR)
+ if (errno != EBADF)
return std::error_code(errno, std::generic_category());
}
// if fstat succeeds, move on to the next FD.
@@ -222,11 +219,8 @@ std::error_code Process::FixupStandardFileDescriptors() {
assert(errno == EBADF && "expected errno to have EBADF at this point!");
if (NullFD < 0) {
- while ((NullFD = open("/dev/null", O_RDWR)) < 0) {
- if (errno == EINTR)
- continue;
+ if ((NullFD = RetryAfterSignal(-1, open, "/dev/null", O_RDWR)) < 0)
return std::error_code(errno, std::generic_category());
- }
}
if (NullFD == StandardFD)