Add a libc wrapper for statx(2).
Bug: http://b/127675384 Bug: http://b/146676114 Test: treehugger Change-Id: I844edc12f62717e579870a040cf03dfe60dc280b
This commit is contained in:
parent
fcbdba22ab
commit
733cedd1c4
7 changed files with 47 additions and 11 deletions
|
@ -52,8 +52,8 @@ Current libc symbols: https://android.googlesource.com/platform/bionic/+/master/
|
||||||
|
|
||||||
New libc functions in R (API level 30):
|
New libc functions in R (API level 30):
|
||||||
* Full C11 `<threads.h>` (available as inlines for older API levels).
|
* Full C11 `<threads.h>` (available as inlines for older API levels).
|
||||||
* `memfd_create` and `mlock2` (GNU extensions).
|
* `memfd_create` and `mlock2` (Linux-specific GNU extensions).
|
||||||
* `renameat2` (GNU extension).
|
* `renameat2` and `statx` (Linux-specific GNU extensions).
|
||||||
* `pthread_cond_clockwait`/`pthread_mutex_clocklock`/`pthread_rwlock_clockrdlock`/`pthread_rwlock_clockwrlock`/`sem_clockwait`
|
* `pthread_cond_clockwait`/`pthread_mutex_clocklock`/`pthread_rwlock_clockrdlock`/`pthread_rwlock_clockwrlock`/`sem_clockwait`
|
||||||
|
|
||||||
New libc behavior in R (API level 30):
|
New libc behavior in R (API level 30):
|
||||||
|
|
|
@ -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.
|
# 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 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
|
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.
|
# Since Linux 5.1, not in glibc.
|
||||||
int clock_gettime64(clockid_t, timespec64*) lp32
|
int clock_gettime64(clockid_t, timespec64*) lp32
|
||||||
int clock_settime64(clockid_t, const timespec64*) lp32
|
int clock_settime64(clockid_t, const timespec64*) lp32
|
||||||
|
|
|
@ -208,6 +208,7 @@ ssize_t listxattr(const char*, char*, size_t) all
|
||||||
ssize_t llistxattr(const char*, char*, size_t) all
|
ssize_t llistxattr(const char*, char*, size_t) all
|
||||||
int removexattr(const char*, const char*) all
|
int removexattr(const char*, const char*) all
|
||||||
int lremovexattr(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 swapon(const char*, int) all
|
||||||
int swapoff(const char*) all
|
int swapoff(const char*) all
|
||||||
|
|
||||||
|
|
|
@ -26,9 +26,7 @@
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _SYS_STAT_H_
|
#pragma once
|
||||||
#error "Never include this file directly; instead, include <sys/stat.h>"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
mode_t __umask_chk(mode_t) __INTRODUCED_IN(18);
|
mode_t __umask_chk(mode_t) __INTRODUCED_IN(18);
|
||||||
mode_t __umask_real(mode_t mode) __RENAME(umask);
|
mode_t __umask_real(mode_t mode) __RENAME(umask);
|
||||||
|
|
|
@ -26,8 +26,12 @@
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _SYS_STAT_H_
|
#pragma once
|
||||||
#define _SYS_STAT_H_
|
|
||||||
|
/**
|
||||||
|
* @file sys/stat.h
|
||||||
|
* @brief File status.
|
||||||
|
*/
|
||||||
|
|
||||||
#include <bits/timespec.h>
|
#include <bits/timespec.h>
|
||||||
#include <linux/stat.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 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);
|
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
|
__END_DECLS
|
||||||
|
|
||||||
#include <android/legacy_sys_stat_inlines.h>
|
#include <android/legacy_sys_stat_inlines.h>
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -1505,6 +1505,7 @@ LIBC_R { # introduced=R
|
||||||
pthread_rwlock_clockwrlock;
|
pthread_rwlock_clockwrlock;
|
||||||
renameat2;
|
renameat2;
|
||||||
sem_clockwait;
|
sem_clockwait;
|
||||||
|
statx;
|
||||||
thrd_create;
|
thrd_create;
|
||||||
thrd_current;
|
thrd_current;
|
||||||
thrd_detach;
|
thrd_detach;
|
||||||
|
|
|
@ -22,6 +22,14 @@
|
||||||
#include <android-base/file.h>
|
#include <android-base/file.h>
|
||||||
#include <gtest/gtest.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) {
|
TEST(sys_stat, futimens) {
|
||||||
FILE* fp = tmpfile();
|
FILE* fp = tmpfile();
|
||||||
ASSERT_TRUE(fp != nullptr);
|
ASSERT_TRUE(fp != nullptr);
|
||||||
|
@ -95,6 +103,24 @@ TEST(sys_stat, stat64_lstat64_fstat64) {
|
||||||
close(fd);
|
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) {
|
TEST(sys_stat, fchmodat_EFAULT_file) {
|
||||||
ASSERT_EQ(-1, fchmodat(AT_FDCWD, (char *) 0x1, 0751, 0));
|
ASSERT_EQ(-1, fchmodat(AT_FDCWD, (char *) 0x1, 0751, 0));
|
||||||
ASSERT_EQ(EFAULT, errno);
|
ASSERT_EQ(EFAULT, errno);
|
||||||
|
|
Loading…
Reference in a new issue