diff --git a/libc/src/sys/stat/linux/CMakeLists.txt b/libc/src/sys/stat/linux/CMakeLists.txt --- a/libc/src/sys/stat/linux/CMakeLists.txt +++ b/libc/src/sys/stat/linux/CMakeLists.txt @@ -74,7 +74,6 @@ libc.include.sys_syscall libc.src.__support.OSUtil.osutil libc.src.__support.common - libc.src.errno.errno ) add_entrypoint_object( @@ -87,6 +86,7 @@ .kernel_statx libc.include.fcntl libc.include.sys_stat + libc.src.errno.errno ) add_entrypoint_object( @@ -99,6 +99,7 @@ .kernel_statx libc.include.fcntl libc.include.sys_stat + libc.src.errno.errno ) add_entrypoint_object( @@ -111,4 +112,5 @@ .kernel_statx libc.include.fcntl libc.include.sys_stat + libc.src.errno.errno ) diff --git a/libc/src/sys/stat/linux/fstat.cpp b/libc/src/sys/stat/linux/fstat.cpp --- a/libc/src/sys/stat/linux/fstat.cpp +++ b/libc/src/sys/stat/linux/fstat.cpp @@ -8,6 +8,7 @@ #include "src/sys/stat/fstat.h" #include "kernel_statx.h" +#include "src/errno/libc_errno.h" #include "src/__support/common.h" @@ -17,7 +18,12 @@ namespace __llvm_libc { LLVM_LIBC_FUNCTION(int, fstat, (int fd, struct stat *statbuf)) { - return statx(fd, "", AT_EMPTY_PATH, statbuf); + int err = statx(fd, "", AT_EMPTY_PATH, statbuf); + if (err != 0) { + libc_errno = err; + return -1; + } + return 0; } } // namespace __llvm_libc diff --git a/libc/src/sys/stat/linux/kernel_statx.h b/libc/src/sys/stat/linux/kernel_statx.h --- a/libc/src/sys/stat/linux/kernel_statx.h +++ b/libc/src/sys/stat/linux/kernel_statx.h @@ -12,7 +12,6 @@ #include "src/__support/OSUtil/syscall.h" // For internal syscall function. #include "src/__support/common.h" -#include #include #include #include // For syscall numbers. @@ -76,10 +75,8 @@ ::statx_buf xbuf; long ret = __llvm_libc::syscall_impl(SYS_statx, dirfd, path, flags, ::STATX_BASIC_STATS_MASK, &xbuf); - if (ret < 0) { - errno = -ret; - return -1; - } + if (ret < 0) + return -ret; statbuf->st_dev = MKDEV(xbuf.stx_dev_major, xbuf.stx_dev_minor); statbuf->st_ino = xbuf.stx_ino; diff --git a/libc/src/sys/stat/linux/lstat.cpp b/libc/src/sys/stat/linux/lstat.cpp --- a/libc/src/sys/stat/linux/lstat.cpp +++ b/libc/src/sys/stat/linux/lstat.cpp @@ -8,6 +8,7 @@ #include "src/sys/stat/lstat.h" #include "kernel_statx.h" +#include "src/errno/libc_errno.h" #include "src/__support/OSUtil/syscall.h" // For internal syscall function. #include "src/__support/common.h" @@ -20,7 +21,12 @@ LLVM_LIBC_FUNCTION(int, lstat, (const char *__restrict path, struct stat *__restrict statbuf)) { - return statx(AT_FDCWD, path, AT_SYMLINK_NOFOLLOW, statbuf); + int err = statx(AT_FDCWD, path, AT_SYMLINK_NOFOLLOW, statbuf); + if (err != 0) { + libc_errno = err; + return -1; + } + return 0; } } // namespace __llvm_libc diff --git a/libc/src/sys/stat/linux/stat.cpp b/libc/src/sys/stat/linux/stat.cpp --- a/libc/src/sys/stat/linux/stat.cpp +++ b/libc/src/sys/stat/linux/stat.cpp @@ -8,6 +8,7 @@ #include "src/sys/stat/stat.h" #include "kernel_statx.h" +#include "src/errno/libc_errno.h" #include "src/__support/common.h" @@ -19,7 +20,12 @@ LLVM_LIBC_FUNCTION(int, stat, (const char *__restrict path, struct stat *__restrict statbuf)) { - return statx(AT_FDCWD, path, 0, statbuf); + int err = statx(AT_FDCWD, path, 0, statbuf); + if (err != 0) { + libc_errno = err; + return -1; + } + return 0; } } // namespace __llvm_libc diff --git a/libc/test/src/sys/stat/lstat_test.cpp b/libc/test/src/sys/stat/lstat_test.cpp --- a/libc/test/src/sys/stat/lstat_test.cpp +++ b/libc/test/src/sys/stat/lstat_test.cpp @@ -6,6 +6,7 @@ // //===----------------------------------------------------------------------===// +#include "src/errno/libc_errno.h" #include "src/fcntl/open.h" #include "src/sys/stat/lstat.h" #include "src/unistd/close.h" @@ -14,7 +15,6 @@ #include "test/UnitTest/Test.h" #include "utils/testutils/FDReader.h" -#include #include #include @@ -27,11 +27,11 @@ // make it readonly using chmod. We test that chmod actually succeeded by // trying to open the file for writing and failing. constexpr const char *TEST_FILE = "testdata/lstat.test"; - errno = 0; + libc_errno = 0; int fd = __llvm_libc::open(TEST_FILE, O_CREAT | O_WRONLY, S_IRWXU); ASSERT_GT(fd, 0); - ASSERT_EQ(errno, 0); + ASSERT_EQ(libc_errno, 0); ASSERT_THAT(__llvm_libc::close(fd), Succeeds(0)); struct stat statbuf; @@ -43,9 +43,9 @@ } TEST(LlvmLibcLStatTest, NonExistentFile) { - errno = 0; + libc_errno = 0; using __llvm_libc::testing::ErrnoSetterMatcher::Fails; struct stat statbuf; ASSERT_THAT(__llvm_libc::lstat("non-existent-file", &statbuf), Fails(ENOENT)); - errno = 0; + libc_errno = 0; }