forked from OSchip/llvm-project
Revert "[Support] Add RetryAfterSignal helper function" and subsequent fix
The fix in r306003 uncovered a pretty fundamental problem that libc++ implementation of std::result_of does not handle the prototype of open(2) correctly (presumably because it contains ...). This makes the whole function unusable in its current form, so I am also reverting the original commit (r305892), which introduced the function, at least until I figure out a way to solve the libc++ issue. llvm-svn: 306005
This commit is contained in:
parent
69ffba4595
commit
efd57a8aec
|
@ -16,7 +16,6 @@
|
|||
|
||||
#include <cerrno>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
|
||||
namespace llvm {
|
||||
namespace sys {
|
||||
|
@ -30,18 +29,6 @@ std::string StrError();
|
|||
/// Like the no-argument version above, but uses \p errnum instead of errno.
|
||||
std::string StrError(int errnum);
|
||||
|
||||
template <typename Fun, typename... Args,
|
||||
typename ResultT = std::result_of<Fun const &(const Args &...)>>
|
||||
inline typename ResultT::type RetryAfterSignal(typename ResultT::type Fail,
|
||||
const Fun &F,
|
||||
const Args &... As) {
|
||||
typename ResultT::type Res;
|
||||
do
|
||||
Res = F(As...);
|
||||
while (Res == Fail && errno == EINTR);
|
||||
return Res;
|
||||
}
|
||||
|
||||
} // namespace sys
|
||||
} // namespace llvm
|
||||
|
||||
|
|
|
@ -240,9 +240,11 @@ getMemoryBufferForStream(int FD, const Twine &BufferName) {
|
|||
// Read into Buffer until we hit EOF.
|
||||
do {
|
||||
Buffer.reserve(Buffer.size() + ChunkSize);
|
||||
ReadBytes = sys::RetryAfterSignal(-1, read, FD, Buffer.end(), ChunkSize);
|
||||
if (ReadBytes == -1)
|
||||
ReadBytes = read(FD, Buffer.end(), ChunkSize);
|
||||
if (ReadBytes == -1) {
|
||||
if (errno == EINTR) continue;
|
||||
return std::error_code(errno, std::generic_category());
|
||||
}
|
||||
Buffer.set_size(Buffer.size() + ReadBytes);
|
||||
} while (ReadBytes != 0);
|
||||
|
||||
|
@ -389,12 +391,13 @@ getOpenFileImpl(int FD, const Twine &Filename, uint64_t FileSize,
|
|||
|
||||
while (BytesLeft) {
|
||||
#ifdef HAVE_PREAD
|
||||
ssize_t NumRead = sys::RetryAfterSignal(-1, ::pread, FD, BufPtr, BytesLeft,
|
||||
MapSize - BytesLeft + Offset);
|
||||
ssize_t NumRead = ::pread(FD, BufPtr, BytesLeft, MapSize-BytesLeft+Offset);
|
||||
#else
|
||||
ssize_t NumRead = sys::RetryAfterSignal(-1, ::read, FD, BufPtr, BytesLeft);
|
||||
ssize_t NumRead = ::read(FD, BufPtr, BytesLeft);
|
||||
#endif
|
||||
if (NumRead == -1) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
// Error while reading.
|
||||
return std::error_code(errno, std::generic_category());
|
||||
}
|
||||
|
|
|
@ -737,8 +737,10 @@ std::error_code openFileForRead(const Twine &Name, int &ResultFD,
|
|||
#ifdef O_CLOEXEC
|
||||
OpenFlags |= O_CLOEXEC;
|
||||
#endif
|
||||
if ((ResultFD = sys::RetryAfterSignal(-1, open, P.begin(), OpenFlags)) < 0)
|
||||
return std::error_code(errno, std::generic_category());
|
||||
while ((ResultFD = open(P.begin(), OpenFlags)) < 0) {
|
||||
if (errno != EINTR)
|
||||
return std::error_code(errno, std::generic_category());
|
||||
}
|
||||
#ifndef O_CLOEXEC
|
||||
int r = fcntl(ResultFD, F_SETFD, FD_CLOEXEC);
|
||||
(void)r;
|
||||
|
@ -798,8 +800,10 @@ std::error_code openFileForWrite(const Twine &Name, int &ResultFD,
|
|||
|
||||
SmallString<128> Storage;
|
||||
StringRef P = Name.toNullTerminatedStringRef(Storage);
|
||||
if ((ResultFD = sys::RetryAfterSignal(-1, open, P.begin(), OpenFlags, Mode)) < 0)
|
||||
return std::error_code(errno, std::generic_category());
|
||||
while ((ResultFD = open(P.begin(), OpenFlags, Mode)) < 0) {
|
||||
if (errno != EINTR)
|
||||
return std::error_code(errno, std::generic_category());
|
||||
}
|
||||
#ifndef O_CLOEXEC
|
||||
int r = fcntl(ResultFD, F_SETFD, FD_CLOEXEC);
|
||||
(void)r;
|
||||
|
|
|
@ -207,10 +207,13 @@ std::error_code Process::FixupStandardFileDescriptors() {
|
|||
for (int StandardFD : StandardFDs) {
|
||||
struct stat st;
|
||||
errno = 0;
|
||||
if (RetryAfterSignal(-1, fstat, StandardFD, &st) < 0) {
|
||||
while (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)
|
||||
if (errno == EBADF)
|
||||
break;
|
||||
// retry fstat if we got EINTR, otherwise bubble up the failure.
|
||||
if (errno != EINTR)
|
||||
return std::error_code(errno, std::generic_category());
|
||||
}
|
||||
// if fstat succeeds, move on to the next FD.
|
||||
|
@ -219,8 +222,11 @@ std::error_code Process::FixupStandardFileDescriptors() {
|
|||
assert(errno == EBADF && "expected errno to have EBADF at this point!");
|
||||
|
||||
if (NullFD < 0) {
|
||||
if ((NullFD = RetryAfterSignal(-1, open, "/dev/null", O_RDWR)) < 0)
|
||||
while ((NullFD = open("/dev/null", O_RDWR)) < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
return std::error_code(errno, std::generic_category());
|
||||
}
|
||||
}
|
||||
|
||||
if (NullFD == StandardFD)
|
||||
|
|
|
@ -21,7 +21,6 @@ add_llvm_unittest(SupportTests
|
|||
DebugTest.cpp
|
||||
EndianStreamTest.cpp
|
||||
EndianTest.cpp
|
||||
ErrnoTest.cpp
|
||||
ErrorOrTest.cpp
|
||||
ErrorTest.cpp
|
||||
FileOutputBufferTest.cpp
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
//===- ErrnoTest.cpp - Error handling unit tests --------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Support/Errno.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
using namespace llvm::sys;
|
||||
|
||||
static int *ReturnPointer() { return new int(47); }
|
||||
|
||||
TEST(ErrnoTest, RetryAfterSignal) {
|
||||
EXPECT_EQ(1, RetryAfterSignal(-1, [] { return 1; }));
|
||||
|
||||
EXPECT_EQ(-1, RetryAfterSignal(-1, [] {
|
||||
errno = EAGAIN;
|
||||
return -1;
|
||||
}));
|
||||
EXPECT_EQ(EAGAIN, errno);
|
||||
|
||||
unsigned calls = 0;
|
||||
EXPECT_EQ(1, RetryAfterSignal(-1, [&calls] {
|
||||
errno = EINTR;
|
||||
++calls;
|
||||
return calls == 1 ? -1 : 1;
|
||||
}));
|
||||
EXPECT_EQ(2u, calls);
|
||||
|
||||
EXPECT_EQ(1, RetryAfterSignal(-1, [](int x) { return x; }, 1));
|
||||
|
||||
std::unique_ptr<int> P{RetryAfterSignal(nullptr, ReturnPointer)};
|
||||
EXPECT_EQ(47, *P);
|
||||
}
|
Loading…
Reference in New Issue