Signed-off-by: Mark Salter <msal...@redhat.com> --- ldso/include/dl-syscall.h | 16 +++++++++++++ libc/sysdeps/linux/common/access.c | 8 ++++++ libc/sysdeps/linux/common/chmod.c | 8 ++++++ libc/sysdeps/linux/common/chown.c | 12 +++++----- libc/sysdeps/linux/common/fstatat.c | 2 +- libc/sysdeps/linux/common/fstatat64.c | 2 +- libc/sysdeps/linux/common/lchown.c | 11 +++++---- libc/sysdeps/linux/common/link.c | 8 ++++++ libc/sysdeps/linux/common/lstat.c | 9 +++++- libc/sysdeps/linux/common/lstat64.c | 13 +++++----- libc/sysdeps/linux/common/mkdir.c | 11 +++++---- libc/sysdeps/linux/common/mknod.c | 5 ++++ libc/sysdeps/linux/common/not-cancel.h | 8 ++++++ libc/sysdeps/linux/common/open.c | 8 ++++++ libc/sysdeps/linux/common/readlink.c | 8 ++++++ libc/sysdeps/linux/common/rename.c | 11 +++++---- libc/sysdeps/linux/common/rmdir.c | 10 +++++++- libc/sysdeps/linux/common/stubs.c | 4 +- libc/sysdeps/linux/common/symlink.c | 8 ++++++ libc/sysdeps/linux/common/unlink.c | 8 ++++++ libc/sysdeps/linux/common/utimes.c | 24 +++++++++++++++++++- .../linuxthreads.old/sysdeps/pthread/not-cancel.h | 8 ++++++ 22 files changed, 167 insertions(+), 35 deletions(-)
diff --git a/ldso/include/dl-syscall.h b/ldso/include/dl-syscall.h index 4c8aeaf..55ed290 100644 --- a/ldso/include/dl-syscall.h +++ b/ldso/include/dl-syscall.h @@ -49,9 +49,17 @@ static __always_inline _syscall1(void, _dl_exit, int, status) #define __NR__dl_close __NR_close static __always_inline _syscall1(int, _dl_close, int, fd) +#if defined(__NR_open) #define __NR__dl_open __NR_open static __always_inline _syscall3(int, _dl_open, const char *, fn, int, flags, __kernel_mode_t, mode) +#elif defined(__NR_openat) +static __always_inline ssize_t +_dl_open(const char *fn, int flags, __kernel_mode_t mode) +{ + return INLINE_SYSCALL(openat, 4, AT_FDCWD, fn, flags, mode); +} +#endif #define __NR__dl_write __NR_write static __always_inline _syscall3(unsigned long, _dl_write, int, fd, @@ -117,9 +125,17 @@ static __always_inline _syscall0(gid_t, _dl_getegid) #define __NR__dl_getpid __NR_getpid static __always_inline _syscall0(gid_t, _dl_getpid) +#if defined(__NR_readlink) #define __NR__dl_readlink __NR_readlink static __always_inline _syscall3(int, _dl_readlink, const char *, path, char *, buf, size_t, bufsiz) +#elif defined(__NR_readlinkat) +static __always_inline int +_dl_readlink(const char *fn, char *buf, size_t size) +{ + return INLINE_SYSCALL(readlinkat, 4, AT_FDCWD, fn, buf, size); +} +#endif #ifdef __NR_pread64 #define __NR___syscall_pread __NR_pread64 diff --git a/libc/sysdeps/linux/common/access.c b/libc/sysdeps/linux/common/access.c index a075d42..a98bbc4 100644 --- a/libc/sysdeps/linux/common/access.c +++ b/libc/sysdeps/linux/common/access.c @@ -9,4 +9,12 @@ #include <sys/syscall.h> #include <unistd.h> +#include <fcntl.h> +#ifdef __NR_access _syscall2(int, access, const char *, pathname, int, mode) +#elif defined __NR_faccessat +int access(const char *pathname, int mode) +{ + return INLINE_SYSCALL(faccessat, 4, AT_FDCWD, pathname, mode, 0); +} +#endif diff --git a/libc/sysdeps/linux/common/chmod.c b/libc/sysdeps/linux/common/chmod.c index 871e023..e86835a 100644 --- a/libc/sysdeps/linux/common/chmod.c +++ b/libc/sysdeps/linux/common/chmod.c @@ -9,8 +9,10 @@ #include <sys/syscall.h> #include <sys/stat.h> +#include <fcntl.h> +#ifdef __NR_chmod #define __NR___syscall_chmod __NR_chmod static __inline__ _syscall2(int, __syscall_chmod, const char *, path, __kernel_mode_t, mode) @@ -18,4 +20,10 @@ int chmod(const char *path, mode_t mode) { return __syscall_chmod(path, mode); } +#elif defined __NR_fchmodat +int chmod(const char *path, mode_t mode) +{ + return INLINE_SYSCALL(fchmodat, 4, AT_FDCWD, path, mode, 0); +} +#endif libc_hidden_def(chmod) diff --git a/libc/sysdeps/linux/common/chown.c b/libc/sysdeps/linux/common/chown.c index f2c60e0..8e08edf 100644 --- a/libc/sysdeps/linux/common/chown.c +++ b/libc/sysdeps/linux/common/chown.c @@ -10,6 +10,7 @@ #include <sys/syscall.h> #include <unistd.h> #include <bits/wordsize.h> +#include <fcntl.h> #if (__WORDSIZE == 32 && defined(__NR_chown32)) || __WORDSIZE == 64 @@ -21,11 +22,6 @@ _syscall3(int, chown, const char *, path, uid_t, owner, gid_t, group) #else - -# define __NR___syscall_chown __NR_chown -static __inline__ _syscall3(int, __syscall_chown, const char *, path, - __kernel_uid_t, owner, __kernel_gid_t, group) - int chown(const char *path, uid_t owner, gid_t group) { if (((owner + 1) > (uid_t) ((__kernel_uid_t) - 1U)) @@ -33,7 +29,11 @@ int chown(const char *path, uid_t owner, gid_t group) __set_errno(EINVAL); return -1; } - return (__syscall_chown(path, owner, group)); +# ifdef __NR_chown + return INLINE_SYSCALL(chown, 3, path, owner, group); +# elif defined __NR_fchownat + return INLINE_SYSCALL(fchownat, 5, AT_FDCWD, path, owner, group, 0); +# endif } #endif diff --git a/libc/sysdeps/linux/common/fstatat.c b/libc/sysdeps/linux/common/fstatat.c index 33daa7c..21f1383 100644 --- a/libc/sysdeps/linux/common/fstatat.c +++ b/libc/sysdeps/linux/common/fstatat.c @@ -11,7 +11,7 @@ #include "xstatconv.h" /* 64bit ports tend to favor newfstatat() */ -#ifdef __NR_newfstatat +#if defined(__NR_newfstatat) && !defined(__NR_fstatat64) # define __NR_fstatat64 __NR_newfstatat #endif diff --git a/libc/sysdeps/linux/common/fstatat64.c b/libc/sysdeps/linux/common/fstatat64.c index 95627af..78a27b9 100644 --- a/libc/sysdeps/linux/common/fstatat64.c +++ b/libc/sysdeps/linux/common/fstatat64.c @@ -13,7 +13,7 @@ #ifdef __UCLIBC_HAS_LFS__ /* 64bit ports tend to favor newfstatat() */ -#ifdef __NR_newfstatat +#if defined(__NR_newfstatat) && !defined(__NR_fstatat64) # define __NR_fstatat64 __NR_newfstatat #endif diff --git a/libc/sysdeps/linux/common/lchown.c b/libc/sysdeps/linux/common/lchown.c index c0f8ce7..83dabb9 100644 --- a/libc/sysdeps/linux/common/lchown.c +++ b/libc/sysdeps/linux/common/lchown.c @@ -10,6 +10,7 @@ #include <sys/syscall.h> #include <unistd.h> #include <bits/wordsize.h> +#include <fcntl.h> #if (__WORDSIZE == 32 && defined(__NR_lchown32)) || __WORDSIZE == 64 # ifdef __NR_lchown32 @@ -21,10 +22,6 @@ _syscall3(int, lchown, const char *, path, uid_t, owner, gid_t, group) #else -# define __NR___syscall_lchown __NR_lchown -static __inline__ _syscall3(int, __syscall_lchown, const char *, path, - __kernel_uid_t, owner, __kernel_gid_t, group) - int lchown(const char *path, uid_t owner, gid_t group) { if (((owner + 1) > (uid_t) ((__kernel_uid_t) - 1U)) @@ -32,7 +29,11 @@ int lchown(const char *path, uid_t owner, gid_t group) __set_errno(EINVAL); return -1; } - return __syscall_lchown(path, owner, group); +# if defined(__NR_lchown) + return INLINE_SYSCALL(lchown, 3, path, owner, group); +# elif defined(__NR_fchownat) + return INLINE_SYSCALL(fchownat, 5, AT_FDCWD, path, owner, group, AT_SYMLINK_NOFOLLOW); +# endif } #endif diff --git a/libc/sysdeps/linux/common/link.c b/libc/sysdeps/linux/common/link.c index b5e5536..23e985d 100644 --- a/libc/sysdeps/linux/common/link.c +++ b/libc/sysdeps/linux/common/link.c @@ -9,4 +9,12 @@ #include <sys/syscall.h> #include <unistd.h> +#include <fcntl.h> +#if defined(__NR_link) _syscall2(int, link, const char *, oldpath, const char *, newpath) +#elif defined(__NR_linkat) +int link(const char * oldpath, const char * newpath) +{ + return INLINE_SYSCALL(linkat, 5, AT_FDCWD, oldpath, AT_FDCWD, newpath, 0); +} +#endif diff --git a/libc/sysdeps/linux/common/lstat.c b/libc/sysdeps/linux/common/lstat.c index db72d1f..7178834 100644 --- a/libc/sysdeps/linux/common/lstat.c +++ b/libc/sysdeps/linux/common/lstat.c @@ -9,20 +9,25 @@ #include <sys/syscall.h> #include <unistd.h> +#include <fcntl.h> #include <sys/stat.h> #include "xstatconv.h" int lstat(const char *file_name, struct stat *buf) { int result; -#ifdef __NR_lstat64 +#if defined __NR_lstat64 || defined __NR_fstatat64 /* normal stat call has limited values for various stat elements * e.g. uid device major/minor etc. * so we use 64 variant if available * in order to get newer versions of stat elements */ struct kernel_stat64 kbuf; +# ifdef __NR_lstat64 result = INLINE_SYSCALL(lstat64, 2, file_name, &kbuf); +# else + result = INLINE_SYSCALL(fstatat64, 4, AT_FDCWD, file_name, &kbuf, AT_SYMLINK_NOFOLLOW); +# endif if (result == 0) { __xstat32_conv(&kbuf, buf); } @@ -38,7 +43,7 @@ int lstat(const char *file_name, struct stat *buf) } libc_hidden_def(lstat) -#if ! defined __NR_lstat64 && defined __UCLIBC_HAS_LFS__ +#if ! defined __NR_lstat64 && ! defined __NR_fstatat64 && defined __UCLIBC_HAS_LFS__ strong_alias_untyped(lstat,lstat64) libc_hidden_def(lstat64) #endif diff --git a/libc/sysdeps/linux/common/lstat64.c b/libc/sysdeps/linux/common/lstat64.c index 235b76d..3abec67 100644 --- a/libc/sysdeps/linux/common/lstat64.c +++ b/libc/sysdeps/linux/common/lstat64.c @@ -9,22 +9,23 @@ #include <sys/syscall.h> -#if defined __UCLIBC_HAS_LFS__ && defined __NR_lstat64 +#if defined __UCLIBC_HAS_LFS__ && (defined __NR_lstat64 || defined __NR_fstatat64) # include <unistd.h> # include <sys/stat.h> +# include <fcntl.h> # include "xstatconv.h" -# define __NR___syscall_lstat64 __NR_lstat64 -static __inline__ _syscall2(int, __syscall_lstat64, const char *, file_name, - struct kernel_stat64 *, buf) - int lstat64(const char *file_name, struct stat64 *buf) { int result; struct kernel_stat64 kbuf; - result = __syscall_lstat64(file_name, &kbuf); +# if defined __NR_lstat64 + result = INLINE_SYSCALL(lstat64, 2, file_name, &kbuf); +# elif defined __NR_fstatat64 + result = INLINE_SYSCALL(fstatat64, 4, AT_FDCWD, file_name, &kbuf, AT_SYMLINK_NOFOLLOW); +# endif if (result == 0) { __xstat64_conv(&kbuf, buf); } diff --git a/libc/sysdeps/linux/common/mkdir.c b/libc/sysdeps/linux/common/mkdir.c index fbc587d..c0199d8 100644 --- a/libc/sysdeps/linux/common/mkdir.c +++ b/libc/sysdeps/linux/common/mkdir.c @@ -9,14 +9,15 @@ #include <sys/syscall.h> #include <sys/stat.h> +#include <fcntl.h> -#define __NR___syscall_mkdir __NR_mkdir -static __inline__ _syscall2(int, __syscall_mkdir, const char *, pathname, - __kernel_mode_t, mode) - int mkdir(const char *pathname, mode_t mode) { - return (__syscall_mkdir(pathname, mode)); +#ifdef __NR_mkdir + return INLINE_SYSCALL(mkdir, 2, pathname, (__kernel_mode_t)mode); +#else + return INLINE_SYSCALL(mkdirat, 3, AT_FDCWD, pathname, (__kernel_mode_t)mode); +#endif } libc_hidden_def(mkdir) diff --git a/libc/sysdeps/linux/common/mknod.c b/libc/sysdeps/linux/common/mknod.c index b52c8c5..9954626 100644 --- a/libc/sysdeps/linux/common/mknod.c +++ b/libc/sysdeps/linux/common/mknod.c @@ -9,6 +9,7 @@ #include <sys/syscall.h> #include <sys/stat.h> +#include <fcntl.h> int mknod(const char *path, mode_t mode, dev_t dev) { @@ -17,6 +18,10 @@ int mknod(const char *path, mode_t mode, dev_t dev) /* We must convert the value to dev_t type used by the kernel. */ k_dev = (dev) & ((1ULL << 32) - 1); +#ifdef __NR_mknod return INLINE_SYSCALL(mknod, 3, path, mode, (unsigned int)k_dev); +#elif defined __NR_mknodat + return INLINE_SYSCALL(mknodat, 4, AT_FDCWD, path, mode, (unsigned int)k_dev); +#endif } libc_hidden_def(mknod) diff --git a/libc/sysdeps/linux/common/not-cancel.h b/libc/sysdeps/linux/common/not-cancel.h index 9418417..d70fac4 100644 --- a/libc/sysdeps/linux/common/not-cancel.h +++ b/libc/sysdeps/linux/common/not-cancel.h @@ -19,12 +19,20 @@ 02111-1307 USA. */ #include <sysdep.h> +#include <fcntl.h> /* Uncancelable open. */ +#ifdef __NR_open #define open_not_cancel(name, flags, mode) \ INLINE_SYSCALL (open, 3, (const char *) (name), (flags), (mode)) #define open_not_cancel_2(name, flags) \ INLINE_SYSCALL (open, 2, (const char *) (name), (flags)) +#elif defined (__NR_openat) +#define open_not_cancel(name, flags, mode) \ + INLINE_SYSCALL (openat, 4, AT_FDCWD, (const char *) (name), (flags), (mode)) +#define open_not_cancel_2(name, flags) \ + INLINE_SYSCALL (openat, 3, AT_FDCWD, (const char *) (name), (flags)) +#endif /* Uncancelable close. */ #define close_not_cancel(fd) \ diff --git a/libc/sysdeps/linux/common/open.c b/libc/sysdeps/linux/common/open.c index 9fb694d..e49a000 100644 --- a/libc/sysdeps/linux/common/open.c +++ b/libc/sysdeps/linux/common/open.c @@ -14,9 +14,17 @@ #include <string.h> #include <sys/param.h> +#ifdef __NR_open #define __NR___syscall_open __NR_open static __inline__ _syscall3(int, __syscall_open, const char *, file, int, flags, __kernel_mode_t, mode) +#endif +#ifdef __NR_openat +#define __NR___syscall_openat __NR_openat +static __inline__ _syscall4(int, __syscall_openat, int, fd, const char *, file, + int, flags, __kernel_mode_t, mode) +#define __syscall_open(a,b,c) __syscall_openat(AT_FDCWD, (a), (b), (c)) +#endif int open(const char *file, int oflag, ...) { diff --git a/libc/sysdeps/linux/common/readlink.c b/libc/sysdeps/linux/common/readlink.c index ef9e835..52d49ec 100644 --- a/libc/sysdeps/linux/common/readlink.c +++ b/libc/sysdeps/linux/common/readlink.c @@ -9,6 +9,14 @@ #include <sys/syscall.h> #include <unistd.h> +#include <fcntl.h> +#ifdef __NR_readlink _syscall3(ssize_t, readlink, const char *, path, char *, buf, size_t, bufsiz) +#elif defined(__NR_readlinkat) +ssize_t readlink(const char *path, char *buf, size_t bufsiz) +{ + return INLINE_SYSCALL(readlinkat, 4, AT_FDCWD, path, buf, bufsiz); +} +#endif libc_hidden_def(readlink) diff --git a/libc/sysdeps/linux/common/rename.c b/libc/sysdeps/linux/common/rename.c index 9d8397a..3a1e721 100644 --- a/libc/sysdeps/linux/common/rename.c +++ b/libc/sysdeps/linux/common/rename.c @@ -12,13 +12,14 @@ #include <string.h> #include <sys/param.h> #include <stdio.h> - -#define __NR___syscall_rename __NR_rename -static __inline__ _syscall2(int, __syscall_rename, const char *, oldpath, - const char *, newpath) +#include <fcntl.h> int rename(const char * oldpath, const char * newpath) { - return __syscall_rename(oldpath, newpath); +# ifdef __NR_rename + return INLINE_SYSCALL(rename, 2, oldpath, newpath); +# else + return INLINE_SYSCALL(renameat, 4, AT_FDCWD, oldpath, AT_FDCWD, newpath); +# endif } diff --git a/libc/sysdeps/linux/common/rmdir.c b/libc/sysdeps/linux/common/rmdir.c index bad6654..ffe34a5 100644 --- a/libc/sysdeps/linux/common/rmdir.c +++ b/libc/sysdeps/linux/common/rmdir.c @@ -9,7 +9,15 @@ #include <sys/syscall.h> #include <unistd.h> +#include <fcntl.h> - +#if defined(__NR_rmdir) _syscall1(int, rmdir, const char *, pathname) +#elif defined(__NR_unlinkat) + +int rmdir(const char * pathname) +{ + return INLINE_SYSCALL(unlinkat, 3, AT_FDCWD, pathname, AT_REMOVEDIR); +} +#endif libc_hidden_def(rmdir) diff --git a/libc/sysdeps/linux/common/stubs.c b/libc/sysdeps/linux/common/stubs.c index 3567b07..30dc6e7 100644 --- a/libc/sysdeps/linux/common/stubs.c +++ b/libc/sysdeps/linux/common/stubs.c @@ -403,7 +403,7 @@ make_stub(swapoff) make_stub(swapon) #endif -#ifndef __NR_symlink +#if !defined __NR_symlink && !defined __NR_symlinkat make_stub(symlink) #endif @@ -443,7 +443,7 @@ make_stub(lutimes) # endif #endif -#if !defined __NR_utime && !defined __NR_utimes +#if !defined __NR_utime && !defined __NR_utimes && !defined __NR_utimensat /*make_stub(utime) obsoleted */ make_stub(utimes) #endif diff --git a/libc/sysdeps/linux/common/symlink.c b/libc/sysdeps/linux/common/symlink.c index e53e8d4..bde0d5e 100644 --- a/libc/sysdeps/linux/common/symlink.c +++ b/libc/sysdeps/linux/common/symlink.c @@ -10,5 +10,13 @@ #include <sys/syscall.h> #if defined __USE_BSD || defined __USE_UNIX98 || defined __USE_XOPEN2K #include <unistd.h> +#include <fcntl.h> +# ifdef __NR_symlink _syscall2(int, symlink, const char *, oldpath, const char *, newpath) +# elif defined __NR_symlinkat +int symlink(const char *oldpath, const char *newpath) +{ + return INLINE_SYSCALL(symlinkat, 3, oldpath, AT_FDCWD, newpath); +} +# endif #endif diff --git a/libc/sysdeps/linux/common/unlink.c b/libc/sysdeps/linux/common/unlink.c index 513cdd5..b55b898 100644 --- a/libc/sysdeps/linux/common/unlink.c +++ b/libc/sysdeps/linux/common/unlink.c @@ -11,5 +11,13 @@ #include <unistd.h> +#if defined __NR_unlink _syscall1(int, unlink, const char *, pathname) +#elif defined __NR_unlinkat +#include <fcntl.h> +int unlink(const char *pathname) +{ + return INLINE_SYSCALL(unlinkat, 3, AT_FDCWD, pathname, 0); +} +#endif libc_hidden_def(unlink) diff --git a/libc/sysdeps/linux/common/utimes.c b/libc/sysdeps/linux/common/utimes.c index 99d9202..d9d63cc 100644 --- a/libc/sysdeps/linux/common/utimes.c +++ b/libc/sysdeps/linux/common/utimes.c @@ -10,10 +10,32 @@ #include <sys/syscall.h> #include <utime.h> #include <sys/time.h> - +#include <stdlib.h> +#include <fcntl.h> #ifdef __NR_utimes _syscall2(int, utimes, const char *, file, const struct timeval *, tvp) +#elif defined __NR_utimensat + +int utimes(const char *file, const struct timeval tvp[2]) +{ + struct timespec ts[2]; + + if (tvp) { + if (tvp[0].tv_usec >= 1000000 || tvp[0].tv_usec < 0 || + tvp[1].tv_usec >= 1000000 || tvp[1].tv_usec < 0) + return -EINVAL; + + ts[0].tv_sec = tvp[0].tv_sec; + ts[0].tv_nsec = 1000 * tvp[0].tv_usec; + ts[1].tv_sec = tvp[1].tv_sec; + ts[1].tv_nsec = 1000 * tvp[1].tv_usec; + + return INLINE_SYSCALL(utimensat, 4, AT_FDCWD, file, ts, 0); + } else { + return INLINE_SYSCALL(utimensat, 4, AT_FDCWD, file, NULL, 0); + } +} #else #include <stdlib.h> diff --git a/libpthread/linuxthreads.old/sysdeps/pthread/not-cancel.h b/libpthread/linuxthreads.old/sysdeps/pthread/not-cancel.h index 80d33be..820dd01 100644 --- a/libpthread/linuxthreads.old/sysdeps/pthread/not-cancel.h +++ b/libpthread/linuxthreads.old/sysdeps/pthread/not-cancel.h @@ -20,12 +20,20 @@ #include <sys/types.h> #include <sysdep.h> +#include <fcntl.h> /* Uncancelable open. */ +#ifdef __NR_open #define open_not_cancel(name, flags, mode) \ INLINE_SYSCALL (open, 3, (const char *) (name), (flags), (mode)) #define open_not_cancel_2(name, flags) \ INLINE_SYSCALL (open, 2, (const char *) (name), (flags)) +#elif defined __NR_openat +#define open_not_cancel(name, flags, mode) \ + INLINE_SYSCALL (openat, 4, AT_FDCWD, (const char *) (name), (flags), (mode)) +#define open_not_cancel_2(name, flags) \ + INLINE_SYSCALL (openat, 3, AT_FDCWD, (const char *) (name), (flags)) +#endif /* Uncancelable openat. */ #if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt -- 1.7.9.1 _______________________________________________ uClibc mailing list uClibc@uclibc.org http://lists.busybox.net/mailman/listinfo/uclibc