mirror of
git://sourceware.org/git/glibc.git
synced 2024-11-21 01:12:26 +08:00
Remove __ASSUME_ATFCTS conditionals in sysdeps/unix/sysv/linux/.
This patch cleans up for __ASSUME_ATFCTS now always being true for the supported Linux kernel versions by removing conditional code in sysdeps/unix/sysv/linux. Several fchownat.c files that were only present because of differences in the fallback syscalls used (depending on the architecture-specific names of chown-related syscalls for 32-bit uids) are removed. Files that looks like they could be replaced by syscalls.list entries have the standard "Consider moving to syscalls.list." comment (see bug 14138) added. Conditionals on the relevant __NR_* syscall numbers being defined are also removed, since my analysis indicated that the relevant syscalls are always defined for all relevant kernel versions using any affected file. Much of the removed fallback code had unbounded stack allocations, so this reduces the number of cases to consider for anyone reviewing uses of alloca and VLAs in glibc. There remain tests of __ASSUME_ATFCTS in io/openat.c (to determine whether to define __have_atfcts) and sysdeps/posix/getcwd.c (which also uses __have_atfcts); thus, the definition of __ASSUME_ATFCTS remains in kernel-features.h. The logical condition relevant there is whether openat64_not_cancel_3 is known to work. Hurd doesn't use this version of getcwd at all, so the conditionals in getcwd.c are always true in glibc. However, this code is also used in gnulib. So the best way to deal with the conditionals there may be for gnulib people to deal with merging all relevant changes in both directions between the glibc and gnulib versions of this file, at the end of which the openat conditionals should be in whatever form is best for gnulib, and hardcoded in the _LIBC case to having openat supported. Tested by comparing before-and-after disassembly of installed (stripped) shared libraries, on x86_64 and x86. On x86 the patch made no change to the disassembly; on x86_64, the only changes were in readlinkat, where formerly the return value from the readlinkat syscall was stored in an int variable before being converted to ssize_t for the return, and now the return value is returned directly without truncation to int. I think it's clearly correct not to truncate the return value (although I also think the truncation would not have been a user-visible bug because the kernel would never have returned a value it could have affected). * include/fcntl.h (__atfct_seterrno): Remove prototype. (__atfct_seterrno_2): Likewise. * sysdeps/unix/sysv/linux/alpha/dl-fxstatat64.c: Do not include <kernel-features.h>. (__ASSUME_ATFCTS): Do not undefine and redefine. * sysdeps/unix/sysv/linux/alpha/fxstatat.c [__ASSUME_ATFCTS] (__have_atfcts): Remove conditional definition. (__fxstatat([__NR_fstatat64]: Make code unconditional. (__fxstatat) [!__ASSUME_ATFCTS]: Remove conditional code and code unreachable if [__ASSUME_ATFCTS]. * sysdeps/unix/sysv/linux/dl-fxstatat64.c (__ASSUME_ATFCTS): Do not undefine and redefine. * sysdeps/unix/sysv/linux/faccessat.c: Do not include <kernel-features.h>. (faccessat) [__NR_faccessat]: Make code unconditional. (faccessat) [!__ASSUME_ATFCTS]: Remove conditional code. * sysdeps/unix/sysv/linux/fchmodat.c: Do not include <kernel-features.h>. (fchmodat) [__NR_fchmodat]: Make code unconditional. (fchmodat) [!__ASSUME_ATFCTS]: Remove conditional code. * sysdeps/unix/sysv/linux/fchownat.c: Do not include <kernel-features.h>. (fchownat) [__NR_fchownat]: Make code unconditional. (fchownat) [!__ASSUME_ATFCTS]: Remove conditional code. * sysdeps/unix/sysv/linux/futimesat.c: Do not include <kernel-features.h>. (futimesat) [__NR_futimesat]: Make code unconditional. (futimesat) [!__ASSUME_ATFCTS]: Remove conditional code. * sysdeps/unix/sysv/linux/fxstatat.c: Do not include <kernel-features.h>. (__fxstatat) [__NR_newfstatat]: Make code unconditional. (__fxstatat) [!__ASSUME_ATFCTS]: Remove conditional code. * sysdeps/unix/sysv/linux/fxstatat64.c: Do not include <kernel-features.h>. (__fxstatat64) [__NR_fstatat64]: Make code unconditional. (__fxstatat64) [!__ASSUME_ATFCTS]: Remove conditional code. * sysdeps/unix/sysv/linux/i386/fchownat.c: Remove file. * sysdeps/unix/sysv/linux/i386/fxstatat.c: Do not include <kernel-features.h>. (__fxstatat) [__NR_fstatat64]: Make code unconditional. (__fxstatat) [!__ASSUME_ATFCTS]: Remove conditional code. * sysdeps/unix/sysv/linux/linkat.c: Do not include <kernel-features.h>. (linkat) [__NR_linkat]: Make code unconditional. (linkat) [!__ASSUME_ATFCTS]: Remove conditional code. * sysdeps/unix/sysv/linux/m68k/fchownat.c: Remove file. * sysdeps/unix/sysv/linux/mips/mips64/fxstatat64.c: Do not include <kernel-features.h>. (__fxstatat64) [__NR_newfstatat]: Make code unconditional. (__fxstatat64) [!__ASSUME_ATFCTS]: Remove conditional code. * sysdeps/unix/sysv/linux/mkdirat.c: Do not include <kernel-features.h>. (mkdirat) [__NR_mkdirat]: Make code unconditional. (mkdirat) [!__ASSUME_ATFCTS]: Remove conditional code. * sysdeps/unix/sysv/linux/openat.c: Do not include <kernel-features.h>. [!__ASSUME_ATFCTS] (__atfct_seterrno): Remove function. [!__ASSUME_ATFCTS] (__have_atfcts): Remove variable. (OPENAT_NOT_CANCEL) [__NR_openat]: Make code unconditional. (OPENAT_NOT_CANCEL) [!__ASSUME_ATFCTS]: Remove conditional code. * sysdeps/unix/sysv/linux/powerpc/fchownat.c: Remove file. * sysdeps/unix/sysv/linux/readlinkat.c: Do not include <kernel-features.h>. (readlinkat) [__NR_readlinkat]: Make code unconditional. (readlinkat) [!__ASSUME_ATFCTS]: Remove conditional code. Return result of INLINE_SYSCALL directly, not via int variable. * sysdeps/unix/sysv/linux/renameat.c: Do not include <kernel-features.h>. [!__ASSUME_ATFCTS] (__atfct_seterrno_2): Remove function. (renameat) [__NR_renameat]: Make code unconditional. (renameat) [!__ASSUME_ATFCTS]: Remove conditional code. * sysdeps/unix/sysv/linux/s390/s390-32/fchownat.c: Remove file. * sysdeps/unix/sysv/linux/sh/fchownat.c: Remove file. * sysdeps/unix/sysv/linux/sparc/sparc32/fchownat.c: Remove file. * sysdeps/unix/sysv/linux/sparc/sparc64/dl-fxstatat64.c (__ASSUME_ATFCTS): Do not undefine and redefine. * sysdeps/unix/sysv/linux/symlinkat.c: Do not include <kernel-features.h>. (symlinkat) [__NR_symlinkat]: Make code unconditional. (symlinkat) [!__ASSUME_ATFCTS]: Remove conditional code. * sysdeps/unix/sysv/linux/unlinkat.c: Do not include <kernel-features.h>. (unlinkat) [__NR_unlinkat]: Make code unconditional. (unlinkat) [!__ASSUME_ATFCTS]: Remove conditional code. * sysdeps/unix/sysv/linux/wordsize-64/dl-fxstatat64.c (__ASSUME_ATFCTS): Do not undefine and redefine. * sysdeps/unix/sysv/linux/wordsize-64/fxstatat.c: Do not include <kernel-features.h>. (__fxstatat) [__NR_newfstatat]: Make code unconditional. (__fxstatat) [!__ASSUME_ATFCTS]: Remove conditional code. * sysdeps/unix/sysv/linux/xmknodat.c: Do not include <kernel-features.h>. (__xmknodat) [__NR_mknodat]: Make code unconditional. (__xmknodat) [!__ASSUME_ATFCTS]: Remove conditional code.
This commit is contained in:
parent
224c6c51c5
commit
809fdf0d23
97
ChangeLog
97
ChangeLog
@ -1,3 +1,100 @@
|
||||
2014-06-20 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
* include/fcntl.h (__atfct_seterrno): Remove prototype.
|
||||
(__atfct_seterrno_2): Likewise.
|
||||
* sysdeps/unix/sysv/linux/alpha/dl-fxstatat64.c: Do not include
|
||||
<kernel-features.h>.
|
||||
(__ASSUME_ATFCTS): Do not undefine and redefine.
|
||||
* sysdeps/unix/sysv/linux/alpha/fxstatat.c [__ASSUME_ATFCTS]
|
||||
(__have_atfcts): Remove conditional definition.
|
||||
(__fxstatat([__NR_fstatat64]: Make code unconditional.
|
||||
(__fxstatat) [!__ASSUME_ATFCTS]: Remove conditional code and code
|
||||
unreachable if [__ASSUME_ATFCTS].
|
||||
* sysdeps/unix/sysv/linux/dl-fxstatat64.c (__ASSUME_ATFCTS): Do
|
||||
not undefine and redefine.
|
||||
* sysdeps/unix/sysv/linux/faccessat.c: Do not include
|
||||
<kernel-features.h>.
|
||||
(faccessat) [__NR_faccessat]: Make code unconditional.
|
||||
(faccessat) [!__ASSUME_ATFCTS]: Remove conditional code.
|
||||
* sysdeps/unix/sysv/linux/fchmodat.c: Do not include
|
||||
<kernel-features.h>.
|
||||
(fchmodat) [__NR_fchmodat]: Make code unconditional.
|
||||
(fchmodat) [!__ASSUME_ATFCTS]: Remove conditional code.
|
||||
* sysdeps/unix/sysv/linux/fchownat.c: Do not include
|
||||
<kernel-features.h>.
|
||||
(fchownat) [__NR_fchownat]: Make code unconditional.
|
||||
(fchownat) [!__ASSUME_ATFCTS]: Remove conditional code.
|
||||
* sysdeps/unix/sysv/linux/futimesat.c: Do not include
|
||||
<kernel-features.h>.
|
||||
(futimesat) [__NR_futimesat]: Make code unconditional.
|
||||
(futimesat) [!__ASSUME_ATFCTS]: Remove conditional code.
|
||||
* sysdeps/unix/sysv/linux/fxstatat.c: Do not include
|
||||
<kernel-features.h>.
|
||||
(__fxstatat) [__NR_newfstatat]: Make code unconditional.
|
||||
(__fxstatat) [!__ASSUME_ATFCTS]: Remove conditional code.
|
||||
* sysdeps/unix/sysv/linux/fxstatat64.c: Do not include
|
||||
<kernel-features.h>.
|
||||
(__fxstatat64) [__NR_fstatat64]: Make code unconditional.
|
||||
(__fxstatat64) [!__ASSUME_ATFCTS]: Remove conditional code.
|
||||
* sysdeps/unix/sysv/linux/i386/fchownat.c: Remove file.
|
||||
* sysdeps/unix/sysv/linux/i386/fxstatat.c: Do not include
|
||||
<kernel-features.h>.
|
||||
(__fxstatat) [__NR_fstatat64]: Make code unconditional.
|
||||
(__fxstatat) [!__ASSUME_ATFCTS]: Remove conditional code.
|
||||
* sysdeps/unix/sysv/linux/linkat.c: Do not include
|
||||
<kernel-features.h>.
|
||||
(linkat) [__NR_linkat]: Make code unconditional.
|
||||
(linkat) [!__ASSUME_ATFCTS]: Remove conditional code.
|
||||
* sysdeps/unix/sysv/linux/m68k/fchownat.c: Remove file.
|
||||
* sysdeps/unix/sysv/linux/mips/mips64/fxstatat64.c: Do not include
|
||||
<kernel-features.h>.
|
||||
(__fxstatat64) [__NR_newfstatat]: Make code unconditional.
|
||||
(__fxstatat64) [!__ASSUME_ATFCTS]: Remove conditional code.
|
||||
* sysdeps/unix/sysv/linux/mkdirat.c: Do not include
|
||||
<kernel-features.h>.
|
||||
(mkdirat) [__NR_mkdirat]: Make code unconditional.
|
||||
(mkdirat) [!__ASSUME_ATFCTS]: Remove conditional code.
|
||||
* sysdeps/unix/sysv/linux/openat.c: Do not include
|
||||
<kernel-features.h>.
|
||||
[!__ASSUME_ATFCTS] (__atfct_seterrno): Remove function.
|
||||
[!__ASSUME_ATFCTS] (__have_atfcts): Remove variable.
|
||||
(OPENAT_NOT_CANCEL) [__NR_openat]: Make code unconditional.
|
||||
(OPENAT_NOT_CANCEL) [!__ASSUME_ATFCTS]: Remove conditional code.
|
||||
* sysdeps/unix/sysv/linux/powerpc/fchownat.c: Remove file.
|
||||
* sysdeps/unix/sysv/linux/readlinkat.c: Do not include
|
||||
<kernel-features.h>.
|
||||
(readlinkat) [__NR_readlinkat]: Make code unconditional.
|
||||
(readlinkat) [!__ASSUME_ATFCTS]: Remove conditional code. Return
|
||||
result of INLINE_SYSCALL directly, not via int variable.
|
||||
* sysdeps/unix/sysv/linux/renameat.c: Do not include
|
||||
<kernel-features.h>.
|
||||
[!__ASSUME_ATFCTS] (__atfct_seterrno_2): Remove function.
|
||||
(renameat) [__NR_renameat]: Make code unconditional.
|
||||
(renameat) [!__ASSUME_ATFCTS]: Remove conditional code.
|
||||
* sysdeps/unix/sysv/linux/s390/s390-32/fchownat.c: Remove file.
|
||||
* sysdeps/unix/sysv/linux/sh/fchownat.c: Remove file.
|
||||
* sysdeps/unix/sysv/linux/sparc/sparc32/fchownat.c: Remove file.
|
||||
* sysdeps/unix/sysv/linux/sparc/sparc64/dl-fxstatat64.c
|
||||
(__ASSUME_ATFCTS): Do not undefine and redefine.
|
||||
* sysdeps/unix/sysv/linux/symlinkat.c: Do not include
|
||||
<kernel-features.h>.
|
||||
(symlinkat) [__NR_symlinkat]: Make code unconditional.
|
||||
(symlinkat) [!__ASSUME_ATFCTS]: Remove conditional code.
|
||||
* sysdeps/unix/sysv/linux/unlinkat.c: Do not include
|
||||
<kernel-features.h>.
|
||||
(unlinkat) [__NR_unlinkat]: Make code unconditional.
|
||||
(unlinkat) [!__ASSUME_ATFCTS]: Remove conditional code.
|
||||
* sysdeps/unix/sysv/linux/wordsize-64/dl-fxstatat64.c
|
||||
(__ASSUME_ATFCTS): Do not undefine and redefine.
|
||||
* sysdeps/unix/sysv/linux/wordsize-64/fxstatat.c: Do not include
|
||||
<kernel-features.h>.
|
||||
(__fxstatat) [__NR_newfstatat]: Make code unconditional.
|
||||
(__fxstatat) [!__ASSUME_ATFCTS]: Remove conditional code.
|
||||
* sysdeps/unix/sysv/linux/xmknodat.c: Do not include
|
||||
<kernel-features.h>.
|
||||
(__xmknodat) [__NR_mknodat]: Make code unconditional.
|
||||
(__xmknodat) [!__ASSUME_ATFCTS]: Remove conditional code.
|
||||
|
||||
2014-06-20 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
* sysdeps/x86_64/multiarch/rtld-strlen.S: Removed.
|
||||
|
@ -31,14 +31,6 @@ extern int __openat_2 (int __fd, const char *__path, int __oflag);
|
||||
extern int __openat64_2 (int __fd, const char *__path, int __oflag);
|
||||
|
||||
|
||||
/* Helper functions for the various *at functions. For Linux. */
|
||||
extern void __atfct_seterrno (int errval, int fd, const char *buf)
|
||||
attribute_hidden;
|
||||
extern void __atfct_seterrno_2 (int errval, int fd1, const char *buf1,
|
||||
int fd2, const char *buf2)
|
||||
attribute_hidden;
|
||||
|
||||
|
||||
/* Flag determining whether the *at system calls are available. */
|
||||
extern int __have_atfcts attribute_hidden;
|
||||
|
||||
|
@ -1,9 +1 @@
|
||||
/* In this implementation we do not really care whether the call fails
|
||||
because of missing kernel support since we do not even call the
|
||||
function in this case. */
|
||||
/* For Alpha, in <kernel-features.h> we redefine the default definition of
|
||||
when __ASSUME_ATFCTS is present. The hack must wait until after that. */
|
||||
#include <kernel-features.h>
|
||||
#undef __ASSUME_ATFCTS
|
||||
#define __ASSUME_ATFCTS 1
|
||||
#include "fxstatat.c"
|
||||
|
@ -29,10 +29,6 @@
|
||||
|
||||
#undef __fxstatat64
|
||||
|
||||
#ifdef __ASSUME_ATFCTS
|
||||
# define __have_atfcts 1
|
||||
#endif
|
||||
|
||||
/* Get information about the file NAME in BUF. */
|
||||
int
|
||||
__fxstatat (int vers, int fd, const char *file, struct stat *st, int flag)
|
||||
@ -45,67 +41,11 @@ __fxstatat (int vers, int fd, const char *file, struct stat *st, int flag)
|
||||
cannot actually check this, lest the compiler not optimize the rest
|
||||
of the function away. */
|
||||
|
||||
#ifdef __NR_fstatat64
|
||||
if (__have_atfcts >= 0)
|
||||
{
|
||||
result = INTERNAL_SYSCALL (fstatat64, err, 4, fd, file, st, flag);
|
||||
if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
|
||||
return result;
|
||||
errno_out = INTERNAL_SYSCALL_ERRNO (result, err);
|
||||
#ifndef __ASSUME_ATFCTS
|
||||
if (errno_out == ENOSYS)
|
||||
__have_atfcts = -1;
|
||||
else
|
||||
#endif
|
||||
{
|
||||
__set_errno (errno_out);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif /* __NR_fstatat64 */
|
||||
|
||||
if (flag & ~AT_SYMLINK_NOFOLLOW)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
char *buf = NULL;
|
||||
|
||||
if (fd != AT_FDCWD && file[0] != '/')
|
||||
{
|
||||
size_t filelen = strlen (file);
|
||||
if (__builtin_expect (filelen == 0, 0))
|
||||
{
|
||||
__set_errno (ENOENT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static const char procfd[] = "/proc/self/fd/%d/%s";
|
||||
/* Buffer for the path name we are going to use. It consists of
|
||||
- the string /proc/self/fd/
|
||||
- the file descriptor number
|
||||
- the file name provided.
|
||||
The final NUL is included in the sizeof. A bit of overhead
|
||||
due to the format elements compensates for possible negative
|
||||
numbers. */
|
||||
size_t buflen = sizeof (procfd) + sizeof (int) * 3 + filelen;
|
||||
buf = alloca (buflen);
|
||||
|
||||
__snprintf (buf, buflen, procfd, fd, file);
|
||||
file = buf;
|
||||
}
|
||||
|
||||
if (flag & AT_SYMLINK_NOFOLLOW)
|
||||
result = INTERNAL_SYSCALL (lstat64, err, 2, file, st);
|
||||
else
|
||||
result = INTERNAL_SYSCALL (stat64, err, 2, file, st);
|
||||
result = INTERNAL_SYSCALL (fstatat64, err, 4, fd, file, st, flag);
|
||||
if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
|
||||
return result;
|
||||
|
||||
errno_out = INTERNAL_SYSCALL_ERRNO (result, err);
|
||||
__atfct_seterrno (errno_out, fd, buf);
|
||||
|
||||
__set_errno (errno_out);
|
||||
return -1;
|
||||
}
|
||||
libc_hidden_def (__fxstatat)
|
||||
|
@ -1,6 +1 @@
|
||||
/* In this implementation we do not really care whether the call fails
|
||||
because of missing kernel support since we do not even call the
|
||||
function in this case. */
|
||||
#undef __ASSUME_ATFCTS
|
||||
#define __ASSUME_ATFCTS 1
|
||||
#include <fxstatat64.c>
|
||||
|
@ -24,7 +24,6 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <alloca.h>
|
||||
#include <kernel-features.h>
|
||||
#include <sysdep.h>
|
||||
|
||||
|
||||
@ -41,76 +40,8 @@ faccessat (fd, file, mode, flag)
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef __NR_faccessat
|
||||
if ((flag == 0 || ((flag & ~AT_EACCESS) == 0 && ! __libc_enable_secure))
|
||||
# ifndef __ASSUME_ATFCTS
|
||||
&& __have_atfcts >= 0
|
||||
# endif
|
||||
)
|
||||
{
|
||||
int result = INLINE_SYSCALL (faccessat, 3, fd, file, mode);
|
||||
# ifndef __ASSUME_ATFCTS
|
||||
if (result == -1 && errno == ENOSYS)
|
||||
__have_atfcts = -1;
|
||||
else
|
||||
# endif
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __ASSUME_ATFCTS
|
||||
if ((!(flag & AT_EACCESS) || ! __libc_enable_secure)
|
||||
# ifndef __NR_laccess /* Linux so far has no laccess syscall. */
|
||||
&& !(flag & AT_SYMLINK_NOFOLLOW)
|
||||
# endif
|
||||
)
|
||||
{
|
||||
/* If we are not set-uid or set-gid, access does the same. */
|
||||
char *buf = NULL;
|
||||
|
||||
if (fd != AT_FDCWD && file[0] != '/')
|
||||
{
|
||||
size_t filelen = strlen (file);
|
||||
if (__glibc_unlikely (filelen == 0))
|
||||
{
|
||||
__set_errno (ENOENT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static const char procfd[] = "/proc/self/fd/%d/%s";
|
||||
/* Buffer for the path name we are going to use. It consists of
|
||||
- the string /proc/self/fd/
|
||||
- the file descriptor number
|
||||
- the file name provided.
|
||||
The final NUL is included in the sizeof. A bit of overhead
|
||||
due to the format elements compensates for possible negative
|
||||
numbers. */
|
||||
size_t buflen = sizeof (procfd) + sizeof (int) * 3 + filelen;
|
||||
buf = alloca (buflen);
|
||||
|
||||
__snprintf (buf, buflen, procfd, fd, file);
|
||||
file = buf;
|
||||
}
|
||||
|
||||
int result;
|
||||
INTERNAL_SYSCALL_DECL (err);
|
||||
|
||||
# ifdef __NR_laccess
|
||||
if (flag & AT_SYMLINK_NOFOLLOW)
|
||||
result = INTERNAL_SYSCALL (laccess, err, 2, file, mode);
|
||||
else
|
||||
# endif
|
||||
result = INTERNAL_SYSCALL (access, err, 2, file, mode);
|
||||
|
||||
if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (result, err)))
|
||||
{
|
||||
__atfct_seterrno (INTERNAL_SYSCALL_ERRNO (result, err), fd, buf);
|
||||
result = -1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
if ((flag == 0 || ((flag & ~AT_EACCESS) == 0 && ! __libc_enable_secure)))
|
||||
return INLINE_SYSCALL (faccessat, 3, fd, file, mode);
|
||||
|
||||
struct stat64 stats;
|
||||
if (__fxstatat64 (_STAT_VER, fd, file, &stats, flag & AT_SYMLINK_NOFOLLOW))
|
||||
|
@ -24,7 +24,6 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <alloca.h>
|
||||
#include <kernel-features.h>
|
||||
#include <sysdep.h>
|
||||
|
||||
int
|
||||
@ -47,65 +46,5 @@ fchmodat (fd, file, mode, flag)
|
||||
}
|
||||
#endif
|
||||
|
||||
int result;
|
||||
|
||||
#ifdef __NR_fchmodat
|
||||
# ifndef __ASSUME_ATFCTS
|
||||
if (__have_atfcts >= 0)
|
||||
# endif
|
||||
{
|
||||
result = INLINE_SYSCALL (fchmodat, 3, fd, file, mode);
|
||||
# ifndef __ASSUME_ATFCTS
|
||||
if (result == -1 && errno == ENOSYS)
|
||||
__have_atfcts = -1;
|
||||
else
|
||||
# endif
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __ASSUME_ATFCTS
|
||||
char *buf = NULL;
|
||||
|
||||
if (fd != AT_FDCWD && file[0] != '/')
|
||||
{
|
||||
size_t filelen = strlen (file);
|
||||
if (__glibc_unlikely (filelen == 0))
|
||||
{
|
||||
__set_errno (ENOENT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static const char procfd[] = "/proc/self/fd/%d/%s";
|
||||
/* Buffer for the path name we are going to use. It consists of
|
||||
- the string /proc/self/fd/
|
||||
- the file descriptor number
|
||||
- the file name provided.
|
||||
The final NUL is included in the sizeof. A bit of overhead
|
||||
due to the format elements compensates for possible negative
|
||||
numbers. */
|
||||
size_t buflen = sizeof (procfd) + sizeof (int) * 3 + filelen;
|
||||
buf = alloca (buflen);
|
||||
|
||||
__snprintf (buf, buflen, procfd, fd, file);
|
||||
file = buf;
|
||||
}
|
||||
|
||||
INTERNAL_SYSCALL_DECL (err);
|
||||
|
||||
# ifdef __NR_lchmod
|
||||
if (flag & AT_SYMLINK_NOFOLLOW)
|
||||
result = INTERNAL_SYSCALL (lchmod, err, 2, file, mode);
|
||||
else
|
||||
# endif
|
||||
result = INTERNAL_SYSCALL (chmod, err, 2, file, mode);
|
||||
|
||||
if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (result, err)))
|
||||
{
|
||||
__atfct_seterrno (INTERNAL_SYSCALL_ERRNO (result, err), fd, buf);
|
||||
result = -1;
|
||||
}
|
||||
|
||||
return result;
|
||||
#endif
|
||||
return INLINE_SYSCALL (fchmodat, 3, fd, file, mode);
|
||||
}
|
||||
|
@ -24,9 +24,10 @@
|
||||
#include <sys/types.h>
|
||||
#include <alloca.h>
|
||||
#include <sysdep.h>
|
||||
#include <kernel-features.h>
|
||||
|
||||
|
||||
/* Consider moving to syscalls.list. */
|
||||
|
||||
/* Change the owner and group of FILE. */
|
||||
int
|
||||
fchownat (fd, file, owner, group, flag)
|
||||
@ -36,69 +37,5 @@ fchownat (fd, file, owner, group, flag)
|
||||
gid_t group;
|
||||
int flag;
|
||||
{
|
||||
int result;
|
||||
|
||||
#ifdef __NR_fchownat
|
||||
# ifndef __ASSUME_ATFCTS
|
||||
if (__have_atfcts >= 0)
|
||||
# endif
|
||||
{
|
||||
result = INLINE_SYSCALL (fchownat, 5, fd, file, owner, group, flag);
|
||||
# ifndef __ASSUME_ATFCTS
|
||||
if (result == -1 && errno == ENOSYS)
|
||||
__have_atfcts = -1;
|
||||
else
|
||||
# endif
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __ASSUME_ATFCTS
|
||||
if (flag & ~AT_SYMLINK_NOFOLLOW)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
char *buf = NULL;
|
||||
|
||||
if (fd != AT_FDCWD && file[0] != '/')
|
||||
{
|
||||
size_t filelen = strlen (file);
|
||||
if (__glibc_unlikely (filelen == 0))
|
||||
{
|
||||
__set_errno (ENOENT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static const char procfd[] = "/proc/self/fd/%d/%s";
|
||||
/* Buffer for the path name we are going to use. It consists of
|
||||
- the string /proc/self/fd/
|
||||
- the file descriptor number
|
||||
- the file name provided.
|
||||
The final NUL is included in the sizeof. A bit of overhead
|
||||
due to the format elements compensates for possible negative
|
||||
numbers. */
|
||||
size_t buflen = sizeof (procfd) + sizeof (int) * 3 + filelen;
|
||||
buf = alloca (buflen);
|
||||
|
||||
__snprintf (buf, buflen, procfd, fd, file);
|
||||
file = buf;
|
||||
}
|
||||
|
||||
INTERNAL_SYSCALL_DECL (err);
|
||||
|
||||
if (flag & AT_SYMLINK_NOFOLLOW)
|
||||
result = INTERNAL_SYSCALL (lchown, err, 3, file, owner, group);
|
||||
else
|
||||
result = INTERNAL_SYSCALL (chown, err, 3, file, owner, group);
|
||||
|
||||
if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (result, err)))
|
||||
{
|
||||
__atfct_seterrno (INTERNAL_SYSCALL_ERRNO (result, err), fd, buf);
|
||||
result = -1;
|
||||
}
|
||||
|
||||
return result;
|
||||
#endif
|
||||
return INLINE_SYSCALL (fchownat, 5, fd, file, owner, group, flag);
|
||||
}
|
||||
|
@ -23,7 +23,6 @@
|
||||
#include <utime.h>
|
||||
#include <sys/time.h>
|
||||
#include <sysdep.h>
|
||||
#include <kernel-features.h>
|
||||
|
||||
|
||||
/* Change the access time of FILE relative to FD to TVP[0] and
|
||||
@ -34,106 +33,8 @@ futimesat (fd, file, tvp)
|
||||
const char *file;
|
||||
const struct timeval tvp[2];
|
||||
{
|
||||
int result;
|
||||
|
||||
#ifdef __NR_futimesat
|
||||
# ifndef __ASSUME_ATFCTS
|
||||
if (__have_atfcts >= 0)
|
||||
# endif
|
||||
{
|
||||
if (file == NULL)
|
||||
return __futimes (fd, tvp);
|
||||
|
||||
result = INLINE_SYSCALL (futimesat, 3, fd, file, tvp);
|
||||
# ifndef __ASSUME_ATFCTS
|
||||
if (result == -1 && errno == ENOSYS)
|
||||
__have_atfcts = -1;
|
||||
else
|
||||
# endif
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __ASSUME_ATFCTS
|
||||
char *buf = NULL;
|
||||
|
||||
if (file == NULL)
|
||||
{
|
||||
static const char procfd[] = "/proc/self/fd/%d";
|
||||
/* Buffer for the path name we are going to use. It consists of
|
||||
- the string /proc/self/fd/
|
||||
- the file descriptor number.
|
||||
The final NUL is included in the sizeof. A bit of overhead
|
||||
due to the format elements compensates for possible negative
|
||||
numbers. */
|
||||
size_t buflen = sizeof (procfd) + sizeof (int) * 3;
|
||||
buf = alloca (buflen);
|
||||
return __futimes (fd, tvp);
|
||||
|
||||
__snprintf (buf, buflen, procfd, fd);
|
||||
file = buf;
|
||||
}
|
||||
else if (fd != AT_FDCWD && file[0] != '/')
|
||||
{
|
||||
size_t filelen = strlen (file);
|
||||
if (__glibc_unlikely (filelen == 0))
|
||||
{
|
||||
__set_errno (ENOENT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static const char procfd[] = "/proc/self/fd/%d/%s";
|
||||
/* Buffer for the path name we are going to use. It consists of
|
||||
- the string /proc/self/fd/
|
||||
- the file descriptor number
|
||||
- the file name provided.
|
||||
The final NUL is included in the sizeof. A bit of overhead
|
||||
due to the format elements compensates for possible negative
|
||||
numbers. */
|
||||
size_t buflen = sizeof (procfd) + sizeof (int) * 3 + filelen;
|
||||
buf = alloca (buflen);
|
||||
|
||||
__snprintf (buf, buflen, procfd, fd, file);
|
||||
file = buf;
|
||||
}
|
||||
|
||||
INTERNAL_SYSCALL_DECL (err);
|
||||
|
||||
# ifdef __NR_utimes
|
||||
result = INTERNAL_SYSCALL (utimes, err, 2, file, tvp);
|
||||
if (__glibc_likely (!INTERNAL_SYSCALL_ERROR_P (result, err)))
|
||||
return result;
|
||||
|
||||
# ifndef __ASSUME_UTIMES
|
||||
if (INTERNAL_SYSCALL_ERRNO (result, err) != ENOSYS)
|
||||
goto fail;
|
||||
# endif
|
||||
# endif
|
||||
|
||||
/* The utimes() syscall does not exist or is not available in the
|
||||
used kernel. Use utime(). For this we have to convert to the
|
||||
data format utime() expects. */
|
||||
# ifndef __ASSUME_UTIMES
|
||||
struct utimbuf tmp;
|
||||
struct utimbuf *times;
|
||||
|
||||
if (tvp != NULL)
|
||||
{
|
||||
times = &tmp;
|
||||
tmp.actime = tvp[0].tv_sec + tvp[0].tv_usec / 1000000;
|
||||
tmp.modtime = tvp[1].tv_sec + tvp[1].tv_usec / 1000000;
|
||||
}
|
||||
else
|
||||
times = NULL;
|
||||
|
||||
result = INTERNAL_SYSCALL (utime, err, 2, file, times);
|
||||
if (__glibc_likely (!INTERNAL_SYSCALL_ERROR_P (result, err)))
|
||||
return result;
|
||||
|
||||
fail:
|
||||
# endif
|
||||
|
||||
__atfct_seterrno (INTERNAL_SYSCALL_ERRNO (result, err), fd, buf);
|
||||
|
||||
return -1;
|
||||
#endif
|
||||
return INLINE_SYSCALL (futimesat, 3, fd, file, tvp);
|
||||
}
|
||||
|
@ -29,7 +29,6 @@
|
||||
|
||||
#include <sysdep.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <kernel-features.h>
|
||||
|
||||
#include <xstatconv.h>
|
||||
|
||||
@ -45,97 +44,20 @@ __fxstatat (int vers, int fd, const char *file, struct stat *st, int flag)
|
||||
struct kernel_stat kst;
|
||||
#endif
|
||||
|
||||
#ifdef __NR_newfstatat
|
||||
# ifndef __ASSUME_ATFCTS
|
||||
if (__have_atfcts >= 0)
|
||||
# endif
|
||||
result = INTERNAL_SYSCALL (newfstatat, err, 4, fd, file, &kst, flag);
|
||||
if (!__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 1))
|
||||
{
|
||||
result = INTERNAL_SYSCALL (newfstatat, err, 4, fd, file, &kst, flag);
|
||||
# ifndef __ASSUME_ATFCTS
|
||||
if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 1)
|
||||
&& INTERNAL_SYSCALL_ERRNO (result, err) == ENOSYS)
|
||||
__have_atfcts = -1;
|
||||
else
|
||||
# endif
|
||||
if (!__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 1))
|
||||
{
|
||||
#ifdef STAT_IS_KERNEL_STAT
|
||||
return 0;
|
||||
return 0;
|
||||
#else
|
||||
return __xstat_conv (vers, &kst, st);
|
||||
return __xstat_conv (vers, &kst, st);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
__set_errno (INTERNAL_SYSCALL_ERRNO (result, err));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (flag & ~AT_SYMLINK_NOFOLLOW)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
char *buf = NULL;
|
||||
|
||||
if (fd != AT_FDCWD && file[0] != '/')
|
||||
{
|
||||
size_t filelen = strlen (file);
|
||||
if (__glibc_unlikely (filelen == 0))
|
||||
{
|
||||
__set_errno (ENOENT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static const char procfd[] = "/proc/self/fd/%d/%s";
|
||||
/* Buffer for the path name we are going to use. It consists of
|
||||
- the string /proc/self/fd/
|
||||
- the file descriptor number
|
||||
- the file name provided.
|
||||
The final NUL is included in the sizeof. A bit of overhead
|
||||
due to the format elements compensates for possible negative
|
||||
numbers. */
|
||||
size_t buflen = sizeof (procfd) + sizeof (int) * 3 + filelen;
|
||||
buf = alloca (buflen);
|
||||
|
||||
__snprintf (buf, buflen, procfd, fd, file);
|
||||
file = buf;
|
||||
}
|
||||
|
||||
if (vers == _STAT_VER_KERNEL)
|
||||
{
|
||||
if (flag & AT_SYMLINK_NOFOLLOW)
|
||||
result = INTERNAL_SYSCALL (lstat, err, 2, file,
|
||||
(struct kernel_stat *) st);
|
||||
else
|
||||
result = INTERNAL_SYSCALL (stat, err, 2, file,
|
||||
(struct kernel_stat *) st);
|
||||
|
||||
if (__glibc_likely (!INTERNAL_SYSCALL_ERROR_P (result, err)))
|
||||
return result;
|
||||
}
|
||||
#ifdef STAT_IS_KERNEL_STAT
|
||||
else
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
__set_errno (INTERNAL_SYSCALL_ERRNO (result, err));
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
if (flag & AT_SYMLINK_NOFOLLOW)
|
||||
result = INTERNAL_SYSCALL (lstat, err, 2, file, &kst);
|
||||
else
|
||||
result = INTERNAL_SYSCALL (stat, err, 2, file, &kst);
|
||||
|
||||
if (__glibc_likely (!INTERNAL_SYSCALL_ERROR_P (result, err)))
|
||||
return __xstat_conv (vers, &kst, st);
|
||||
#endif
|
||||
|
||||
__atfct_seterrno (INTERNAL_SYSCALL_ERRNO (result, err), fd, buf);
|
||||
|
||||
return -1;
|
||||
}
|
||||
libc_hidden_def (__fxstatat)
|
||||
#ifdef XSTAT_IS_XSTAT64
|
||||
|
@ -26,8 +26,6 @@
|
||||
#include <sysdep.h>
|
||||
#include <sys/syscall.h>
|
||||
|
||||
#include <kernel-features.h>
|
||||
|
||||
/* Get information about the file NAME in BUF. */
|
||||
|
||||
int
|
||||
@ -42,76 +40,13 @@ __fxstatat64 (int vers, int fd, const char *file, struct stat64 *st, int flag)
|
||||
int result;
|
||||
INTERNAL_SYSCALL_DECL (err);
|
||||
|
||||
#ifdef __NR_fstatat64
|
||||
# ifndef __ASSUME_ATFCTS
|
||||
if (__have_atfcts >= 0)
|
||||
# endif
|
||||
result = INTERNAL_SYSCALL (fstatat64, err, 4, fd, file, st, flag);
|
||||
if (!__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 1))
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
result = INTERNAL_SYSCALL (fstatat64, err, 4, fd, file, st, flag);
|
||||
# ifndef __ASSUME_ATFCTS
|
||||
if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 1)
|
||||
&& INTERNAL_SYSCALL_ERRNO (result, err) == ENOSYS)
|
||||
__have_atfcts = -1;
|
||||
else
|
||||
# endif
|
||||
if (!__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 1))
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
__set_errno (INTERNAL_SYSCALL_ERRNO (result, err));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __ASSUME_ATFCTS
|
||||
if (flag & ~AT_SYMLINK_NOFOLLOW)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
__set_errno (INTERNAL_SYSCALL_ERRNO (result, err));
|
||||
return -1;
|
||||
}
|
||||
|
||||
char *buf = NULL;
|
||||
|
||||
if (fd != AT_FDCWD && file[0] != '/')
|
||||
{
|
||||
size_t filelen = strlen (file);
|
||||
if (__glibc_unlikely (filelen == 0))
|
||||
{
|
||||
__set_errno (ENOENT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static const char procfd[] = "/proc/self/fd/%d/%s";
|
||||
/* Buffer for the path name we are going to use. It consists of
|
||||
- the string /proc/self/fd/
|
||||
- the file descriptor number
|
||||
- the file name provided.
|
||||
The final NUL is included in the sizeof. A bit of overhead
|
||||
due to the format elements compensates for possible negative
|
||||
numbers. */
|
||||
size_t buflen = sizeof (procfd) + sizeof (int) * 3 + filelen;
|
||||
buf = alloca (buflen);
|
||||
|
||||
__snprintf (buf, buflen, procfd, fd, file);
|
||||
file = buf;
|
||||
}
|
||||
|
||||
if (flag & AT_SYMLINK_NOFOLLOW)
|
||||
result = INTERNAL_SYSCALL (lstat64, err, 2, file, st);
|
||||
else
|
||||
result = INTERNAL_SYSCALL (stat64, err, 2, file, st);
|
||||
if (__glibc_likely (!INTERNAL_SYSCALL_ERROR_P (result, err)))
|
||||
{
|
||||
# if defined _HAVE_STAT64___ST_INO && __ASSUME_ST_INO_64_BIT == 0
|
||||
if (st->__st_ino != (__ino_t) st->st_ino)
|
||||
st->st_ino = st->__st_ino;
|
||||
# endif
|
||||
return result;
|
||||
}
|
||||
__atfct_seterrno (INTERNAL_SYSCALL_ERRNO (result, err), fd, buf);
|
||||
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
libc_hidden_def (__fxstatat64)
|
||||
|
@ -1,101 +0,0 @@
|
||||
/* Copyright (C) 2005-2014 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <sysdep.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <shlib-compat.h>
|
||||
|
||||
#include <linux/posix_types.h>
|
||||
#include <kernel-features.h>
|
||||
|
||||
|
||||
int
|
||||
fchownat (int fd, const char *file, uid_t owner, gid_t group, int flag)
|
||||
{
|
||||
int result;
|
||||
|
||||
#ifdef __NR_fchownat
|
||||
# ifndef __ASSUME_ATFCTS
|
||||
if (__have_atfcts >= 0)
|
||||
# endif
|
||||
{
|
||||
result = INLINE_SYSCALL (fchownat, 5, fd, file, owner, group, flag);
|
||||
# ifndef __ASSUME_ATFCTS
|
||||
if (result == -1 && errno == ENOSYS)
|
||||
__have_atfcts = -1;
|
||||
else
|
||||
# endif
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __ASSUME_ATFCTS
|
||||
if (flag & ~AT_SYMLINK_NOFOLLOW)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
char *buf = NULL;
|
||||
|
||||
if (fd != AT_FDCWD && file[0] != '/')
|
||||
{
|
||||
size_t filelen = strlen (file);
|
||||
if (__glibc_unlikely (filelen == 0))
|
||||
{
|
||||
__set_errno (ENOENT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static const char procfd[] = "/proc/self/fd/%d/%s";
|
||||
/* Buffer for the path name we are going to use. It consists of
|
||||
- the string /proc/self/fd/
|
||||
- the file descriptor number
|
||||
- the file name provided.
|
||||
The final NUL is included in the sizeof. A bit of overhead
|
||||
due to the format elements compensates for possible negative
|
||||
numbers. */
|
||||
size_t buflen = sizeof (procfd) + sizeof (int) * 3 + filelen;
|
||||
buf = alloca (buflen);
|
||||
|
||||
__snprintf (buf, buflen, procfd, fd, file);
|
||||
file = buf;
|
||||
}
|
||||
|
||||
INTERNAL_SYSCALL_DECL (err);
|
||||
|
||||
if (flag & AT_SYMLINK_NOFOLLOW)
|
||||
result = INTERNAL_SYSCALL (lchown32, err, 3, file, owner, group);
|
||||
else
|
||||
result = INTERNAL_SYSCALL (chown32, err, 3, file, owner, group);
|
||||
|
||||
if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (result, err)))
|
||||
{
|
||||
__atfct_seterrno (INTERNAL_SYSCALL_ERRNO (result, err), fd, buf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
#endif
|
||||
}
|
@ -30,8 +30,6 @@
|
||||
#include <sysdep.h>
|
||||
#include <sys/syscall.h>
|
||||
|
||||
#include <kernel-features.h>
|
||||
|
||||
#include <xstatconv.h>
|
||||
|
||||
|
||||
@ -43,88 +41,14 @@ __fxstatat (int vers, int fd, const char *file, struct stat *st, int flag)
|
||||
INTERNAL_SYSCALL_DECL (err);
|
||||
struct stat64 st64;
|
||||
|
||||
#ifdef __NR_fstatat64
|
||||
# ifndef __ASSUME_ATFCTS
|
||||
if (__have_atfcts >= 0)
|
||||
# endif
|
||||
result = INTERNAL_SYSCALL (fstatat64, err, 4, fd, file, &st64, flag);
|
||||
if (!__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 1))
|
||||
return __xstat32_conv (vers, &st64, st);
|
||||
else
|
||||
{
|
||||
result = INTERNAL_SYSCALL (fstatat64, err, 4, fd, file, &st64, flag);
|
||||
# ifndef __ASSUME_ATFCTS
|
||||
if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 1)
|
||||
&& INTERNAL_SYSCALL_ERRNO (result, err) == ENOSYS)
|
||||
__have_atfcts = -1;
|
||||
else
|
||||
# endif
|
||||
if (!__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 1))
|
||||
return __xstat32_conv (vers, &st64, st);
|
||||
else
|
||||
{
|
||||
__set_errno (INTERNAL_SYSCALL_ERRNO (result, err));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __ASSUME_ATFCTS
|
||||
if (__glibc_unlikely (flag & ~AT_SYMLINK_NOFOLLOW))
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
__set_errno (INTERNAL_SYSCALL_ERRNO (result, err));
|
||||
return -1;
|
||||
}
|
||||
|
||||
char *buf = NULL;
|
||||
|
||||
if (fd != AT_FDCWD && file[0] != '/')
|
||||
{
|
||||
size_t filelen = strlen (file);
|
||||
if (__glibc_unlikely (filelen == 0))
|
||||
{
|
||||
__set_errno (ENOENT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static const char procfd[] = "/proc/self/fd/%d/%s";
|
||||
/* Buffer for the path name we are going to use. It consists of
|
||||
- the string /proc/self/fd/
|
||||
- the file descriptor number
|
||||
- the file name provided.
|
||||
The final NUL is included in the sizeof. A bit of overhead
|
||||
due to the format elements compensates for possible negative
|
||||
numbers. */
|
||||
size_t buflen = sizeof (procfd) + sizeof (int) * 3 + filelen;
|
||||
buf = alloca (buflen);
|
||||
|
||||
__snprintf (buf, buflen, procfd, fd, file);
|
||||
file = buf;
|
||||
}
|
||||
|
||||
if (vers == _STAT_VER_KERNEL)
|
||||
{
|
||||
if (flag & AT_SYMLINK_NOFOLLOW)
|
||||
result = INTERNAL_SYSCALL (lstat, err, 2, file,
|
||||
(struct kernel_stat *) st);
|
||||
else
|
||||
result = INTERNAL_SYSCALL (stat, err, 2, file,
|
||||
(struct kernel_stat *) st);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (flag & AT_SYMLINK_NOFOLLOW)
|
||||
result = INTERNAL_SYSCALL (lstat64, err, 2, file, &st64);
|
||||
else
|
||||
result = INTERNAL_SYSCALL (stat64, err, 2, file, &st64);
|
||||
if (__glibc_likely (!INTERNAL_SYSCALL_ERROR_P (result, err)))
|
||||
return __xstat32_conv (vers, &st64, st);
|
||||
|
||||
out:
|
||||
if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (result, err)))
|
||||
{
|
||||
__atfct_seterrno (INTERNAL_SYSCALL_ERRNO (result, err), fd, buf);
|
||||
result = -1;
|
||||
}
|
||||
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
libc_hidden_def (__fxstatat)
|
||||
#ifdef XSTAT_IS_XSTAT64
|
||||
|
@ -21,9 +21,10 @@
|
||||
#include <stdio.h>
|
||||
#include <sysdep.h>
|
||||
#include <unistd.h>
|
||||
#include <kernel-features.h>
|
||||
|
||||
|
||||
/* Consider moving to syscalls.list. */
|
||||
|
||||
/* Make a link to FROM named TO but relative paths in TO and FROM are
|
||||
interpreted relative to FROMFD and TOFD respectively. */
|
||||
int
|
||||
@ -34,87 +35,5 @@ linkat (fromfd, from, tofd, to, flags)
|
||||
const char *to;
|
||||
int flags;
|
||||
{
|
||||
int result;
|
||||
|
||||
#ifdef __NR_linkat
|
||||
# ifndef __ASSUME_ATFCTS
|
||||
if (__have_atfcts >= 0)
|
||||
# endif
|
||||
{
|
||||
result = INLINE_SYSCALL (linkat, 5, fromfd, from, tofd, to, flags);
|
||||
# ifndef __ASSUME_ATFCTS
|
||||
if (result == -1 && errno == ENOSYS)
|
||||
__have_atfcts = -1;
|
||||
else
|
||||
# endif
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __ASSUME_ATFCTS
|
||||
/* Without kernel support we cannot handle AT_SYMLINK_FOLLOW. */
|
||||
if (flags != 0)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static const char procfd[] = "/proc/self/fd/%d/%s";
|
||||
char *buffrom = NULL;
|
||||
|
||||
if (fromfd != AT_FDCWD && from[0] != '/')
|
||||
{
|
||||
size_t filelen = strlen (from);
|
||||
if (__glibc_unlikely (filelen == 0))
|
||||
{
|
||||
__set_errno (ENOENT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Buffer for the path name we are going to use. It consists of
|
||||
- the string /proc/self/fd/
|
||||
- the file descriptor number
|
||||
- the file name provided.
|
||||
The final NUL is included in the sizeof. A bit of overhead
|
||||
due to the format elements compensates for possible negative
|
||||
numbers. */
|
||||
size_t buflen = sizeof (procfd) + sizeof (int) * 3 + filelen;
|
||||
buffrom = alloca (buflen);
|
||||
|
||||
__snprintf (buffrom, buflen, procfd, fromfd, from);
|
||||
from = buffrom;
|
||||
}
|
||||
|
||||
char *bufto = NULL;
|
||||
|
||||
if (tofd != AT_FDCWD && to[0] != '/')
|
||||
{
|
||||
size_t filelen = strlen (to);
|
||||
/* Buffer for the path name we are going to use. It consists of
|
||||
- the string /proc/self/fd/
|
||||
- the file descriptor number
|
||||
- the file name provided.
|
||||
The final NUL is included in the sizeof. A bit of overhead
|
||||
due to the format elements compensates for possible negative
|
||||
numbers. */
|
||||
size_t buflen = sizeof (procfd) + sizeof (int) * 3 + filelen;
|
||||
bufto = alloca (buflen);
|
||||
|
||||
__snprintf (bufto, buflen, procfd, tofd, to);
|
||||
to = bufto;
|
||||
}
|
||||
|
||||
INTERNAL_SYSCALL_DECL (err);
|
||||
|
||||
result = INTERNAL_SYSCALL (link, err, 2, from, to);
|
||||
|
||||
if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (result, err)))
|
||||
{
|
||||
__atfct_seterrno_2 (INTERNAL_SYSCALL_ERRNO (result, err), tofd, bufto,
|
||||
fromfd, buffrom);
|
||||
result = -1;
|
||||
}
|
||||
|
||||
return result;
|
||||
#endif
|
||||
return INLINE_SYSCALL (linkat, 5, fromfd, from, tofd, to, flags);
|
||||
}
|
||||
|
@ -1 +0,0 @@
|
||||
#include <sysdeps/unix/sysv/linux/i386/fchownat.c>
|
@ -26,8 +26,6 @@
|
||||
#include <sysdep.h>
|
||||
#include <sys/syscall.h>
|
||||
|
||||
#include <kernel-features.h>
|
||||
|
||||
#include <xstatconv.h>
|
||||
|
||||
/* Get information about the file NAME in BUF. */
|
||||
@ -45,65 +43,13 @@ __fxstatat64 (int vers, int fd, const char *file, struct stat64 *st, int flag)
|
||||
INTERNAL_SYSCALL_DECL (err);
|
||||
struct kernel_stat kst;
|
||||
|
||||
#ifdef __NR_newfstatat
|
||||
# ifndef __ASSUME_ATFCTS
|
||||
if (__have_atfcts >= 0)
|
||||
# endif
|
||||
result = INTERNAL_SYSCALL (newfstatat, err, 4, fd, file, &kst, flag);
|
||||
if (!__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 1))
|
||||
return __xstat64_conv (vers, &kst, st);
|
||||
else
|
||||
{
|
||||
result = INTERNAL_SYSCALL (newfstatat, err, 4, fd, file, &kst, flag);
|
||||
# ifndef __ASSUME_ATFCTS
|
||||
if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 1)
|
||||
&& INTERNAL_SYSCALL_ERRNO (result, err) == ENOSYS)
|
||||
__have_atfcts = -1;
|
||||
else
|
||||
# endif
|
||||
if (!__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 1))
|
||||
return __xstat64_conv (vers, &kst, st);
|
||||
else
|
||||
{
|
||||
__set_errno (INTERNAL_SYSCALL_ERRNO (result, err));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __ASSUME_ATFCTS
|
||||
if (flag & ~AT_SYMLINK_NOFOLLOW)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
__set_errno (INTERNAL_SYSCALL_ERRNO (result, err));
|
||||
return -1;
|
||||
}
|
||||
|
||||
char *buf = NULL;
|
||||
|
||||
if (fd != AT_FDCWD && file[0] != '/')
|
||||
{
|
||||
size_t filelen = strlen (file);
|
||||
static const char procfd[] = "/proc/self/fd/%d/%s";
|
||||
/* Buffer for the path name we are going to use. It consists of
|
||||
- the string /proc/self/fd/
|
||||
- the file descriptor number
|
||||
- the file name provided.
|
||||
The final NUL is included in the sizeof. A bit of overhead
|
||||
due to the format elements compensates for possible negative
|
||||
numbers. */
|
||||
size_t buflen = sizeof (procfd) + sizeof (int) * 3 + filelen;
|
||||
buf = alloca (buflen);
|
||||
|
||||
__snprintf (buf, buflen, procfd, fd, file);
|
||||
file = buf;
|
||||
}
|
||||
|
||||
if (flag & AT_SYMLINK_NOFOLLOW)
|
||||
result = INTERNAL_SYSCALL (lstat, err, 2, file, &kst);
|
||||
else
|
||||
result = INTERNAL_SYSCALL (stat, err, 2, file, &kst);
|
||||
|
||||
if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
|
||||
return __xstat64_conv (vers, &kst, st);
|
||||
|
||||
__atfct_seterrno (INTERNAL_SYSCALL_ERRNO (result, err), fd, buf);
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
libc_hidden_def (__fxstatat64)
|
||||
|
@ -21,10 +21,11 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <kernel-features.h>
|
||||
#include <sysdep-cancel.h>
|
||||
|
||||
|
||||
/* Consider moving to syscalls.list. */
|
||||
|
||||
/* Create a new directory with permission bits MODE. But interpret
|
||||
relative PATH names relative to the directory associated with FD. */
|
||||
int
|
||||
@ -33,59 +34,5 @@ mkdirat (fd, file, mode)
|
||||
const char *file;
|
||||
mode_t mode;
|
||||
{
|
||||
int res;
|
||||
|
||||
#ifdef __NR_mkdirat
|
||||
# ifndef __ASSUME_ATFCTS
|
||||
if (__have_atfcts >= 0)
|
||||
# endif
|
||||
{
|
||||
res = INLINE_SYSCALL (mkdirat, 3, fd, file, mode);
|
||||
# ifndef __ASSUME_ATFCTS
|
||||
if (res == -1 && errno == ENOSYS)
|
||||
__have_atfcts = -1;
|
||||
else
|
||||
# endif
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __ASSUME_ATFCTS
|
||||
char *buf = NULL;
|
||||
|
||||
if (fd != AT_FDCWD && file[0] != '/')
|
||||
{
|
||||
size_t filelen = strlen (file);
|
||||
if (__glibc_unlikely (filelen == 0))
|
||||
{
|
||||
__set_errno (ENOENT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static const char procfd[] = "/proc/self/fd/%d/%s";
|
||||
/* Buffer for the path name we are going to use. It consists of
|
||||
- the string /proc/self/fd/
|
||||
- the file descriptor number
|
||||
- the file name provided.
|
||||
The final NUL is included in the sizeof. A bit of overhead
|
||||
due to the format elements compensates for possible negative
|
||||
numbers. */
|
||||
size_t buflen = sizeof (procfd) + sizeof (int) * 3 + filelen;
|
||||
buf = alloca (buflen);
|
||||
|
||||
__snprintf (buf, buflen, procfd, fd, file);
|
||||
file = buf;
|
||||
}
|
||||
|
||||
INTERNAL_SYSCALL_DECL (err);
|
||||
res = INTERNAL_SYSCALL (mkdir, err, 2, file, mode);
|
||||
|
||||
if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (res, err)))
|
||||
{
|
||||
__atfct_seterrno (INTERNAL_SYSCALL_ERRNO (res, err), fd, buf);
|
||||
res = -1;
|
||||
}
|
||||
|
||||
return res;
|
||||
#endif
|
||||
return INLINE_SYSCALL (mkdirat, 3, fd, file, mode);
|
||||
}
|
||||
|
@ -22,46 +22,12 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <kernel-features.h>
|
||||
#include <sysdep-cancel.h>
|
||||
#include <not-cancel.h>
|
||||
|
||||
|
||||
#ifndef OPENAT
|
||||
# define OPENAT openat
|
||||
|
||||
# ifndef __ASSUME_ATFCTS
|
||||
/* Set errno after a failed call. If BUF is not null,
|
||||
it is a /proc/self/fd/ path name we just tried to use. */
|
||||
void
|
||||
attribute_hidden
|
||||
__atfct_seterrno (int errval, int fd, const char *buf)
|
||||
{
|
||||
if (buf != NULL)
|
||||
{
|
||||
struct stat64 st;
|
||||
|
||||
if (errval == ENOTDIR || errval == ENOENT)
|
||||
{
|
||||
/* This can mean either the file descriptor is invalid or
|
||||
/proc is not mounted. */
|
||||
if (__fxstat64 (_STAT_VER, fd, &st) != 0)
|
||||
/* errno is already set correctly. */
|
||||
return;
|
||||
|
||||
/* If /proc is not mounted there is nothing we can do. */
|
||||
if ((errval != ENOTDIR || S_ISDIR (st.st_mode))
|
||||
&& (__xstat64 (_STAT_VER, "/proc/self/fd", &st) != 0
|
||||
|| !S_ISDIR (st.st_mode)))
|
||||
errval = ENOSYS;
|
||||
}
|
||||
}
|
||||
|
||||
__set_errno (errval);
|
||||
}
|
||||
|
||||
int __have_atfcts;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
@ -83,63 +49,7 @@ OPENAT_NOT_CANCEL (fd, file, oflag, mode)
|
||||
oflag |= MORE_OFLAGS;
|
||||
#endif
|
||||
|
||||
int res;
|
||||
|
||||
#ifdef __NR_openat
|
||||
# ifndef __ASSUME_ATFCTS
|
||||
if (__have_atfcts >= 0)
|
||||
# endif
|
||||
{
|
||||
res = INLINE_SYSCALL (openat, 4, fd, file, oflag, mode);
|
||||
|
||||
# ifndef __ASSUME_ATFCTS
|
||||
if (res == -1 && errno == ENOSYS)
|
||||
__have_atfcts = -1;
|
||||
else
|
||||
# endif
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __ASSUME_ATFCTS
|
||||
INTERNAL_SYSCALL_DECL (err);
|
||||
char *buf = NULL;
|
||||
|
||||
if (fd != AT_FDCWD && file[0] != '/')
|
||||
{
|
||||
size_t filelen = strlen (file);
|
||||
if (__glibc_unlikely (filelen == 0))
|
||||
{
|
||||
__set_errno (ENOENT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static const char procfd[] = "/proc/self/fd/%d/%s";
|
||||
/* Buffer for the path name we are going to use. It consists of
|
||||
- the string /proc/self/fd/
|
||||
- the file descriptor number
|
||||
- the file name provided.
|
||||
The final NUL is included in the sizeof. A bit of overhead
|
||||
due to the format elements compensates for possible negative
|
||||
numbers. */
|
||||
size_t buflen = sizeof (procfd) + sizeof (int) * 3 + filelen;
|
||||
buf = alloca (buflen);
|
||||
|
||||
/* Note: snprintf cannot be canceled. */
|
||||
__snprintf (buf, buflen, procfd, fd, file);
|
||||
file = buf;
|
||||
}
|
||||
|
||||
res = INTERNAL_SYSCALL (open, err, 3, file, oflag, mode);
|
||||
|
||||
if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (res, err)))
|
||||
{
|
||||
__atfct_seterrno (INTERNAL_SYSCALL_ERRNO (res, err), fd, buf);
|
||||
res = -1;
|
||||
}
|
||||
|
||||
return res;
|
||||
#endif
|
||||
return INLINE_SYSCALL (openat, 4, fd, file, oflag, mode);
|
||||
}
|
||||
|
||||
#define UNDERIZE(name) UNDERIZE_1 (name)
|
||||
|
@ -1,105 +0,0 @@
|
||||
/* Copyright (C) 2005-2014 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
#include <sysdep.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <kernel-features.h>
|
||||
|
||||
/*
|
||||
In Linux 2.1.x the chown functions have been changed. A new function lchown
|
||||
was introduced. The new chown now follows symlinks - the old chown and the
|
||||
new lchown do not follow symlinks.
|
||||
This file emulates chown() under the old kernels.
|
||||
*/
|
||||
|
||||
int
|
||||
fchownat (int fd, const char *file, uid_t owner, gid_t group, int flag)
|
||||
{
|
||||
int result;
|
||||
|
||||
#ifdef __NR_fchownat
|
||||
# ifndef __ASSUME_ATFCTS
|
||||
if (__have_atfcts >= 0)
|
||||
# endif
|
||||
{
|
||||
result = INLINE_SYSCALL (fchownat, 5, fd, file, owner, group, flag);
|
||||
# ifndef __ASSUME_ATFCTS
|
||||
if (result == -1 && errno == ENOSYS)
|
||||
__have_atfcts = -1;
|
||||
else
|
||||
# endif
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __ASSUME_ATFCTS
|
||||
if (flag & ~AT_SYMLINK_NOFOLLOW)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
char *buf = NULL;
|
||||
|
||||
if (fd != AT_FDCWD && file[0] != '/')
|
||||
{
|
||||
size_t filelen = strlen (file);
|
||||
if (__glibc_unlikely (filelen == 0))
|
||||
{
|
||||
__set_errno (ENOENT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static const char procfd[] = "/proc/self/fd/%d/%s";
|
||||
/* Buffer for the path name we are going to use. It consists of
|
||||
- the string /proc/self/fd/
|
||||
- the file descriptor number
|
||||
- the file name provided.
|
||||
The final NUL is included in the sizeof. A bit of overhead
|
||||
due to the format elements compensates for possible negative
|
||||
numbers. */
|
||||
size_t buflen = sizeof (procfd) + sizeof (int) * 3 + filelen;
|
||||
buf = alloca (buflen);
|
||||
|
||||
__snprintf (buf, buflen, procfd, fd, file);
|
||||
file = buf;
|
||||
}
|
||||
|
||||
INTERNAL_SYSCALL_DECL (err);
|
||||
|
||||
if (flag & AT_SYMLINK_NOFOLLOW)
|
||||
result = INTERNAL_SYSCALL (lchown, err, 3, file, owner, group);
|
||||
else
|
||||
result = INTERNAL_SYSCALL (chown, err, 3, file, owner, group);
|
||||
|
||||
if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (result, err)))
|
||||
{
|
||||
__atfct_seterrno (INTERNAL_SYSCALL_ERRNO (result, err), fd, buf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
#endif
|
||||
}
|
@ -23,9 +23,10 @@
|
||||
#include <string.h>
|
||||
#include <sysdep.h>
|
||||
#include <unistd.h>
|
||||
#include <kernel-features.h>
|
||||
|
||||
|
||||
/* Consider moving to syscalls.list. */
|
||||
|
||||
/* Read the contents of the symbolic link PATH relative to FD into no
|
||||
more than LEN bytes of BUF. */
|
||||
ssize_t
|
||||
@ -35,61 +36,6 @@ readlinkat (fd, path, buf, len)
|
||||
char *buf;
|
||||
size_t len;
|
||||
{
|
||||
int result;
|
||||
|
||||
#ifdef __NR_readlinkat
|
||||
# ifndef __ASSUME_ATFCTS
|
||||
if (__have_atfcts >= 0)
|
||||
# endif
|
||||
{
|
||||
result = INLINE_SYSCALL (readlinkat, 4, fd, path, buf, len);
|
||||
# ifndef __ASSUME_ATFCTS
|
||||
if (result == -1 && errno == ENOSYS)
|
||||
__have_atfcts = -1;
|
||||
else
|
||||
# endif
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __ASSUME_ATFCTS
|
||||
char *pathbuf = NULL;
|
||||
|
||||
if (fd != AT_FDCWD && path[0] != '/')
|
||||
{
|
||||
size_t pathlen = strlen (path);
|
||||
if (__glibc_unlikely (pathlen == 0))
|
||||
{
|
||||
__set_errno (ENOENT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static const char procfd[] = "/proc/self/fd/%d/%s";
|
||||
/* Buffer for the path name we are going to use. It consists of
|
||||
- the string /proc/self/fd/
|
||||
- the file descriptor number
|
||||
- the file name provided.
|
||||
The final NUL is included in the sizeof. A bit of overhead
|
||||
due to the format elements compensates for possible negative
|
||||
numbers. */
|
||||
size_t buflen = sizeof (procfd) + sizeof (int) * 3 + pathlen;
|
||||
pathbuf = __alloca (buflen);
|
||||
|
||||
__snprintf (pathbuf, buflen, procfd, fd, path);
|
||||
path = pathbuf;
|
||||
}
|
||||
|
||||
INTERNAL_SYSCALL_DECL (err);
|
||||
|
||||
result = INTERNAL_SYSCALL (readlink, err, 3, path, buf, len);
|
||||
|
||||
if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (result, err)))
|
||||
{
|
||||
__atfct_seterrno (INTERNAL_SYSCALL_ERRNO (result, err), fd, pathbuf);
|
||||
result = -1;
|
||||
}
|
||||
|
||||
return result;
|
||||
#endif
|
||||
return INLINE_SYSCALL (readlinkat, 4, fd, path, buf, len);
|
||||
}
|
||||
libc_hidden_def (readlinkat)
|
||||
|
@ -19,88 +19,10 @@
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <kernel-features.h>
|
||||
#include <sysdep.h>
|
||||
|
||||
|
||||
#ifndef __ASSUME_ATFCTS
|
||||
void
|
||||
attribute_hidden
|
||||
__atfct_seterrno_2 (int errval, int fd1, const char *buf1, int fd2,
|
||||
const char *buf2)
|
||||
{
|
||||
if (buf1 != NULL || buf2 != NULL)
|
||||
{
|
||||
struct stat64 st;
|
||||
|
||||
if (errval == ENOTDIR)
|
||||
{
|
||||
/* This can mean either the file descriptor is invalid or
|
||||
/proc is not mounted. */
|
||||
if (buf1 != NULL)
|
||||
{
|
||||
if (__fxstat64 (_STAT_VER, fd1, &st) != 0)
|
||||
/* errno is already set correctly. */
|
||||
return;
|
||||
|
||||
/* If /proc is not mounted there is nothing we can do. */
|
||||
if (S_ISDIR (st.st_mode)
|
||||
&& (__xstat64 (_STAT_VER, "/proc/self/fd", &st) != 0
|
||||
|| !S_ISDIR (st.st_mode)))
|
||||
{
|
||||
errval = ENOSYS;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (buf2 != NULL)
|
||||
{
|
||||
if (__fxstat64 (_STAT_VER, fd2, &st) != 0)
|
||||
/* errno is already set correctly. */
|
||||
return;
|
||||
|
||||
/* If /proc is not mounted there is nothing we can do. */
|
||||
if (S_ISDIR (st.st_mode)
|
||||
&& (__xstat64 (_STAT_VER, "/proc/self/fd", &st) != 0
|
||||
|| !S_ISDIR (st.st_mode)))
|
||||
errval = ENOSYS;
|
||||
}
|
||||
}
|
||||
else if (errval == ENOENT)
|
||||
{
|
||||
/* This could mean the file descriptor is not valid. We
|
||||
reuse BUF for the stat call. Find the slash after the
|
||||
file descriptor number. */
|
||||
if (buf1 != NULL)
|
||||
{
|
||||
*(char *) strchr (buf1 + sizeof "/proc/self/fd", '/') = '\0';
|
||||
|
||||
int e = __lxstat64 (_STAT_VER, buf1, &st);
|
||||
if ((e == -1 && errno == ENOENT)
|
||||
||(e == 0 && !S_ISLNK (st.st_mode)))
|
||||
{
|
||||
errval = EBADF;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (buf2 != NULL)
|
||||
{
|
||||
*(char *) strchr (buf2 + sizeof "/proc/self/fd", '/') = '\0';
|
||||
|
||||
int e = __lxstat64 (_STAT_VER, buf2, &st);
|
||||
if ((e == -1 && errno == ENOENT)
|
||||
||(e == 0 && !S_ISLNK (st.st_mode)))
|
||||
errval = EBADF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
__set_errno (errval);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Consider moving to syscalls.list. */
|
||||
|
||||
/* Rename the file OLD relative to OLDFD to NEW relative to NEWFD. */
|
||||
int
|
||||
@ -110,86 +32,5 @@ renameat (oldfd, old, newfd, new)
|
||||
int newfd;
|
||||
const char *new;
|
||||
{
|
||||
int result;
|
||||
|
||||
#ifdef __NR_renameat
|
||||
# ifndef __ASSUME_ATFCTS
|
||||
if (__have_atfcts >= 0)
|
||||
# endif
|
||||
{
|
||||
result = INLINE_SYSCALL (renameat, 4, oldfd, old, newfd, new);
|
||||
# ifndef __ASSUME_ATFCTS
|
||||
if (result == -1 && errno == ENOSYS)
|
||||
__have_atfcts = -1;
|
||||
else
|
||||
# endif
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __ASSUME_ATFCTS
|
||||
static const char procfd[] = "/proc/self/fd/%d/%s";
|
||||
char *bufold = NULL;
|
||||
|
||||
if (oldfd != AT_FDCWD && old[0] != '/')
|
||||
{
|
||||
size_t filelen = strlen (old);
|
||||
if (__glibc_unlikely (filelen == 0))
|
||||
{
|
||||
__set_errno (ENOENT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Buffer for the path name we are going to use. It consists of
|
||||
- the string /proc/self/fd/
|
||||
- the file descriptor number
|
||||
- the file name provided.
|
||||
The final NUL is included in the sizeof. A bit of overhead
|
||||
due to the format elements compensates for possible negative
|
||||
numbers. */
|
||||
size_t buflen = sizeof (procfd) + sizeof (int) * 3 + filelen;
|
||||
bufold = alloca (buflen);
|
||||
|
||||
__snprintf (bufold, buflen, procfd, oldfd, old);
|
||||
old = bufold;
|
||||
}
|
||||
|
||||
char *bufnew = NULL;
|
||||
|
||||
if (newfd != AT_FDCWD && new[0] != '/')
|
||||
{
|
||||
size_t filelen = strlen (new);
|
||||
if (__glibc_unlikely (filelen == 0))
|
||||
{
|
||||
__set_errno (ENOENT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Buffer for the path name we are going to use. It consists of
|
||||
- the string /proc/self/fd/
|
||||
- the file descriptor number
|
||||
- the file name provided.
|
||||
The final NUL is included in the sizeof. A bit of overhead
|
||||
due to the format elements compensates for possible negative
|
||||
numbers. */
|
||||
size_t buflen = sizeof (procfd) + sizeof (int) * 3 + filelen;
|
||||
bufnew = alloca (buflen);
|
||||
|
||||
__snprintf (bufnew, buflen, procfd, newfd, new);
|
||||
new = bufnew;
|
||||
}
|
||||
|
||||
INTERNAL_SYSCALL_DECL (err);
|
||||
|
||||
result = INTERNAL_SYSCALL (rename, err, 2, old, new);
|
||||
|
||||
if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (result, err)))
|
||||
{
|
||||
__atfct_seterrno_2 (INTERNAL_SYSCALL_ERRNO (result, err), newfd, bufnew,
|
||||
oldfd, bufold);
|
||||
result = -1;
|
||||
}
|
||||
|
||||
return result;
|
||||
#endif
|
||||
return INLINE_SYSCALL (renameat, 4, oldfd, old, newfd, new);
|
||||
}
|
||||
|
@ -1 +0,0 @@
|
||||
#include <sysdeps/unix/sysv/linux/i386/fchownat.c>
|
@ -1 +0,0 @@
|
||||
#include <sysdeps/unix/sysv/linux/i386/fchownat.c>
|
@ -1 +0,0 @@
|
||||
#include <sysdeps/unix/sysv/linux/i386/fchownat.c>
|
@ -1,6 +1 @@
|
||||
/* In this implementation we do not really care whether the call fails
|
||||
because of missing kernel support since we do not even call the
|
||||
function in this case. */
|
||||
#undef __ASSUME_ATFCTS
|
||||
#define __ASSUME_ATFCTS 1
|
||||
#include "fxstatat.c"
|
||||
|
@ -23,9 +23,10 @@
|
||||
#include <string.h>
|
||||
#include <sysdep.h>
|
||||
#include <unistd.h>
|
||||
#include <kernel-features.h>
|
||||
|
||||
|
||||
/* Consider moving to syscalls.list. */
|
||||
|
||||
/* Make a symbolic link to FROM named TO relative to TOFD. */
|
||||
int
|
||||
symlinkat (from, tofd, to)
|
||||
@ -33,60 +34,5 @@ symlinkat (from, tofd, to)
|
||||
int tofd;
|
||||
const char *to;
|
||||
{
|
||||
int result;
|
||||
|
||||
#ifdef __NR_symlinkat
|
||||
# ifndef __ASSUME_ATFCTS
|
||||
if (__have_atfcts >= 0)
|
||||
# endif
|
||||
{
|
||||
result = INLINE_SYSCALL (symlinkat, 3, from, tofd, to);
|
||||
# ifndef __ASSUME_ATFCTS
|
||||
if (result == -1 && errno == ENOSYS)
|
||||
__have_atfcts = -1;
|
||||
else
|
||||
# endif
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __ASSUME_ATFCTS
|
||||
char *buf = NULL;
|
||||
|
||||
if (tofd != AT_FDCWD && to[0] != '/')
|
||||
{
|
||||
size_t tolen = strlen (to);
|
||||
if (__glibc_unlikely (tolen == 0))
|
||||
{
|
||||
__set_errno (ENOENT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static const char procfd[] = "/proc/self/fd/%d/%s";
|
||||
/* Buffer for the path name we are going to use. It consists of
|
||||
- the string /proc/self/fd/
|
||||
- the file descriptor number
|
||||
- the file name provided.
|
||||
The final NUL is included in the sizeof. A bit of overhead
|
||||
due to the format elements compensates for possible negative
|
||||
numbers. */
|
||||
size_t buflen = sizeof (procfd) + sizeof (int) * 3 + tolen;
|
||||
buf = __alloca (buflen);
|
||||
|
||||
__snprintf (buf, buflen, procfd, tofd, to);
|
||||
to = buf;
|
||||
}
|
||||
|
||||
INTERNAL_SYSCALL_DECL (err);
|
||||
|
||||
result = INTERNAL_SYSCALL (symlink, err, 2, from, to);
|
||||
|
||||
if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (result, err)))
|
||||
{
|
||||
__atfct_seterrno (INTERNAL_SYSCALL_ERRNO (result, err), tofd, buf);
|
||||
result = -1;
|
||||
}
|
||||
|
||||
return result;
|
||||
#endif
|
||||
return INLINE_SYSCALL (symlinkat, 3, from, tofd, to);
|
||||
}
|
||||
|
@ -24,9 +24,10 @@
|
||||
#include <string.h>
|
||||
#include <sysdep.h>
|
||||
#include <unistd.h>
|
||||
#include <kernel-features.h>
|
||||
|
||||
|
||||
/* Consider moving to syscalls.list. */
|
||||
|
||||
/* Remove the link named NAME. */
|
||||
int
|
||||
unlinkat (fd, file, flag)
|
||||
@ -34,69 +35,5 @@ unlinkat (fd, file, flag)
|
||||
const char *file;
|
||||
int flag;
|
||||
{
|
||||
int result;
|
||||
|
||||
#ifdef __NR_unlinkat
|
||||
# ifndef __ASSUME_ATFCTS
|
||||
if (__have_atfcts >= 0)
|
||||
# endif
|
||||
{
|
||||
result = INLINE_SYSCALL (unlinkat, 3, fd, file, flag);
|
||||
# ifndef __ASSUME_ATFCTS
|
||||
if (result == -1 && errno == ENOSYS)
|
||||
__have_atfcts = -1;
|
||||
else
|
||||
# endif
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __ASSUME_ATFCTS
|
||||
if (flag & ~AT_REMOVEDIR)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
char *buf = NULL;
|
||||
|
||||
if (fd != AT_FDCWD && file[0] != '/')
|
||||
{
|
||||
size_t filelen = strlen (file);
|
||||
if (__glibc_unlikely (filelen == 0))
|
||||
{
|
||||
__set_errno (ENOENT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static const char procfd[] = "/proc/self/fd/%d/%s";
|
||||
/* Buffer for the path name we are going to use. It consists of
|
||||
- the string /proc/self/fd/
|
||||
- the file descriptor number
|
||||
- the file name provided.
|
||||
The final NUL is included in the sizeof. A bit of overhead
|
||||
due to the format elements compensates for possible negative
|
||||
numbers. */
|
||||
size_t buflen = sizeof (procfd) + sizeof (int) * 3 + filelen;
|
||||
buf = __alloca (buflen);
|
||||
|
||||
__snprintf (buf, buflen, procfd, fd, file);
|
||||
file = buf;
|
||||
}
|
||||
|
||||
INTERNAL_SYSCALL_DECL (err);
|
||||
|
||||
if (flag & AT_REMOVEDIR)
|
||||
result = INTERNAL_SYSCALL (rmdir, err, 1, file);
|
||||
else
|
||||
result = INTERNAL_SYSCALL (unlink, err, 1, file);
|
||||
|
||||
if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (result, err)))
|
||||
{
|
||||
__atfct_seterrno (INTERNAL_SYSCALL_ERRNO (result, err), fd, buf);
|
||||
result = -1;
|
||||
}
|
||||
|
||||
return result;
|
||||
#endif
|
||||
return INLINE_SYSCALL (unlinkat, 3, fd, file, flag);
|
||||
}
|
||||
|
@ -1,6 +1 @@
|
||||
/* In this implementation we do not really care whether the call fails
|
||||
because of missing kernel support since we do not even call the
|
||||
function in this case. */
|
||||
#undef __ASSUME_ATFCTS
|
||||
#define __ASSUME_ATFCTS 1
|
||||
#include "fxstatat.c"
|
||||
|
@ -27,7 +27,6 @@
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <sysdep.h>
|
||||
#include <kernel-features.h>
|
||||
#include <sys/syscall.h>
|
||||
|
||||
|
||||
@ -41,71 +40,7 @@ __fxstatat (int vers, int fd, const char *file, struct stat *st, int flag)
|
||||
return -1;
|
||||
}
|
||||
|
||||
int res;
|
||||
|
||||
#ifdef __NR_newfstatat
|
||||
# ifndef __ASSUME_ATFCTS
|
||||
if (__have_atfcts >= 0)
|
||||
# endif
|
||||
{
|
||||
res = INLINE_SYSCALL (newfstatat, 4, fd, file, st, flag);
|
||||
# ifndef __ASSUME_ATFCTS
|
||||
if (res == -1 && errno == ENOSYS)
|
||||
__have_atfcts = -1;
|
||||
else
|
||||
# endif
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __ASSUME_ATFCTS
|
||||
if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
char *buf = NULL;
|
||||
|
||||
if (fd != AT_FDCWD && file[0] != '/')
|
||||
{
|
||||
size_t filelen = strlen (file);
|
||||
if (__glibc_unlikely (filelen == 0))
|
||||
{
|
||||
__set_errno (ENOENT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static const char procfd[] = "/proc/self/fd/%d/%s";
|
||||
/* Buffer for the path name we are going to use. It consists of
|
||||
- the string /proc/self/fd/
|
||||
- the file descriptor number
|
||||
- the file name provided.
|
||||
The final NUL is included in the sizeof. A bit of overhead
|
||||
due to the format elements compensates for possible negative
|
||||
numbers. */
|
||||
size_t buflen = sizeof (procfd) + sizeof (int) * 3 + filelen;
|
||||
buf = alloca (buflen);
|
||||
|
||||
__snprintf (buf, buflen, procfd, fd, file);
|
||||
file = buf;
|
||||
}
|
||||
|
||||
INTERNAL_SYSCALL_DECL (err);
|
||||
|
||||
if (flag & AT_SYMLINK_NOFOLLOW)
|
||||
res = INTERNAL_SYSCALL (lstat, err, 2, file, st);
|
||||
else
|
||||
res = INTERNAL_SYSCALL (stat, err, 2, file, st);
|
||||
|
||||
if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (res, err)))
|
||||
{
|
||||
__atfct_seterrno (INTERNAL_SYSCALL_ERRNO (res, err), fd, buf);
|
||||
res = -1;
|
||||
}
|
||||
|
||||
return res;
|
||||
#endif
|
||||
return INLINE_SYSCALL (newfstatat, 4, fd, file, st, flag);
|
||||
}
|
||||
libc_hidden_def (__fxstatat)
|
||||
#undef __fxstatat64
|
||||
|
@ -24,7 +24,6 @@
|
||||
#include <sys/sysmacros.h>
|
||||
|
||||
#include <sysdep.h>
|
||||
#include <kernel-features.h>
|
||||
#include <sys/syscall.h>
|
||||
|
||||
|
||||
@ -48,51 +47,7 @@ __xmknodat (int vers, int fd, const char *file, mode_t mode, dev_t *dev)
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef __NR_mknodat
|
||||
# ifndef __ASSUME_ATFCTS
|
||||
if (__have_atfcts >= 0)
|
||||
# endif
|
||||
{
|
||||
int res = INLINE_SYSCALL (mknodat, 4, fd, file, mode,
|
||||
(unsigned int) k_dev);
|
||||
# ifndef __ASSUME_ATFCTS
|
||||
if (res == -1 && errno == ENOSYS)
|
||||
__have_atfcts = -1;
|
||||
else
|
||||
# endif
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __ASSUME_ATFCTS
|
||||
char *buf = NULL;
|
||||
|
||||
if (fd != AT_FDCWD && file[0] != '/')
|
||||
{
|
||||
size_t filelen = strlen (file);
|
||||
if (__glibc_unlikely (filelen == 0))
|
||||
{
|
||||
__set_errno (ENOENT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static const char procfd[] = "/proc/self/fd/%d/%s";
|
||||
/* Buffer for the path name we are going to use. It consists of
|
||||
- the string /proc/self/fd/
|
||||
- the file descriptor number
|
||||
- the file name provided.
|
||||
The final NUL is included in the sizeof. A bit of overhead
|
||||
due to the format elements compensates for possible negative
|
||||
numbers. */
|
||||
size_t buflen = sizeof (procfd) + sizeof (int) * 3 + filelen;
|
||||
buf = alloca (buflen);
|
||||
|
||||
__snprintf (buf, buflen, procfd, fd, file);
|
||||
file = buf;
|
||||
}
|
||||
|
||||
return INLINE_SYSCALL (mknod, 3, file, mode, (unsigned int) k_dev);
|
||||
#endif
|
||||
return INLINE_SYSCALL (mknodat, 4, fd, file, mode, (unsigned int) k_dev);
|
||||
}
|
||||
|
||||
libc_hidden_def (__xmknodat)
|
||||
|
Loading…
Reference in New Issue
Block a user