diff options
author | Elliott Hughes <enh@google.com> | 2020-02-21 23:21:28 -0800 |
---|---|---|
committer | Elliott Hughes <enh@google.com> | 2020-02-23 11:36:53 -0800 |
commit | 733cedd1c4696ea74dab34d629ef7ac28ecc2200 (patch) | |
tree | 6f24227b01f5bfea254d364bd90ee5a1067d4408 | |
parent | fcbdba22ab1c84825bd1e4cd18f8298c87991a5b (diff) |
Add a libc wrapper for statx(2).
Bug: http://b/127675384
Bug: http://b/146676114
Test: treehugger
Change-Id: I844edc12f62717e579870a040cf03dfe60dc280b
-rw-r--r-- | docs/status.md | 4 | ||||
-rw-r--r-- | libc/SECCOMP_WHITELIST_COMMON.TXT | 2 | ||||
-rw-r--r-- | libc/SYSCALLS.TXT | 1 | ||||
-rw-r--r-- | libc/include/bits/fortify/stat.h | 4 | ||||
-rw-r--r-- | libc/include/sys/stat.h | 20 | ||||
-rw-r--r-- | libc/libc.map.txt | 1 | ||||
-rw-r--r-- | tests/sys_stat_test.cpp | 26 |
7 files changed, 47 insertions, 11 deletions
diff --git a/docs/status.md b/docs/status.md index 6f358ea66..9d3ad8887 100644 --- a/docs/status.md +++ b/docs/status.md @@ -52,8 +52,8 @@ Current libc symbols: https://android.googlesource.com/platform/bionic/+/master/ New libc functions in R (API level 30): * Full C11 `<threads.h>` (available as inlines for older API levels). - * `memfd_create` and `mlock2` (GNU extensions). - * `renameat2` (GNU extension). + * `memfd_create` and `mlock2` (Linux-specific GNU extensions). + * `renameat2` and `statx` (Linux-specific GNU extensions). * `pthread_cond_clockwait`/`pthread_mutex_clocklock`/`pthread_rwlock_clockrdlock`/`pthread_rwlock_clockwrlock`/`sem_clockwait` New libc behavior in R (API level 30): diff --git a/libc/SECCOMP_WHITELIST_COMMON.TXT b/libc/SECCOMP_WHITELIST_COMMON.TXT index 72ced4f96..56f9d1d34 100644 --- a/libc/SECCOMP_WHITELIST_COMMON.TXT +++ b/libc/SECCOMP_WHITELIST_COMMON.TXT @@ -54,8 +54,6 @@ ssize_t copy_file_range(int fd_in, loff_t* off_in, int fd_out, loff_t* off_out, # Since Linux 4.6, glibc 2.26. ssize_t preadv2(int fd, const struct iovec* iov, int iovcnt, off_t offset, int flags) all ssize_t pwritev2(int fd, const struct iovec* iov, int iovcnt, off_t offset, int flags) all -# Since Linux 4.11, glibc 2.30. -int statx(int, const char*, int, unsigned int, statx*) all # Since Linux 5.1, not in glibc. int clock_gettime64(clockid_t, timespec64*) lp32 int clock_settime64(clockid_t, const timespec64*) lp32 diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT index 571df2206..ab309e629 100644 --- a/libc/SYSCALLS.TXT +++ b/libc/SYSCALLS.TXT @@ -208,6 +208,7 @@ ssize_t listxattr(const char*, char*, size_t) all ssize_t llistxattr(const char*, char*, size_t) all int removexattr(const char*, const char*) all int lremovexattr(const char*, const char*) all +int statx(int, const char*, int, unsigned, struct statx*) all int swapon(const char*, int) all int swapoff(const char*) all diff --git a/libc/include/bits/fortify/stat.h b/libc/include/bits/fortify/stat.h index e92e6ac81..2d42a51f2 100644 --- a/libc/include/bits/fortify/stat.h +++ b/libc/include/bits/fortify/stat.h @@ -26,9 +26,7 @@ * SUCH DAMAGE. */ -#ifndef _SYS_STAT_H_ -#error "Never include this file directly; instead, include <sys/stat.h>" -#endif +#pragma once mode_t __umask_chk(mode_t) __INTRODUCED_IN(18); mode_t __umask_real(mode_t mode) __RENAME(umask); diff --git a/libc/include/sys/stat.h b/libc/include/sys/stat.h index a6c73b7d9..4184f6c7f 100644 --- a/libc/include/sys/stat.h +++ b/libc/include/sys/stat.h @@ -26,8 +26,12 @@ * SUCH DAMAGE. */ -#ifndef _SYS_STAT_H_ -#define _SYS_STAT_H_ +#pragma once + +/** + * @file sys/stat.h + * @brief File status. + */ #include <bits/timespec.h> #include <linux/stat.h> @@ -169,8 +173,16 @@ int mknodat(int __dir_fd, const char* __path, mode_t __mode, dev_t __dev) __INTR int utimensat(int __dir_fd, const char* __path, const struct timespec __times[2], int __flags); int futimens(int __dir_fd, const struct timespec __times[2]) __INTRODUCED_IN(19); +#if defined(__USE_GNU) +/** + * [statx(2)](http://man7.org/linux/man-pages/man2/statx.2.html) returns + * extended file status information. + * + * Returns 0 on success and returns -1 and sets `errno` on failure. + */ +int statx(int __dir_fd, const char* __path, int __flags, unsigned __mask, struct statx* __buf) __INTRODUCED_IN(30); +#endif + __END_DECLS #include <android/legacy_sys_stat_inlines.h> - -#endif diff --git a/libc/libc.map.txt b/libc/libc.map.txt index 37807be5b..4bfb8a232 100644 --- a/libc/libc.map.txt +++ b/libc/libc.map.txt @@ -1505,6 +1505,7 @@ LIBC_R { # introduced=R pthread_rwlock_clockwrlock; renameat2; sem_clockwait; + statx; thrd_create; thrd_current; thrd_detach; diff --git a/tests/sys_stat_test.cpp b/tests/sys_stat_test.cpp index 97bf58026..71591c0c2 100644 --- a/tests/sys_stat_test.cpp +++ b/tests/sys_stat_test.cpp @@ -22,6 +22,14 @@ #include <android-base/file.h> #include <gtest/gtest.h> +#if defined(__BIONIC__) +#define HAVE_STATX +#elif defined(__GLIBC_PREREQ) +#if __GLIBC_PREREQ(2, 28) +#define HAVE_STATX +#endif +#endif + TEST(sys_stat, futimens) { FILE* fp = tmpfile(); ASSERT_TRUE(fp != nullptr); @@ -95,6 +103,24 @@ TEST(sys_stat, stat64_lstat64_fstat64) { close(fd); } +TEST(sys_stat, statx) { +#if defined(HAVE_STATX) + struct statx sx; + int rc = statx(AT_FDCWD, "/proc/version", AT_STATX_SYNC_AS_STAT, STATX_ALL, &sx); + if (rc == -1 && errno == ENOSYS) { + GTEST_SKIP() << "statx returned ENOSYS"; + return; + } + ASSERT_EQ(0, rc); + struct stat64 sb; + ASSERT_EQ(0, stat64("/proc/version", &sb)); + EXPECT_EQ(sb.st_ino, sx.stx_ino); + EXPECT_EQ(sb.st_mode, sx.stx_mode); +#else + GTEST_SKIP() << "statx not available"; +#endif +} + TEST(sys_stat, fchmodat_EFAULT_file) { ASSERT_EQ(-1, fchmodat(AT_FDCWD, (char *) 0x1, 0751, 0)); ASSERT_EQ(EFAULT, errno); |