diff --git a/libc/src/errno/CMakeLists.txt b/libc/src/errno/CMakeLists.txt --- a/libc/src/errno/CMakeLists.txt +++ b/libc/src/errno/CMakeLists.txt @@ -1,4 +1,3 @@ -if (LLVM_LIBC_FULL_BUILD) add_object_library( errno SRCS @@ -6,12 +5,3 @@ HDRS llvmlibc_errno.h ) -else() -add_object_library( - errno - SRCS - dummy_errno.cpp - HDRS - dummy_errno.h -) -endif() diff --git a/libc/src/errno/errno.cpp b/libc/src/errno/errno.cpp --- a/libc/src/errno/errno.cpp +++ b/libc/src/errno/errno.cpp @@ -1,4 +1,4 @@ -//===-- Implementation of __errno_location --------------------------------===// +//===-- Implementation of errno -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,4 +6,10 @@ // //===----------------------------------------------------------------------===// +// TODO: Conditionally exclude one of the errno's based on +// LLVM_LIBC_PUBLIC_PACKAGING. We need both to exist now as all references to +// errno have not been swtiched over to the setter and getter functions. + thread_local int __llvmlibc_errno = 0; + +thread_local int __llvmlibc_test_errno = 0; diff --git a/libc/src/errno/llvmlibc_errno.h b/libc/src/errno/llvmlibc_errno.h --- a/libc/src/errno/llvmlibc_errno.h +++ b/libc/src/errno/llvmlibc_errno.h @@ -9,9 +9,26 @@ #ifndef LLVM_LIBC_SRC_ERRNO_LLVMLIBC_ERRNO_H #define LLVM_LIBC_SRC_ERRNO_LLVMLIBC_ERRNO_H -// Internal code should use this and not use the errno macro from the -// public header. -extern thread_local int __llvmlibc_errno; -#define llvmlibc_errno __llvmlibc_errno +#ifdef LLVM_LIBC_PUBLIC_PACKAGING +#include +#define ACTIVE_ERRNO errno +#else +#define ACTIVE_ERRNO __llvmlibc_test_errno +extern thread_local int __llvmlibc_test_errno; +#endif // LLVM_LIBC_PUBLIC_PACKAGING + +namespace __llvm_libc { + +// Internal and test code should read and update errno using the following +// functions. This way, we ensure that there is no mixup with the errno from +// the system libc in unit tests. + +inline int get_errno() { return ACTIVE_ERRNO; } + +inline void set_errno(int err) { ACTIVE_ERRNO = err; } + +} // namespace __llvm_libc + +#undef ACTIVE_ERRNO #endif // LLVM_LIBC_SRC_ERRNO_LLVMLIBC_ERRNO_H diff --git a/libc/src/fcntl/linux/openat.cpp b/libc/src/fcntl/linux/openat.cpp --- a/libc/src/fcntl/linux/openat.cpp +++ b/libc/src/fcntl/linux/openat.cpp @@ -10,8 +10,8 @@ #include "src/__support/OSUtil/syscall.h" // For internal syscall function. #include "src/__support/common.h" +#include "src/errno/llvmlibc_errno.h" -#include #include #include #include // For syscall numbers. @@ -33,7 +33,7 @@ if (fd > 0) return fd; - errno = -fd; + __llvm_libc::set_errno(-fd); return -1; } diff --git a/libc/src/sys/mman/linux/mmap.cpp b/libc/src/sys/mman/linux/mmap.cpp --- a/libc/src/sys/mman/linux/mmap.cpp +++ b/libc/src/sys/mman/linux/mmap.cpp @@ -10,8 +10,8 @@ #include "src/__support/OSUtil/syscall.h" // For internal syscall function. #include "src/__support/common.h" +#include "src/errno/llvmlibc_errno.h" -#include #include // For EXEC_PAGESIZE. #include // For syscall numbers. @@ -53,7 +53,7 @@ // return value corresponding to a location in the last page is an error // value. if (ret_val < 0 && ret_val > -EXEC_PAGESIZE) { - errno = -ret_val; + __llvm_libc::set_errno(-ret_val); return MAP_FAILED; } diff --git a/libc/src/sys/mman/linux/munmap.cpp b/libc/src/sys/mman/linux/munmap.cpp --- a/libc/src/sys/mman/linux/munmap.cpp +++ b/libc/src/sys/mman/linux/munmap.cpp @@ -10,8 +10,8 @@ #include "src/__support/OSUtil/syscall.h" // For internal syscall function. #include "src/__support/common.h" +#include "src/errno/llvmlibc_errno.h" -#include #include // For syscall numbers. namespace __llvm_libc { @@ -25,7 +25,7 @@ // A negative return value indicates an error with the magnitude of the // value being the error code. if (ret_val < 0) { - errno = -ret_val; + __llvm_libc::set_errno(-ret_val); return -1; } diff --git a/libc/src/sys/stat/linux/mkdir.cpp b/libc/src/sys/stat/linux/mkdir.cpp --- a/libc/src/sys/stat/linux/mkdir.cpp +++ b/libc/src/sys/stat/linux/mkdir.cpp @@ -10,8 +10,8 @@ #include "src/__support/OSUtil/syscall.h" // For internal syscall function. #include "src/__support/common.h" +#include "src/errno/llvmlibc_errno.h" -#include #include #include #include // For syscall numbers. @@ -28,7 +28,7 @@ #endif if (ret < 0) { - errno = -ret; + __llvm_libc::set_errno(-ret); return -1; } return 0; diff --git a/libc/src/sys/stat/linux/mkdirat.cpp b/libc/src/sys/stat/linux/mkdirat.cpp --- a/libc/src/sys/stat/linux/mkdirat.cpp +++ b/libc/src/sys/stat/linux/mkdirat.cpp @@ -10,8 +10,8 @@ #include "src/__support/OSUtil/syscall.h" // For internal syscall function. #include "src/__support/common.h" +#include "src/errno/llvmlibc_errno.h" -#include #include #include // For syscall numbers. @@ -25,7 +25,7 @@ #endif if (ret < 0) { - errno = -ret; + __llvm_libc::set_errno(-ret); return -1; } return 0; diff --git a/libc/src/time/time_utils.h b/libc/src/time/time_utils.h --- a/libc/src/time/time_utils.h +++ b/libc/src/time/time_utils.h @@ -69,11 +69,11 @@ // POSIX.1-2017 requires this. static inline time_t out_of_range() { - llvmlibc_errno = EOVERFLOW; + set_errno(EOVERFLOW); return static_cast(-1); } -static inline void invalid_value() { llvmlibc_errno = EINVAL; } +static inline void invalid_value() { set_errno(EINVAL); } static inline char *asctime(const struct tm *timeptr, char *buffer, size_t bufferLength) { diff --git a/libc/src/unistd/linux/lseek.cpp b/libc/src/unistd/linux/lseek.cpp --- a/libc/src/unistd/linux/lseek.cpp +++ b/libc/src/unistd/linux/lseek.cpp @@ -10,8 +10,8 @@ #include "src/__support/OSUtil/syscall.h" // For internal syscall function. #include "src/__support/common.h" +#include "src/errno/llvmlibc_errno.h" -#include #include // For syscall numbers. #include @@ -30,7 +30,7 @@ #endif if (ret < 0) { - errno = -ret; + __llvm_libc::set_errno(-ret); return -1; } return result; diff --git a/libc/src/unistd/linux/read.cpp b/libc/src/unistd/linux/read.cpp --- a/libc/src/unistd/linux/read.cpp +++ b/libc/src/unistd/linux/read.cpp @@ -10,8 +10,8 @@ #include "src/__support/OSUtil/syscall.h" // For internal syscall function. #include "src/__support/common.h" +#include "src/errno/llvmlibc_errno.h" -#include #include // For syscall numbers. namespace __llvm_libc { @@ -19,7 +19,7 @@ LLVM_LIBC_FUNCTION(ssize_t, read, (int fd, void *buf, size_t count)) { long ret = __llvm_libc::syscall(SYS_read, fd, buf, count); if (ret < 0) { - errno = -ret; + __llvm_libc::set_errno(-ret); return -1; } return ret; diff --git a/libc/src/unistd/linux/rmdir.cpp b/libc/src/unistd/linux/rmdir.cpp --- a/libc/src/unistd/linux/rmdir.cpp +++ b/libc/src/unistd/linux/rmdir.cpp @@ -10,8 +10,8 @@ #include "src/__support/OSUtil/syscall.h" // For internal syscall function. #include "src/__support/common.h" +#include "src/errno/llvmlibc_errno.h" -#include #include #include // For syscall numbers. @@ -27,7 +27,7 @@ #endif if (ret < 0) { - errno = -ret; + __llvm_libc::set_errno(-ret); return -1; } return 0; diff --git a/libc/src/unistd/linux/unlink.cpp b/libc/src/unistd/linux/unlink.cpp --- a/libc/src/unistd/linux/unlink.cpp +++ b/libc/src/unistd/linux/unlink.cpp @@ -10,8 +10,8 @@ #include "src/__support/OSUtil/syscall.h" // For internal syscall function. #include "src/__support/common.h" +#include "src/errno/llvmlibc_errno.h" -#include #include #include // For syscall numbers. @@ -27,7 +27,7 @@ #endif if (ret < 0) { - errno = -ret; + __llvm_libc::set_errno(-ret); return -1; } return 0; diff --git a/libc/src/unistd/linux/unlinkat.cpp b/libc/src/unistd/linux/unlinkat.cpp --- a/libc/src/unistd/linux/unlinkat.cpp +++ b/libc/src/unistd/linux/unlinkat.cpp @@ -10,8 +10,8 @@ #include "src/__support/OSUtil/syscall.h" // For internal syscall function. #include "src/__support/common.h" +#include "src/errno/llvmlibc_errno.h" -#include #include #include // For syscall numbers. @@ -25,7 +25,7 @@ #endif if (ret < 0) { - errno = -ret; + __llvm_libc::set_errno(-ret); return -1; } return 0; diff --git a/libc/src/unistd/linux/write.cpp b/libc/src/unistd/linux/write.cpp --- a/libc/src/unistd/linux/write.cpp +++ b/libc/src/unistd/linux/write.cpp @@ -10,8 +10,8 @@ #include "src/__support/OSUtil/syscall.h" // For internal syscall function. #include "src/__support/common.h" +#include -#include #include // For syscall numbers. namespace __llvm_libc { @@ -19,7 +19,7 @@ LLVM_LIBC_FUNCTION(ssize_t, write, (int fd, const void *buf, size_t count)) { long ret = __llvm_libc::syscall(SYS_write, fd, buf, count); if (ret < 0) { - errno = -ret; + __llvm_libc::set_errno(-ret); return -1; } return ret; diff --git a/libc/test/ErrnoSetterMatcher.h b/libc/test/ErrnoSetterMatcher.h --- a/libc/test/ErrnoSetterMatcher.h +++ b/libc/test/ErrnoSetterMatcher.h @@ -11,7 +11,7 @@ #include "utils/UnitTest/Test.h" -#include +#include "src/errno/llvmlibc_errno.h" namespace __llvm_libc { namespace testing { @@ -43,8 +43,8 @@ bool match(T Got) { ActualReturn = Got; - ActualErrno = errno; - errno = 0; + ActualErrno = __llvm_libc::get_errno(); + __llvm_libc::set_errno(0); return Got == ExpectedReturn && ActualErrno == ExpectedErrno; } }; diff --git a/libc/test/integration/loader/linux/tls_test.cpp b/libc/test/integration/loader/linux/tls_test.cpp --- a/libc/test/integration/loader/linux/tls_test.cpp +++ b/libc/test/integration/loader/linux/tls_test.cpp @@ -28,11 +28,11 @@ // set in errno. Since errno is implemented using a thread // local var, this helps us test setting of errno and // reading it back. - ASSERT_TRUE(llvmlibc_errno == 0); + ASSERT_EQ(__llvm_libc::get_errno(), 0); void *addr = __llvm_libc::mmap(nullptr, 0, PROT_READ, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); ASSERT_TRUE(addr == MAP_FAILED); - ASSERT_TRUE(llvmlibc_errno == EINVAL); + ASSERT_EQ(__llvm_libc::get_errno(), EINVAL); return 0; } diff --git a/libc/test/src/errno/errno_test.cpp b/libc/test/src/errno/errno_test.cpp --- a/libc/test/src/errno/errno_test.cpp +++ b/libc/test/src/errno/errno_test.cpp @@ -10,7 +10,8 @@ #include "utils/UnitTest/Test.h" TEST(LlvmLibcErrnoTest, Basic) { + ASSERT_EQ(0, __llvm_libc::get_errno()); int test_val = 123; - llvmlibc_errno = test_val; - ASSERT_EQ(test_val, llvmlibc_errno); + __llvm_libc::set_errno(test_val); + ASSERT_EQ(test_val, __llvm_libc::get_errno()); } diff --git a/libc/test/src/time/asctime_r_test.cpp b/libc/test/src/time/asctime_r_test.cpp --- a/libc/test/src/time/asctime_r_test.cpp +++ b/libc/test/src/time/asctime_r_test.cpp @@ -26,18 +26,21 @@ // tests from asctime. Added couple of validation tests. TEST(LlvmLibcAsctimeR, Nullptr) { char *result; + __llvm_libc::set_errno(0); result = __llvm_libc::asctime_r(nullptr, nullptr); - ASSERT_EQ(EINVAL, llvmlibc_errno); + ASSERT_EQ(EINVAL, __llvm_libc::get_errno()); ASSERT_STREQ(nullptr, result); char buffer[TimeConstants::ASCTIME_BUFFER_SIZE]; + __llvm_libc::set_errno(0); result = __llvm_libc::asctime_r(nullptr, buffer); - ASSERT_EQ(EINVAL, llvmlibc_errno); + ASSERT_EQ(EINVAL, __llvm_libc::get_errno()); ASSERT_STREQ(nullptr, result); struct tm tm_data; + __llvm_libc::set_errno(0); result = __llvm_libc::asctime_r(&tm_data, nullptr); - ASSERT_EQ(EINVAL, llvmlibc_errno); + ASSERT_EQ(EINVAL, __llvm_libc::get_errno()); ASSERT_STREQ(nullptr, result); } diff --git a/libc/test/src/time/asctime_test.cpp b/libc/test/src/time/asctime_test.cpp --- a/libc/test/src/time/asctime_test.cpp +++ b/libc/test/src/time/asctime_test.cpp @@ -21,7 +21,7 @@ TEST(LlvmLibcAsctime, Nullptr) { char *result; result = __llvm_libc::asctime(nullptr); - ASSERT_EQ(EINVAL, llvmlibc_errno); + ASSERT_EQ(EINVAL, __llvm_libc::get_errno()); ASSERT_STREQ(nullptr, result); } @@ -40,7 +40,7 @@ 0, // sec -1, // wday 0); // yday - ASSERT_EQ(EINVAL, llvmlibc_errno); + ASSERT_EQ(EINVAL, __llvm_libc::get_errno()); // Test with wday = 7. result = call_asctime(&tm_data, @@ -52,7 +52,7 @@ 0, // sec 7, // wday 0); // yday - ASSERT_EQ(EINVAL, llvmlibc_errno); + ASSERT_EQ(EINVAL, __llvm_libc::get_errno()); } // Months are from January to December. Test passing invalid value in month. @@ -70,7 +70,7 @@ 0, // sec 4, // wday 0); // yday - ASSERT_EQ(EINVAL, llvmlibc_errno); + ASSERT_EQ(EINVAL, __llvm_libc::get_errno()); // Test with month = 13. result = call_asctime(&tm_data, @@ -82,7 +82,7 @@ 0, // sec 4, // wday 0); // yday - ASSERT_EQ(EINVAL, llvmlibc_errno); + ASSERT_EQ(EINVAL, __llvm_libc::get_errno()); } TEST(LlvmLibcAsctime, ValidWeekdays) { @@ -210,6 +210,6 @@ 50, // sec 2, // wday 50); // yday - ASSERT_EQ(EOVERFLOW, llvmlibc_errno); + ASSERT_EQ(EOVERFLOW, __llvm_libc::get_errno()); ASSERT_STREQ(nullptr, result); } diff --git a/libc/test/src/time/gmtime_test.cpp b/libc/test/src/time/gmtime_test.cpp --- a/libc/test/src/time/gmtime_test.cpp +++ b/libc/test/src/time/gmtime_test.cpp @@ -26,15 +26,15 @@ TimeConstants::NUMBER_OF_SECONDS_IN_LEAP_YEAR); struct tm *tm_data = __llvm_libc::gmtime(&seconds); EXPECT_TRUE(tm_data == nullptr); - EXPECT_EQ(llvmlibc_errno, EOVERFLOW); + EXPECT_EQ(__llvm_libc::get_errno(), EOVERFLOW); - llvmlibc_errno = 0; + __llvm_libc::set_errno(0); seconds = INT_MIN * static_cast( TimeConstants::NUMBER_OF_SECONDS_IN_LEAP_YEAR) - 1; tm_data = __llvm_libc::gmtime(&seconds); EXPECT_TRUE(tm_data == nullptr); - EXPECT_EQ(llvmlibc_errno, EOVERFLOW); + EXPECT_EQ(__llvm_libc::get_errno(), EOVERFLOW); } TEST(LlvmLibcGmTime, InvalidSeconds) {