llvm.org GIT mirror llvm / 5fd5dc8
[Support] Clear errno before calling the function in RetryAfterSignal. For certain APIs, the return value of the function does not distinguish between failure (which populates errno) and other non-error conditions (which do not set errno). For example, `fgets` returns `NULL` both when an error has occurred, or upon EOF. If `errno` is already `EINTR` for whatever reason, then ``` RetryAfterSignal(nullptr, fgets, ...); ``` on a stream that has reached EOF would infinite loop. Fix this by setting `errno` to `0` before each attempt in `RetryAfterSignal`. Patch by Ricky Zhou! Differential Revision: https://reviews.llvm.org/D48755 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@336479 91177308-0d34-0410-b5e6-96231b3b80d8 Chandler Carruth 1 year, 3 months ago
2 changed file(s) with 6 addition(s) and 2 deletion(s). Raw diff Collapse all Expand all
3333 inline auto RetryAfterSignal(const FailT &Fail, const Fun &F,
3434 const Args &... As) -> decltype(F(As...)) {
3535 decltype(F(As...)) Res;
36 do
36 do {
37 errno = 0;
3738 Res = F(As...);
38 while (Res == Fail && errno == EINTR);
39 } while (Res == Fail && errno == EINTR);
3940 return Res;
4041 }
4142
3232
3333 std::unique_ptr P(RetryAfterSignal(nullptr, [] { return new int(47); }));
3434 EXPECT_EQ(47, *P);
35
36 errno = EINTR;
37 EXPECT_EQ(-1, RetryAfterSignal(-1, [] { return -1; }));
3538 }