mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-08 14:20:07 +00:00
* io/Makefile (routines): Add fstatat, fstatat64, fxstatat, fxstatat64,
fchownat, and unlinkat. (static-only-routines): Add fstatat and fstatat64. (tests): Add tst-unlinkat, tst-fstatat, tst-futimesat, tst-renameat, and tst-fchownat. * io/Versions [GLIBC_2.4]: Add fchownat, __fxstatat, __fxstatat64, and unlinkat. * io/fcntl.h: Define AT_FDCWD, AT_SYMLINK_NOFOLLOW, and AT_REMOVEDIR. * io/fstatat.c: New file. * io/fstatat64.c: New file. * io/sys/stat.h: Declare fstatat, fstatat64, __fxstatat, __fxstatat64 and define fstatat and fstatat64 inline functions. * libio/stdio.h: Declare renameat. * misc/Makefile (routines): Add futimesat. * misc/Versions [GLIBC_2.4]: Add futimesat. * posix/unistd.h: Declare fchownat and unlinkat. * stdio-common/Makefile (routines): Add renameat. * stdio-common/Versions [GLIBC_2.4]: Add renameat. * sysdeps/generic/fchownat.c: New file. * sysdeps/generic/futimesat.c: New file. * sysdeps/generic/fxstatat.c: New file. * sysdeps/generic/fxstatat64.c: New file. * sysdeps/generic/renameat.c: New file. * sysdeps/generic/unlinkat.c: New file. * sysdeps/unix/sysv/linux/fchownat.c: New file. * sysdeps/unix/sysv/linux/futimesat.c: New file. * sysdeps/unix/sysv/linux/fxstatat.c: New file. * sysdeps/unix/sysv/linux/fxstatat64.c: New file. * sysdeps/unix/sysv/linux/renameat.c: New file. * sysdeps/unix/sysv/linux/unlinkat.c: New file. * sysdeps/unix/sysv/linux/alpha/fxstatat.c: New file. * sysdeps/unix/sysv/linux/i386/fchownat.c: New file. * sysdeps/unix/sysv/linux/i386/fxstatat.c: New file. * sysdeps/unix/sysv/linux/m68k/fchownat.c: New file. * sysdeps/unix/sysv/linux/m68k/fxstatat.c: New file. * sysdeps/unix/sysv/linux/powerpc/fchownat.c: New file. * sysdeps/unix/sysv/linux/powerpc/powerpc32/fxstatat.c: New file. * sysdeps/unix/sysv/linux/s390/s390-32/fchownat.c: New file. * sysdeps/unix/sysv/linux/s390/s390-32/fxstatat.c: New file. * sysdeps/unix/sysv/linux/sh/fchownat.c: New file. * sysdeps/unix/sysv/linux/sh/fxstatat.c: New file. * sysdeps/unix/sysv/linux/sparc/sparc32/fchownat.c: New file. * sysdeps/unix/sysv/linux/sparc/sparc32/fxstatat.c: New file. * sysdeps/unix/sysv/linux/sparc/sparc64/fxstatat.c: New file. * sysdeps/unix/sysv/linux/wordsize-64/fxstatat.c: New file. * sysdeps/unix/sysv/linux/wordsize-64/fxstatat64.c: New file. * time/sys/time.h: Declare futimesat. * include/fcntl.h: Declare __atfct_seterrno. * sysdeps/unix/sysv/linux/openat.c (__atfct_seterrno): New function. Split out from openat code and called. (do_test): Allow openat to fail with ENOSYS. Handle AT_FDCWD. * sysdeps/generic/openat.c: Handle AT_FDCWD. * sysdeps/generic/openat64.c: Likewise. * io/tst-unlinkat.c: New file. * io/tst-fstatat.c: New file. * io/tst-futimesat.c: New file. * io/tst-renameat.c: New file. * io/tst-fchownat.c: New file. * io/tst-openat.c: Don't fail if openat is not implemented. * sysdeps/unix/sysv/linux/powerpc/chown.c: Don't provide backward compatibility code if new kernel is guaranteed. * time/sys/time.h: Add a few nonnull attributes.
This commit is contained in:
parent
4973cbe599
commit
26cec518ac
67
ChangeLog
67
ChangeLog
@ -1,3 +1,70 @@
|
||||
2005-11-11 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* io/Makefile (routines): Add fstatat, fstatat64, fxstatat, fxstatat64,
|
||||
fchownat, and unlinkat.
|
||||
(static-only-routines): Add fstatat and fstatat64.
|
||||
(tests): Add tst-unlinkat, tst-fstatat, tst-futimesat, tst-renameat,
|
||||
and tst-fchownat.
|
||||
* io/Versions [GLIBC_2.4]: Add fchownat, __fxstatat, __fxstatat64,
|
||||
and unlinkat.
|
||||
* io/fcntl.h: Define AT_FDCWD, AT_SYMLINK_NOFOLLOW, and AT_REMOVEDIR.
|
||||
* io/fstatat.c: New file.
|
||||
* io/fstatat64.c: New file.
|
||||
* io/sys/stat.h: Declare fstatat, fstatat64, __fxstatat, __fxstatat64
|
||||
and define fstatat and fstatat64 inline functions.
|
||||
* libio/stdio.h: Declare renameat.
|
||||
* misc/Makefile (routines): Add futimesat.
|
||||
* misc/Versions [GLIBC_2.4]: Add futimesat.
|
||||
* posix/unistd.h: Declare fchownat and unlinkat.
|
||||
* stdio-common/Makefile (routines): Add renameat.
|
||||
* stdio-common/Versions [GLIBC_2.4]: Add renameat.
|
||||
* sysdeps/generic/fchownat.c: New file.
|
||||
* sysdeps/generic/futimesat.c: New file.
|
||||
* sysdeps/generic/fxstatat.c: New file.
|
||||
* sysdeps/generic/fxstatat64.c: New file.
|
||||
* sysdeps/generic/renameat.c: New file.
|
||||
* sysdeps/generic/unlinkat.c: New file.
|
||||
* sysdeps/unix/sysv/linux/fchownat.c: New file.
|
||||
* sysdeps/unix/sysv/linux/futimesat.c: New file.
|
||||
* sysdeps/unix/sysv/linux/fxstatat.c: New file.
|
||||
* sysdeps/unix/sysv/linux/fxstatat64.c: New file.
|
||||
* sysdeps/unix/sysv/linux/renameat.c: New file.
|
||||
* sysdeps/unix/sysv/linux/unlinkat.c: New file.
|
||||
* sysdeps/unix/sysv/linux/alpha/fxstatat.c: New file.
|
||||
* sysdeps/unix/sysv/linux/i386/fchownat.c: New file.
|
||||
* sysdeps/unix/sysv/linux/i386/fxstatat.c: New file.
|
||||
* sysdeps/unix/sysv/linux/m68k/fchownat.c: New file.
|
||||
* sysdeps/unix/sysv/linux/m68k/fxstatat.c: New file.
|
||||
* sysdeps/unix/sysv/linux/powerpc/fchownat.c: New file.
|
||||
* sysdeps/unix/sysv/linux/powerpc/powerpc32/fxstatat.c: New file.
|
||||
* sysdeps/unix/sysv/linux/s390/s390-32/fchownat.c: New file.
|
||||
* sysdeps/unix/sysv/linux/s390/s390-32/fxstatat.c: New file.
|
||||
* sysdeps/unix/sysv/linux/sh/fchownat.c: New file.
|
||||
* sysdeps/unix/sysv/linux/sh/fxstatat.c: New file.
|
||||
* sysdeps/unix/sysv/linux/sparc/sparc32/fchownat.c: New file.
|
||||
* sysdeps/unix/sysv/linux/sparc/sparc32/fxstatat.c: New file.
|
||||
* sysdeps/unix/sysv/linux/sparc/sparc64/fxstatat.c: New file.
|
||||
* sysdeps/unix/sysv/linux/wordsize-64/fxstatat.c: New file.
|
||||
* sysdeps/unix/sysv/linux/wordsize-64/fxstatat64.c: New file.
|
||||
* time/sys/time.h: Declare futimesat.
|
||||
* include/fcntl.h: Declare __atfct_seterrno.
|
||||
* sysdeps/unix/sysv/linux/openat.c (__atfct_seterrno): New function.
|
||||
Split out from openat code and called.
|
||||
(do_test): Allow openat to fail with ENOSYS. Handle AT_FDCWD.
|
||||
* sysdeps/generic/openat.c: Handle AT_FDCWD.
|
||||
* sysdeps/generic/openat64.c: Likewise.
|
||||
* io/tst-unlinkat.c: New file.
|
||||
* io/tst-fstatat.c: New file.
|
||||
* io/tst-futimesat.c: New file.
|
||||
* io/tst-renameat.c: New file.
|
||||
* io/tst-fchownat.c: New file.
|
||||
* io/tst-openat.c: Don't fail if openat is not implemented.
|
||||
|
||||
* sysdeps/unix/sysv/linux/powerpc/chown.c: Don't provide backward
|
||||
compatibility code if new kernel is guaranteed.
|
||||
|
||||
* time/sys/time.h: Add a few nonnull attributes.
|
||||
|
||||
2005-11-09 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* io/fcntl.h: Declare openat and openat64.
|
||||
|
5
NEWS
5
NEWS
@ -1,4 +1,4 @@
|
||||
GNU C Library NEWS -- history of user-visible changes. 2005-11-09
|
||||
GNU C Library NEWS -- history of user-visible changes. 2005-11-11
|
||||
Copyright (C) 1992-2002,2003,2004,2005 Free Software Foundation, Inc.
|
||||
See the end for copying conditions.
|
||||
|
||||
@ -27,7 +27,8 @@ Version 2.4
|
||||
For a libc and libpthread that works well on Linux 2.4 kernels, we
|
||||
recommend using the stable 2.3 branch.
|
||||
|
||||
* New interfaces: fdopendir, openat.
|
||||
* New interfaces: fdopendir, openat, fstatat, fchownat, futimesat, renameat,
|
||||
unlinkat.
|
||||
|
||||
Version 2.3.6
|
||||
|
||||
|
@ -18,4 +18,8 @@ libc_hidden_proto (__open)
|
||||
extern int __fcntl (int __fd, int __cmd, ...);
|
||||
libc_hidden_proto (__fcntl)
|
||||
|
||||
/* Helper functions for the various *at functions. For Linux. */
|
||||
extern void __atfct_seterrno (int errval, int fd, const char *buf)
|
||||
attribute_hidden;
|
||||
|
||||
#endif
|
||||
|
51
io/Makefile
51
io/Makefile
@ -26,40 +26,43 @@ headers := sys/stat.h bits/stat.h sys/statfs.h bits/statfs.h sys/vfs.h \
|
||||
poll.h sys/poll.h bits/poll.h \
|
||||
utime.h ftw.h fts.h sys/sendfile.h
|
||||
|
||||
routines := \
|
||||
utime \
|
||||
mkfifo \
|
||||
stat fstat lstat mknod stat64 fstat64 lstat64 \
|
||||
xstat fxstat lxstat xmknod xstat64 fxstat64 lxstat64 \
|
||||
statfs fstatfs statfs64 fstatfs64 \
|
||||
statvfs fstatvfs statvfs64 fstatvfs64 \
|
||||
umask chmod fchmod lchmod mkdir \
|
||||
open open64 openat openat64 close \
|
||||
read write lseek lseek64 access euidaccess \
|
||||
fcntl flock lockf lockf64 \
|
||||
dup dup2 pipe \
|
||||
creat creat64 \
|
||||
chdir fchdir \
|
||||
getcwd getwd getdirname \
|
||||
chown fchown lchown \
|
||||
ttyname ttyname_r isatty \
|
||||
link symlink readlink \
|
||||
unlink rmdir \
|
||||
ftw ftw64 fts poll \
|
||||
posix_fadvise posix_fadvise64 \
|
||||
posix_fallocate posix_fallocate64 \
|
||||
routines := \
|
||||
utime \
|
||||
mkfifo \
|
||||
stat fstat lstat mknod stat64 fstat64 lstat64 fstatat fstatat64 \
|
||||
xstat fxstat lxstat xmknod xstat64 fxstat64 lxstat64 \
|
||||
fxstatat fxstatat64 \
|
||||
statfs fstatfs statfs64 fstatfs64 \
|
||||
statvfs fstatvfs statvfs64 fstatvfs64 \
|
||||
umask chmod fchmod lchmod mkdir \
|
||||
open open64 openat openat64 close \
|
||||
read write lseek lseek64 access euidaccess \
|
||||
fcntl flock lockf lockf64 \
|
||||
dup dup2 pipe \
|
||||
creat creat64 \
|
||||
chdir fchdir \
|
||||
getcwd getwd getdirname \
|
||||
chown fchown lchown fchownat \
|
||||
ttyname ttyname_r isatty \
|
||||
link symlink readlink \
|
||||
unlink unlinkat rmdir \
|
||||
ftw ftw64 fts poll \
|
||||
posix_fadvise posix_fadvise64 \
|
||||
posix_fallocate posix_fallocate64 \
|
||||
sendfile sendfile64
|
||||
|
||||
# These routines will be omitted from the libc shared object.
|
||||
# Instead the static object files will be included in a special archive
|
||||
# linked against when the shared library will be used.
|
||||
static-only-routines = stat fstat lstat mknod stat64 fstat64 lstat64
|
||||
static-only-routines = stat fstat lstat mknod stat64 fstat64 lstat64 \
|
||||
fstatat fstatat64
|
||||
|
||||
others := pwd
|
||||
test-srcs := ftwtest
|
||||
tests := test-utime test-stat test-stat2 test-lfs tst-getcwd \
|
||||
tst-fcntl bug-ftw1 bug-ftw2 bug-ftw3 bug-ftw4 tst-statvfs \
|
||||
tst-openat
|
||||
tst-openat tst-unlinkat tst-fstatat tst-futimesat \
|
||||
tst-renameat tst-fchownat
|
||||
|
||||
distribute := ftwtest-sh
|
||||
|
||||
|
@ -98,6 +98,9 @@ libc {
|
||||
nftw; nftw64;
|
||||
}
|
||||
GLIBC_2.4 {
|
||||
fchownat;
|
||||
__fxstatat; __fxstatat64;
|
||||
openat; openat64;
|
||||
unlinkat;
|
||||
}
|
||||
}
|
||||
|
@ -56,6 +56,15 @@ __BEGIN_DECLS
|
||||
# define SEEK_END 2 /* Seek from end of file. */
|
||||
#endif /* XPG */
|
||||
|
||||
#ifdef __USE_GNU
|
||||
# define AT_FDCWD -100 /* Special value used to indicate
|
||||
openat should use the current
|
||||
working directory. */
|
||||
# define AT_SYMLINK_NOFOLLOW 0x100 /* Do not follow symbolic links. */
|
||||
# define AT_REMOVEDIR 0x200 /* Remove directory instead of
|
||||
unlinking file. */
|
||||
#endif
|
||||
|
||||
/* Do the file control operation described by CMD on FD.
|
||||
The remaining arguments are interpreted depending on CMD.
|
||||
|
||||
|
58
io/fstatat.c
Normal file
58
io/fstatat.c
Normal file
@ -0,0 +1,58 @@
|
||||
/* Copyright (C) 2005 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.
|
||||
|
||||
In addition to the permissions in the GNU Lesser General Public
|
||||
License, the Free Software Foundation gives you unlimited
|
||||
permission to link the compiled version of this file with other
|
||||
programs, and to distribute those programs without any restriction
|
||||
coming from the use of this file. (The GNU Lesser General Public
|
||||
License restrictions do apply in other respects; for example, they
|
||||
cover modification of the file, and distribution when not linked
|
||||
into another program.)
|
||||
|
||||
Note that people who make modified versions of this file are not
|
||||
obligated to grant this special exception for their modified
|
||||
versions; it is their choice whether to do so. The GNU Lesser
|
||||
General Public License gives permission to release a modified
|
||||
version without this exception; this exception also makes it
|
||||
possible to release a modified version which carries forward this
|
||||
exception.
|
||||
|
||||
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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
/* This definition is only used if inlining fails for this function; see
|
||||
the last page of <sys/stat.h>. The real work is done by the `x'
|
||||
function which is passed a version number argument. We arrange in the
|
||||
makefile that when not inlined this function is always statically
|
||||
linked; that way a dynamically-linked executable always encodes the
|
||||
version number corresponding to the data structures it uses, so the `x'
|
||||
functions in the shared library can adapt without needing to recompile
|
||||
all callers. */
|
||||
|
||||
#undef fstatat
|
||||
int
|
||||
fstatat (int fd, const char *file, struct stat *buf, int flag)
|
||||
{
|
||||
return __fxstatat (_STAT_VER, fd, file, buf, flag);
|
||||
}
|
||||
|
||||
/* Hide the symbol so that no definition but the one locally in the
|
||||
executable or DSO is used. */
|
||||
#ifdef HAVE_DOT_HIDDEN
|
||||
asm (".hidden\tfstatat");
|
||||
#endif
|
58
io/fstatat64.c
Normal file
58
io/fstatat64.c
Normal file
@ -0,0 +1,58 @@
|
||||
/* Copyright (C) 2005 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.
|
||||
|
||||
In addition to the permissions in the GNU Lesser General Public
|
||||
License, the Free Software Foundation gives you unlimited
|
||||
permission to link the compiled version of this file with other
|
||||
programs, and to distribute those programs without any restriction
|
||||
coming from the use of this file. (The GNU Lesser General Public
|
||||
License restrictions do apply in other respects; for example, they
|
||||
cover modification of the file, and distribution when not linked
|
||||
into another program.)
|
||||
|
||||
Note that people who make modified versions of this file are not
|
||||
obligated to grant this special exception for their modified
|
||||
versions; it is their choice whether to do so. The GNU Lesser
|
||||
General Public License gives permission to release a modified
|
||||
version without this exception; this exception also makes it
|
||||
possible to release a modified version which carries forward this
|
||||
exception.
|
||||
|
||||
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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
/* This definition is only used if inlining fails for this function; see
|
||||
the last page of <sys/stat.h>. The real work is done by the `x'
|
||||
function which is passed a version number argument. We arrange in the
|
||||
makefile that when not inlined this function is always statically
|
||||
linked; that way a dynamically-linked executable always encodes the
|
||||
version number corresponding to the data structures it uses, so the `x'
|
||||
functions in the shared library can adapt without needing to recompile
|
||||
all callers. */
|
||||
|
||||
#undef fstatat64
|
||||
int
|
||||
fstatat64 (int fd, const char *file, struct stat64 *buf, int flag)
|
||||
{
|
||||
return __fxstatat64 (_STAT_VER, fd, file, buf, flag);
|
||||
}
|
||||
|
||||
/* Hide the symbol so that no definition but the one locally in the
|
||||
executable or DSO is used. */
|
||||
#ifdef HAVE_DOT_HIDDEN
|
||||
asm (".hidden\tfstatat64");
|
||||
#endif
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1991,1992,1995-2002,2003,2004 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1991,1992,1995-2004,2005 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
|
||||
@ -228,6 +228,23 @@ extern int stat64 (__const char *__restrict __file,
|
||||
extern int fstat64 (int __fd, struct stat64 *__buf) __THROW __nonnull ((2));
|
||||
#endif
|
||||
|
||||
#ifdef __USE_GNU
|
||||
/* Similar to stat, get the attributes for FILE and put them in BUF.
|
||||
Relative path names are interpreted relative to FD unless FD is
|
||||
AT_FDCWD. */
|
||||
# ifndef __USE_FILE_OFFSET64
|
||||
extern int fstatat (int __fd, const char *__file, struct stat *__buf,
|
||||
int __flag) __THROW __nonnull ((2, 3));
|
||||
# else
|
||||
extern int __REDIRECT_NTH (fstatat, (int __fd, const char *__file,
|
||||
struct stat *__buf, int __flag),
|
||||
fstatat64) __THROW __nonnull ((2, 3));
|
||||
# endif
|
||||
|
||||
extern int fstatat64 (int __fd, const char *__file, struct stat64 *__buf,
|
||||
int __flag) __THROW __nonnull ((2, 3));
|
||||
#endif
|
||||
|
||||
#if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
|
||||
# ifndef __USE_FILE_OFFSET64
|
||||
/* Get file attributes about FILE and put them in BUF.
|
||||
@ -327,6 +344,9 @@ extern int __xstat (int __ver, __const char *__filename,
|
||||
struct stat *__stat_buf) __THROW __nonnull ((2, 3));
|
||||
extern int __lxstat (int __ver, __const char *__filename,
|
||||
struct stat *__stat_buf) __THROW __nonnull ((2, 3));
|
||||
extern int __fxstatat (int __ver, int __fildes, __const char *__filename,
|
||||
struct stat *__stat_buf, int __flag)
|
||||
__THROW __nonnull ((3, 4));
|
||||
#else
|
||||
# ifdef __REDIRECT_NTH
|
||||
extern int __REDIRECT_NTH (__fxstat, (int __ver, int __fildes,
|
||||
@ -338,6 +358,10 @@ extern int __REDIRECT_NTH (__xstat, (int __ver, __const char *__filename,
|
||||
extern int __REDIRECT_NTH (__lxstat, (int __ver, __const char *__filename,
|
||||
struct stat *__stat_buf), __lxstat64)
|
||||
__nonnull ((2, 3));
|
||||
extern int __REDIRECT_NTH (__fxstatat, (int __ver, int __fildes,
|
||||
__const char *__filename,
|
||||
struct stat *__stat_buf, int __flag),
|
||||
__fxstatat64) __nonnull ((3, 4));
|
||||
|
||||
# else
|
||||
# define __fxstat __fxstat64
|
||||
@ -353,6 +377,9 @@ extern int __xstat64 (int __ver, __const char *__filename,
|
||||
struct stat64 *__stat_buf) __THROW __nonnull ((2, 3));
|
||||
extern int __lxstat64 (int __ver, __const char *__filename,
|
||||
struct stat64 *__stat_buf) __THROW __nonnull ((2, 3));
|
||||
extern int __fxstatat64 (int __ver, int __fildes, __const char *__filename,
|
||||
struct stat64 *__stat_buf, int __flag)
|
||||
__THROW __nonnull ((3, 4));
|
||||
#endif
|
||||
extern int __xmknod (int __ver, __const char *__path, __mode_t __mode,
|
||||
__dev_t *__dev) __THROW __nonnull ((2, 4));
|
||||
@ -380,6 +407,15 @@ __NTH (fstat (int __fd, struct stat *__statbuf))
|
||||
return __fxstat (_STAT_VER, __fd, __statbuf);
|
||||
}
|
||||
|
||||
# ifdef __USE_GNU
|
||||
extern __inline__ int
|
||||
__NTH (fstatat (int __fd, __const char *__filename, struct stat *__statbuf,
|
||||
int __flag))
|
||||
{
|
||||
return __fxstatat (_STAT_VER, __fd, __filename, __statbuf, __flag);
|
||||
}
|
||||
# endif
|
||||
|
||||
# if defined __USE_MISC || defined __USE_BSD
|
||||
extern __inline__ int
|
||||
__NTH (mknod (__const char *__path, __mode_t __mode, __dev_t __dev))
|
||||
@ -412,6 +448,15 @@ __NTH (fstat64 (int __fd, struct stat64 *__statbuf))
|
||||
}
|
||||
# endif
|
||||
|
||||
# ifdef __USE_GNU
|
||||
extern __inline__ int
|
||||
__NTH (fstatat64 (int __fd, __const char *__filename, struct stat64 *__statbuf,
|
||||
int __flag))
|
||||
{
|
||||
return __fxstatat64 (_STAT_VER, __fd, __filename, __statbuf, __flag);
|
||||
}
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
__END_DECLS
|
||||
|
145
io/tst-fchownat.c
Normal file
145
io/tst-fchownat.c
Normal file
@ -0,0 +1,145 @@
|
||||
#include <dirent.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
static void prepare (void);
|
||||
#define PREPARE(argc, argv) prepare ()
|
||||
|
||||
static int do_test (void);
|
||||
#define TEST_FUNCTION do_test ()
|
||||
|
||||
#include "../test-skeleton.c"
|
||||
|
||||
static int dir_fd;
|
||||
|
||||
static void
|
||||
prepare (void)
|
||||
{
|
||||
#if _POSIX_CHOWN_RESTRICTED > 0
|
||||
uid_t uid = getuid ();
|
||||
if (uid != 0)
|
||||
{
|
||||
puts ("need root privileges");
|
||||
exit (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
size_t test_dir_len = strlen (test_dir);
|
||||
static const char dir_name[] = "/tst-fchownat.XXXXXX";
|
||||
|
||||
size_t dirbuflen = test_dir_len + sizeof (dir_name);
|
||||
char *dirbuf = malloc (dirbuflen);
|
||||
if (dirbuf == NULL)
|
||||
{
|
||||
puts ("out of memory");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
snprintf (dirbuf, dirbuflen, "%s%s", test_dir, dir_name);
|
||||
if (mkdtemp (dirbuf) == NULL)
|
||||
{
|
||||
puts ("cannot create temporary directory");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
add_temp_file (dirbuf);
|
||||
|
||||
dir_fd = open (dirbuf, O_RDONLY | O_DIRECTORY);
|
||||
if (dir_fd == -1)
|
||||
{
|
||||
puts ("cannot open directory");
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
do_test (void)
|
||||
{
|
||||
/* fdopendir takes over the descriptor, make a copy. */
|
||||
int dupfd = dup (dir_fd);
|
||||
if (dupfd == -1)
|
||||
{
|
||||
puts ("dup failed");
|
||||
return 1;
|
||||
}
|
||||
if (lseek (dupfd, 0, SEEK_SET) != 0)
|
||||
{
|
||||
puts ("1st lseek failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* The directory should be empty safe the . and .. files. */
|
||||
DIR *dir = fdopendir (dupfd);
|
||||
if (dir == NULL)
|
||||
{
|
||||
puts ("fdopendir failed");
|
||||
return 1;
|
||||
}
|
||||
struct dirent64 *d;
|
||||
while ((d = readdir64 (dir)) != NULL)
|
||||
if (strcmp (d->d_name, ".") != 0 && strcmp (d->d_name, "..") != 0)
|
||||
{
|
||||
printf ("temp directory contains file \"%s\"\n", d->d_name);
|
||||
return 1;
|
||||
}
|
||||
closedir (dir);
|
||||
|
||||
/* Try to create a file. */
|
||||
int fd = openat (dir_fd, "some-file", O_CREAT|O_RDWR|O_EXCL, 0666);
|
||||
if (fd == -1)
|
||||
{
|
||||
if (errno == ENOSYS)
|
||||
{
|
||||
puts ("*at functions not supported");
|
||||
return 0;
|
||||
}
|
||||
|
||||
puts ("file creation failed");
|
||||
return 1;
|
||||
}
|
||||
write (fd, "hello", 5);
|
||||
puts ("file created");
|
||||
|
||||
struct stat64 st1;
|
||||
if (fstat64 (fd, &st1) != 0)
|
||||
{
|
||||
puts ("fstat64 failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
close (fd);
|
||||
|
||||
if (fchownat (dir_fd, "some-file", st1.st_uid + 1, st1.st_gid + 1, 0) != 0)
|
||||
{
|
||||
puts ("fchownat failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct stat64 st2;
|
||||
if (fstatat64 (dir_fd, "some-file", &st2, 0) != 0)
|
||||
{
|
||||
puts ("fstatat64 failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (st1.st_uid + 1 != st2.st_uid || st1.st_gid + 1 != st2.st_gid)
|
||||
{
|
||||
puts ("owner change failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (unlinkat (dir_fd, "some-file", 0) != 0)
|
||||
{
|
||||
puts ("unlinkat failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
close (dir_fd);
|
||||
|
||||
return 0;
|
||||
}
|
143
io/tst-fstatat.c
Normal file
143
io/tst-fstatat.c
Normal file
@ -0,0 +1,143 @@
|
||||
#include <dirent.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
static void prepare (void);
|
||||
#define PREPARE(argc, argv) prepare ()
|
||||
|
||||
static int do_test (void);
|
||||
#define TEST_FUNCTION do_test ()
|
||||
|
||||
#include "../test-skeleton.c"
|
||||
|
||||
static int dir_fd;
|
||||
|
||||
static void
|
||||
prepare (void)
|
||||
{
|
||||
size_t test_dir_len = strlen (test_dir);
|
||||
static const char dir_name[] = "/tst-fstatat.XXXXXX";
|
||||
|
||||
size_t dirbuflen = test_dir_len + sizeof (dir_name);
|
||||
char *dirbuf = malloc (dirbuflen);
|
||||
if (dirbuf == NULL)
|
||||
{
|
||||
puts ("out of memory");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
snprintf (dirbuf, dirbuflen, "%s%s", test_dir, dir_name);
|
||||
if (mkdtemp (dirbuf) == NULL)
|
||||
{
|
||||
puts ("cannot create temporary directory");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
add_temp_file (dirbuf);
|
||||
|
||||
dir_fd = open (dirbuf, O_RDONLY | O_DIRECTORY);
|
||||
if (dir_fd == -1)
|
||||
{
|
||||
puts ("cannot open directory");
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
do_test (void)
|
||||
{
|
||||
/* fdopendir takes over the descriptor, make a copy. */
|
||||
int dupfd = dup (dir_fd);
|
||||
if (dupfd == -1)
|
||||
{
|
||||
puts ("dup failed");
|
||||
return 1;
|
||||
}
|
||||
if (lseek (dupfd, 0, SEEK_SET) != 0)
|
||||
{
|
||||
puts ("1st lseek failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* The directory should be empty safe the . and .. files. */
|
||||
DIR *dir = fdopendir (dupfd);
|
||||
if (dir == NULL)
|
||||
{
|
||||
puts ("fdopendir failed");
|
||||
return 1;
|
||||
}
|
||||
struct dirent64 *d;
|
||||
while ((d = readdir64 (dir)) != NULL)
|
||||
if (strcmp (d->d_name, ".") != 0 && strcmp (d->d_name, "..") != 0)
|
||||
{
|
||||
printf ("temp directory contains file \"%s\"\n", d->d_name);
|
||||
return 1;
|
||||
}
|
||||
closedir (dir);
|
||||
|
||||
/* Try to create a file. */
|
||||
int fd = openat (dir_fd, "some-file", O_CREAT|O_RDWR|O_EXCL, 0666);
|
||||
if (fd == -1)
|
||||
{
|
||||
if (errno == ENOSYS)
|
||||
{
|
||||
puts ("*at functions not supported");
|
||||
return 0;
|
||||
}
|
||||
|
||||
puts ("file creation failed");
|
||||
return 1;
|
||||
}
|
||||
write (fd, "hello", 5);
|
||||
puts ("file created");
|
||||
|
||||
struct stat64 st1;
|
||||
if (fstat64 (fd, &st1) != 0)
|
||||
{
|
||||
puts ("fstat64 failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
close (fd);
|
||||
|
||||
struct stat64 st2;
|
||||
if (fstatat64 (dir_fd, "some-file", &st2, 0) != 0)
|
||||
{
|
||||
puts ("fstatat64 failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (st1.st_dev != st2.st_dev
|
||||
|| st1.st_ino != st2.st_ino
|
||||
|| st1.st_size != st2.st_size)
|
||||
{
|
||||
puts ("stat results do not match");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (unlinkat (dir_fd, "some-file", 0) != 0)
|
||||
{
|
||||
puts ("unlinkat failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (fstatat64 (dir_fd, "some-file", &st2, 0) == 0)
|
||||
{
|
||||
puts ("second fstatat64 succeeded");
|
||||
return 1;
|
||||
}
|
||||
if (errno != ENOENT)
|
||||
{
|
||||
puts ("second fstatat64 did not fail with ENOENT");
|
||||
return 1;
|
||||
}
|
||||
|
||||
close (dir_fd);
|
||||
|
||||
return 0;
|
||||
}
|
147
io/tst-futimesat.c
Normal file
147
io/tst-futimesat.c
Normal file
@ -0,0 +1,147 @@
|
||||
#include <dirent.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
|
||||
static void prepare (void);
|
||||
#define PREPARE(argc, argv) prepare ()
|
||||
|
||||
static int do_test (void);
|
||||
#define TEST_FUNCTION do_test ()
|
||||
|
||||
#include "../test-skeleton.c"
|
||||
|
||||
static int dir_fd;
|
||||
|
||||
static void
|
||||
prepare (void)
|
||||
{
|
||||
size_t test_dir_len = strlen (test_dir);
|
||||
static const char dir_name[] = "/tst-futimesat.XXXXXX";
|
||||
|
||||
size_t dirbuflen = test_dir_len + sizeof (dir_name);
|
||||
char *dirbuf = malloc (dirbuflen);
|
||||
if (dirbuf == NULL)
|
||||
{
|
||||
puts ("out of memory");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
snprintf (dirbuf, dirbuflen, "%s%s", test_dir, dir_name);
|
||||
if (mkdtemp (dirbuf) == NULL)
|
||||
{
|
||||
puts ("cannot create temporary directory");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
add_temp_file (dirbuf);
|
||||
|
||||
dir_fd = open (dirbuf, O_RDONLY | O_DIRECTORY);
|
||||
if (dir_fd == -1)
|
||||
{
|
||||
puts ("cannot open directory");
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
do_test (void)
|
||||
{
|
||||
/* fdopendir takes over the descriptor, make a copy. */
|
||||
int dupfd = dup (dir_fd);
|
||||
if (dupfd == -1)
|
||||
{
|
||||
puts ("dup failed");
|
||||
return 1;
|
||||
}
|
||||
if (lseek (dupfd, 0, SEEK_SET) != 0)
|
||||
{
|
||||
puts ("1st lseek failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* The directory should be empty safe the . and .. files. */
|
||||
DIR *dir = fdopendir (dupfd);
|
||||
if (dir == NULL)
|
||||
{
|
||||
puts ("fdopendir failed");
|
||||
return 1;
|
||||
}
|
||||
struct dirent64 *d;
|
||||
while ((d = readdir64 (dir)) != NULL)
|
||||
if (strcmp (d->d_name, ".") != 0 && strcmp (d->d_name, "..") != 0)
|
||||
{
|
||||
printf ("temp directory contains file \"%s\"\n", d->d_name);
|
||||
return 1;
|
||||
}
|
||||
closedir (dir);
|
||||
|
||||
/* Try to create a file. */
|
||||
int fd = openat (dir_fd, "some-file", O_CREAT|O_RDWR|O_EXCL, 0666);
|
||||
if (fd == -1)
|
||||
{
|
||||
if (errno == ENOSYS)
|
||||
{
|
||||
puts ("*at functions not supported");
|
||||
return 0;
|
||||
}
|
||||
|
||||
puts ("file creation failed");
|
||||
return 1;
|
||||
}
|
||||
write (fd, "hello", 5);
|
||||
puts ("file created");
|
||||
|
||||
struct stat64 st1;
|
||||
if (fstat64 (fd, &st1) != 0)
|
||||
{
|
||||
puts ("fstat64 failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
close (fd);
|
||||
|
||||
struct timeval tv[2];
|
||||
tv[0].tv_sec = st1.st_atime + 1;
|
||||
tv[0].tv_usec = 0;
|
||||
tv[1].tv_sec = st1.st_mtime + 1;
|
||||
tv[1].tv_usec = 0;
|
||||
if (futimesat (dir_fd, "some-file", tv) != 0)
|
||||
{
|
||||
puts ("futimesat failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct stat64 st2;
|
||||
if (fstatat64 (dir_fd, "some-file", &st2, 0) != 0)
|
||||
{
|
||||
puts ("fstatat64 failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (st2.st_mtime != tv[1].tv_sec
|
||||
#ifdef _STATBUF_ST_NSEC
|
||||
|| st2.st_mtim.tv_nsec != 0
|
||||
#endif
|
||||
)
|
||||
{
|
||||
puts ("stat shows different mtime");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
if (unlinkat (dir_fd, "some-file", 0) != 0)
|
||||
{
|
||||
puts ("unlinkat failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
close (dir_fd);
|
||||
|
||||
return 0;
|
||||
}
|
@ -84,6 +84,12 @@ do_test (void)
|
||||
int fd = openat (dir_fd, "some-file", O_CREAT|O_RDWR|O_EXCL, 0666);
|
||||
if (fd == -1)
|
||||
{
|
||||
if (errno == ENOSYS)
|
||||
{
|
||||
puts ("*at functions not supported");
|
||||
return 0;
|
||||
}
|
||||
|
||||
puts ("file creation failed");
|
||||
return 1;
|
||||
}
|
||||
|
149
io/tst-renameat.c
Normal file
149
io/tst-renameat.c
Normal file
@ -0,0 +1,149 @@
|
||||
#include <dirent.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
static void prepare (void);
|
||||
#define PREPARE(argc, argv) prepare ()
|
||||
|
||||
static int do_test (void);
|
||||
#define TEST_FUNCTION do_test ()
|
||||
|
||||
#include "../test-skeleton.c"
|
||||
|
||||
static int dir_fd;
|
||||
|
||||
static void
|
||||
prepare (void)
|
||||
{
|
||||
size_t test_dir_len = strlen (test_dir);
|
||||
static const char dir_name[] = "/tst-renameat.XXXXXX";
|
||||
|
||||
size_t dirbuflen = test_dir_len + sizeof (dir_name);
|
||||
char *dirbuf = malloc (dirbuflen);
|
||||
if (dirbuf == NULL)
|
||||
{
|
||||
puts ("out of memory");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
snprintf (dirbuf, dirbuflen, "%s%s", test_dir, dir_name);
|
||||
if (mkdtemp (dirbuf) == NULL)
|
||||
{
|
||||
puts ("cannot create temporary directory");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
add_temp_file (dirbuf);
|
||||
|
||||
dir_fd = open (dirbuf, O_RDONLY | O_DIRECTORY);
|
||||
if (dir_fd == -1)
|
||||
{
|
||||
puts ("cannot open directory");
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
do_test (void)
|
||||
{
|
||||
/* fdopendir takes over the descriptor, make a copy. */
|
||||
int dupfd = dup (dir_fd);
|
||||
if (dupfd == -1)
|
||||
{
|
||||
puts ("dup failed");
|
||||
return 1;
|
||||
}
|
||||
if (lseek (dupfd, 0, SEEK_SET) != 0)
|
||||
{
|
||||
puts ("1st lseek failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* The directory should be empty safe the . and .. files. */
|
||||
DIR *dir = fdopendir (dupfd);
|
||||
if (dir == NULL)
|
||||
{
|
||||
puts ("fdopendir failed");
|
||||
return 1;
|
||||
}
|
||||
struct dirent64 *d;
|
||||
while ((d = readdir64 (dir)) != NULL)
|
||||
if (strcmp (d->d_name, ".") != 0 && strcmp (d->d_name, "..") != 0)
|
||||
{
|
||||
printf ("temp directory contains file \"%s\"\n", d->d_name);
|
||||
return 1;
|
||||
}
|
||||
closedir (dir);
|
||||
|
||||
/* Try to create a file. */
|
||||
int fd = openat (dir_fd, "some-file", O_CREAT|O_RDWR|O_EXCL, 0666);
|
||||
if (fd == -1)
|
||||
{
|
||||
if (errno == ENOSYS)
|
||||
{
|
||||
puts ("*at functions not supported");
|
||||
return 0;
|
||||
}
|
||||
|
||||
puts ("file creation failed");
|
||||
return 1;
|
||||
}
|
||||
write (fd, "hello", 5);
|
||||
puts ("file created");
|
||||
|
||||
struct stat64 st1;
|
||||
if (fstat64 (fd, &st1) != 0)
|
||||
{
|
||||
puts ("fstat64 failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
close (fd);
|
||||
|
||||
if (renameat (dir_fd, "some-file", dir_fd, "another-file") != 0)
|
||||
{
|
||||
puts ("renameat failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct stat64 st2;
|
||||
if (fstatat64 (dir_fd, "some-file", &st2, 0) == 0)
|
||||
{
|
||||
puts ("fstatat64 succeeded");
|
||||
return 1;
|
||||
}
|
||||
if (errno != ENOENT)
|
||||
{
|
||||
puts ("fstatat64 did not fail with ENOENT");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (fstatat64 (dir_fd, "another-file", &st2, 0) != 0)
|
||||
{
|
||||
puts ("2nd fstatat64 failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (st1.st_dev != st2.st_dev
|
||||
|| st1.st_ino != st2.st_ino
|
||||
|| st1.st_size != st2.st_size)
|
||||
{
|
||||
puts ("stat results do not match");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (unlinkat (dir_fd, "another-file", 0) != 0)
|
||||
{
|
||||
puts ("unlinkat failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
close (dir_fd);
|
||||
|
||||
return 0;
|
||||
}
|
178
io/tst-unlinkat.c
Normal file
178
io/tst-unlinkat.c
Normal file
@ -0,0 +1,178 @@
|
||||
#include <dirent.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
static void prepare (void);
|
||||
#define PREPARE(argc, argv) prepare ()
|
||||
|
||||
static int do_test (void);
|
||||
#define TEST_FUNCTION do_test ()
|
||||
|
||||
#include "../test-skeleton.c"
|
||||
|
||||
static int dir_fd;
|
||||
|
||||
static void
|
||||
prepare (void)
|
||||
{
|
||||
size_t test_dir_len = strlen (test_dir);
|
||||
static const char dir_name[] = "/tst-unlinkat.XXXXXX";
|
||||
|
||||
size_t dirbuflen = test_dir_len + sizeof (dir_name);
|
||||
char *dirbuf = malloc (dirbuflen);
|
||||
if (dirbuf == NULL)
|
||||
{
|
||||
puts ("out of memory");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
snprintf (dirbuf, dirbuflen, "%s%s", test_dir, dir_name);
|
||||
if (mkdtemp (dirbuf) == NULL)
|
||||
{
|
||||
puts ("cannot create temporary directory");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
add_temp_file (dirbuf);
|
||||
|
||||
dir_fd = open (dirbuf, O_RDONLY | O_DIRECTORY);
|
||||
if (dir_fd == -1)
|
||||
{
|
||||
puts ("cannot open directory");
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
do_test (void)
|
||||
{
|
||||
/* fdopendir takes over the descriptor, make a copy. */
|
||||
int dupfd = dup (dir_fd);
|
||||
if (dupfd == -1)
|
||||
{
|
||||
puts ("dup failed");
|
||||
return 1;
|
||||
}
|
||||
if (lseek (dupfd, 0, SEEK_SET) != 0)
|
||||
{
|
||||
puts ("1st lseek failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* The directory should be empty safe the . and .. files. */
|
||||
DIR *dir = fdopendir (dupfd);
|
||||
if (dir == NULL)
|
||||
{
|
||||
puts ("fdopendir failed");
|
||||
return 1;
|
||||
}
|
||||
struct dirent64 *d;
|
||||
while ((d = readdir64 (dir)) != NULL)
|
||||
if (strcmp (d->d_name, ".") != 0 && strcmp (d->d_name, "..") != 0)
|
||||
{
|
||||
printf ("temp directory contains file \"%s\"\n", d->d_name);
|
||||
return 1;
|
||||
}
|
||||
closedir (dir);
|
||||
|
||||
/* Try to create a file. */
|
||||
int fd = openat (dir_fd, "some-file", O_CREAT|O_RDWR|O_EXCL, 0666);
|
||||
if (fd == -1)
|
||||
{
|
||||
if (errno == ENOSYS)
|
||||
{
|
||||
puts ("*at functions not supported");
|
||||
return 0;
|
||||
}
|
||||
|
||||
puts ("file creation failed");
|
||||
return 1;
|
||||
}
|
||||
write (fd, "hello", 5);
|
||||
close (fd);
|
||||
puts ("file created");
|
||||
|
||||
/* fdopendir takes over the descriptor, make a copy. */
|
||||
dupfd = dup (dir_fd);
|
||||
if (dupfd == -1)
|
||||
{
|
||||
puts ("2nd dup failed");
|
||||
return 1;
|
||||
}
|
||||
if (lseek (dupfd, 0, SEEK_SET) != 0)
|
||||
{
|
||||
puts ("2nd lseek failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* The directory should be empty safe the . and .. files. */
|
||||
dir = fdopendir (dupfd);
|
||||
if (dir == NULL)
|
||||
{
|
||||
puts ("2nd fdopendir failed");
|
||||
return 1;
|
||||
}
|
||||
bool seen_file = false;
|
||||
while ((d = readdir64 (dir)) != NULL)
|
||||
if (strcmp (d->d_name, ".") != 0 && strcmp (d->d_name, "..") != 0)
|
||||
{
|
||||
if (strcmp (d->d_name, "some-file") != 0)
|
||||
{
|
||||
printf ("temp directory contains file \"%s\"\n", d->d_name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
seen_file = true;
|
||||
}
|
||||
closedir (dir);
|
||||
|
||||
if (!seen_file)
|
||||
{
|
||||
puts ("file not created in correct directory");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Remove the file now. */
|
||||
if (unlinkat (dir_fd, "some-file", 0) != 0)
|
||||
{
|
||||
puts ("unlinkat failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* We won't need dir_fd anymore after this, so use it. */
|
||||
if (lseek (dir_fd, 0, SEEK_SET) != 0)
|
||||
{
|
||||
puts ("3rd lseek failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* The directory should be empty safe the . and .. files. */
|
||||
dir = fdopendir (dir_fd);
|
||||
if (dir == NULL)
|
||||
{
|
||||
puts ("3rd fdopendir failed");
|
||||
return 1;
|
||||
}
|
||||
while ((d = readdir64 (dir)) != NULL)
|
||||
if (strcmp (d->d_name, ".") != 0 && strcmp (d->d_name, "..") != 0)
|
||||
{
|
||||
if (strcmp (d->d_name, "some-file") == 0)
|
||||
{
|
||||
puts ("some-file not removed");
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf ("temp directory contains file \"%s\"\n", d->d_name);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
closedir (dir);
|
||||
|
||||
return 0;
|
||||
}
|
@ -154,6 +154,11 @@ extern int remove (__const char *__filename) __THROW;
|
||||
extern int rename (__const char *__old, __const char *__new) __THROW;
|
||||
__END_NAMESPACE_STD
|
||||
|
||||
#ifdef __USE_GNU
|
||||
/* Rename file OLD relative to OLDFD to NEW relative to NEWFD. */
|
||||
extern int renameat (int __oldfd, __const char *__old, int __newfd,
|
||||
__const char *__new) __THROW;
|
||||
#endif
|
||||
|
||||
__BEGIN_NAMESPACE_STD
|
||||
/* Create a temporary file and open it read/write.
|
||||
|
@ -47,7 +47,7 @@ routines := brk sbrk sstk ioctl \
|
||||
gtty stty \
|
||||
ptrace \
|
||||
fstab mntent mntent_r \
|
||||
utimes lutimes futimes \
|
||||
utimes lutimes futimes futimesat \
|
||||
truncate ftruncate truncate64 ftruncate64 \
|
||||
chflags fchflags \
|
||||
insremque getttyent getusershell getpass ttyslot \
|
||||
|
@ -131,6 +131,7 @@ libc {
|
||||
remap_file_pages;
|
||||
}
|
||||
GLIBC_2.4 {
|
||||
futimesat;
|
||||
__syslog_chk; __vsyslog_chk;
|
||||
}
|
||||
}
|
||||
|
@ -431,6 +431,14 @@ extern int lchown (__const char *__file, __uid_t __owner, __gid_t __group)
|
||||
|
||||
#endif /* Use BSD || X/Open Unix. */
|
||||
|
||||
#ifdef __USE_GNU
|
||||
/* Change the owner and group of FILE relative to the directory FD is open
|
||||
on. */
|
||||
extern int fchownat (int __fd, __const char *__file, __uid_t __owner,
|
||||
__gid_t __group, int __flag)
|
||||
__THROW __nonnull ((2)) __wur;
|
||||
#endif /* Use GNU. */
|
||||
|
||||
/* Change the process's working directory to PATH. */
|
||||
extern int chdir (__const char *__path) __THROW __nonnull ((1)) __wur;
|
||||
|
||||
@ -749,6 +757,12 @@ extern int readlink (__const char *__restrict __path, char *__restrict __buf,
|
||||
/* Remove the link NAME. */
|
||||
extern int unlink (__const char *__name) __THROW __nonnull ((1));
|
||||
|
||||
#ifdef __USE_GNU
|
||||
/* Remove the link NAME relative to FD. */
|
||||
extern int unlinkat (int __fd, __const char *__name, int __flag)
|
||||
__THROW __nonnull ((2));
|
||||
#endif
|
||||
|
||||
/* Remove the directory PATH. */
|
||||
extern int rmdir (__const char *__path) __THROW __nonnull ((1));
|
||||
|
||||
|
@ -33,7 +33,7 @@ routines := \
|
||||
perror psignal \
|
||||
tmpfile tmpfile64 tmpnam tmpnam_r tempnam tempname \
|
||||
getline getw putw \
|
||||
remove rename \
|
||||
remove rename renameat \
|
||||
flockfile ftrylockfile funlockfile
|
||||
|
||||
install-others = $(inst_includedir)/bits/stdio_lim.h
|
||||
|
@ -37,7 +37,7 @@ libc {
|
||||
tempnam; tmpfile; tmpnam; tmpnam_r;
|
||||
|
||||
# v*
|
||||
vfprintf; vfscanf; vprintf;
|
||||
vfprintf; vfscanf; vprintf;
|
||||
}
|
||||
GLIBC_2.1 {
|
||||
# p*
|
||||
@ -46,6 +46,9 @@ libc {
|
||||
# t*
|
||||
tmpfile; tmpfile64;
|
||||
}
|
||||
GLIBC_2.4 {
|
||||
renameat;
|
||||
}
|
||||
GLIBC_PRIVATE {
|
||||
# global variables
|
||||
_itoa_lower_digits;
|
||||
|
51
sysdeps/generic/fchownat.c
Normal file
51
sysdeps/generic/fchownat.c
Normal file
@ -0,0 +1,51 @@
|
||||
/* Copyright (C) 2005 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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stddef.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
/* Change the owner and group of FILE. */
|
||||
int
|
||||
fchownat (fd, file, owner, group, flag)
|
||||
int fd;
|
||||
const char *file;
|
||||
uid_t owner;
|
||||
gid_t group;
|
||||
int flag;
|
||||
{
|
||||
if (file == NULL || (flag & ~AT_SYMLINK_NOFOLLOW) != 0)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fd < 0 && fd != AT_FDCWD)
|
||||
{
|
||||
__set_errno (EBADF);
|
||||
return -1;
|
||||
}
|
||||
|
||||
__set_errno (ENOSYS);
|
||||
return -1;
|
||||
}
|
||||
stub_warning (fchownat)
|
||||
|
||||
#include <stub-tag.h>
|
52
sysdeps/generic/futimesat.c
Normal file
52
sysdeps/generic/futimesat.c
Normal file
@ -0,0 +1,52 @@
|
||||
/* Copyright (C) 2005 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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stddef.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
|
||||
/* Change the access time of FILE relative to FD to TVP[0] and
|
||||
the modification time of FILE to TVP[1]. */
|
||||
int
|
||||
futimesat (fd, file, tvp)
|
||||
int fd;
|
||||
const char *file;
|
||||
const struct timeval tvp[2];
|
||||
{
|
||||
if (fd < 0 && fd != AT_FDCWD)
|
||||
{
|
||||
__set_errno (EBADF);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (file == NULL)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
__set_errno (ENOSYS);
|
||||
return -1;
|
||||
}
|
||||
|
||||
weak_alias (__utimes, utimes)
|
||||
|
||||
stub_warning (utimes)
|
||||
#include <stub-tag.h>
|
49
sysdeps/generic/fxstatat.c
Normal file
49
sysdeps/generic/fxstatat.c
Normal file
@ -0,0 +1,49 @@
|
||||
/* Copyright (C) 2005 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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stddef.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
/* Get information about the file descriptor FD in BUF. */
|
||||
int
|
||||
__fxstatat (int vers, int fd, const char *filename, struct stat *buf, int flag)
|
||||
{
|
||||
if (vers != _STAT_VER)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fd < 0 && fd != AT_FDCWD)
|
||||
{
|
||||
__set_errno (EBADF);
|
||||
return -1;
|
||||
}
|
||||
if (buf == NULL || (flag & ~AT_SYMLINK_NOFOLLOW) != 0)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
__set_errno (ENOSYS);
|
||||
return -1;
|
||||
}
|
||||
stub_warning (fstatat)
|
||||
#include <stub-tag.h>
|
50
sysdeps/generic/fxstatat64.c
Normal file
50
sysdeps/generic/fxstatat64.c
Normal file
@ -0,0 +1,50 @@
|
||||
/* Copyright (C) 2005 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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stddef.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
/* Get information about the file descriptor FD in BUF. */
|
||||
int
|
||||
__fxstatat64 (int vers, int fd, const char *filename, struct stat64 *buf,
|
||||
int flag)
|
||||
{
|
||||
if (vers != _STAT_VER)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fd < 0 && fd != AT_FDCWD)
|
||||
{
|
||||
__set_errno (EBADF);
|
||||
return -1;
|
||||
}
|
||||
if (buf == NULL || (flag & ~AT_SYMLINK_NOFOLLOW) != 0)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
__set_errno (ENOSYS);
|
||||
return -1;
|
||||
}
|
||||
stub_warning (fstatat64)
|
||||
#include <stub-tag.h>
|
@ -39,7 +39,7 @@ openat (fd, file, oflag)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (file[0] != '/')
|
||||
if (fd != AT_FDCWD && file[0] != '/')
|
||||
{
|
||||
/* Check FD is associated with a directory. */
|
||||
struct stat64 st;
|
||||
|
@ -39,7 +39,7 @@ openat64 (fd, file, oflag)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (file[0] != '/')
|
||||
if (fd != AT_FDCWD && file[0] != '/')
|
||||
{
|
||||
/* Check FD is associated with a directory. */
|
||||
struct stat64 st;
|
||||
|
50
sysdeps/generic/renameat.c
Normal file
50
sysdeps/generic/renameat.c
Normal file
@ -0,0 +1,50 @@
|
||||
/* Copyright (C) 2005 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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
/* Rename the file OLD relative to OLDFD to NEW relative to NEWFD. */
|
||||
int
|
||||
renameat (oldfd, old, newfd, new)
|
||||
int oldfd;
|
||||
const char *old;
|
||||
int newfd;
|
||||
const char *new;
|
||||
{
|
||||
if ((oldfd < 0 & oldfd !_ AT_FDCWD) || (newfd < 0 && newfd != AT_FDCWD))
|
||||
{
|
||||
__set_errno (EBADF);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (old == NULL || new == NULL)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
__set_errno (ENOSYS);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
stub_warning (renameat)
|
||||
#include <stub-tag.h>
|
49
sysdeps/generic/unlinkat.c
Normal file
49
sysdeps/generic/unlinkat.c
Normal file
@ -0,0 +1,49 @@
|
||||
/* Copyright (C) 2005 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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stddef.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
/* Remove the link named NAME. */
|
||||
int
|
||||
unlinkat (fd, name, flag)
|
||||
int fd;
|
||||
const char *name;
|
||||
int flag;
|
||||
{
|
||||
if (name == NULL || (flag & AT_REMOVEDIR) != 0)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fd < 0 && fd != AT_FDCWD)
|
||||
{
|
||||
__set_errno (EBADF);
|
||||
return -1;
|
||||
}
|
||||
|
||||
__set_errno (ENOSYS);
|
||||
return -1;
|
||||
}
|
||||
stub_warning (unlinkat)
|
||||
|
||||
#include <stub-tag.h>
|
100
sysdeps/unix/sysv/linux/alpha/fxstatat.c
Normal file
100
sysdeps/unix/sysv/linux/alpha/fxstatat.c
Normal file
@ -0,0 +1,100 @@
|
||||
/* Copyright (C) 2005 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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#define __fxstatat64 __fxstatat64_disable
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
#include <kernel_stat.h>
|
||||
#include <sysdep.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <xstatconv.h>
|
||||
|
||||
#undef __fxstatat64
|
||||
|
||||
|
||||
/* Get information about the file NAME in BUF. */
|
||||
int
|
||||
__fxstatat (int vers, int fd, const char *file, struct stat *st, int flag)
|
||||
{
|
||||
if (flag & ~AT_SYMLINK_NOFOLLOW)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
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;
|
||||
}
|
||||
|
||||
INTERNAL_SYSCALL_DECL (err);
|
||||
int result, errno_out;
|
||||
struct kernel_stat kst;
|
||||
|
||||
if (vers == _STAT_VER_KERNEL64 && !__libc_missing_axp_stat64)
|
||||
{
|
||||
if (flags & AT_SYMLINK_NOFOLLOW)
|
||||
result = INTERNAL_SYSCALL (lstat64, err, 2, file, st);
|
||||
else
|
||||
result = INTERNAL_SYSCALL (stat64, err, 2, file, st);
|
||||
|
||||
if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
|
||||
return result;
|
||||
errno_out = INTERNAL_SYSCALL_ERRNO (result, err);
|
||||
if (errno_out != ENOSYS)
|
||||
goto fail;
|
||||
__libc_missing_axp_stat64 = 1;
|
||||
}
|
||||
|
||||
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 __xstat_conv (vers, &kst, st);
|
||||
errno_out = INTERNAL_SYSCALL_ERRNO (result, err);
|
||||
|
||||
fail:
|
||||
__atfct_seterrno (errno_out, fd, buf);
|
||||
|
||||
return -1;
|
||||
}
|
||||
hidden_def (__xstat)
|
||||
weak_alias (__xstat, _xstat);
|
||||
strong_alias (__xstat, __xstat64);
|
||||
hidden_ver (__xstat, __xstat64)
|
73
sysdeps/unix/sysv/linux/fchownat.c
Normal file
73
sysdeps/unix/sysv/linux/fchownat.c
Normal file
@ -0,0 +1,73 @@
|
||||
/* Copyright (C) 2005 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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
/* Change the owner and group of FILE. */
|
||||
int
|
||||
fchownat (fd, file, owner, group, flag)
|
||||
int fd;
|
||||
const char *file;
|
||||
uid_t owner;
|
||||
gid_t group;
|
||||
int flag;
|
||||
{
|
||||
if (flag & ~AT_SYMLINK_NOFOLLOW)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
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;
|
||||
}
|
||||
|
||||
int result;
|
||||
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 (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 0))
|
||||
__atfct_seterrno (INTERNAL_SYSCALL_ERRNO (result, err), fd, buf);
|
||||
|
||||
return result;
|
||||
}
|
97
sysdeps/unix/sysv/linux/futimesat.c
Normal file
97
sysdeps/unix/sysv/linux/futimesat.c
Normal file
@ -0,0 +1,97 @@
|
||||
/* Copyright (C) 2005 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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#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
|
||||
the modification time of FILE to TVP[1]. */
|
||||
int
|
||||
futimesat (fd, file, tvp)
|
||||
int fd;
|
||||
const char *file;
|
||||
const struct timeval tvp[2];
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
int result;
|
||||
INTERNAL_SYSCALL_DECL (err);
|
||||
|
||||
#ifdef __NR_utimes
|
||||
result = INTERNAL_SYSCALL (utimes, err, 2, file, tvp);
|
||||
if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
|
||||
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 (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
|
||||
return result;
|
||||
|
||||
fail:
|
||||
#endif
|
||||
|
||||
__atfct_seterrno (INTERNAL_SYSCALL_ERRNO (result, err), fd, buf);
|
||||
|
||||
return -1;
|
||||
}
|
106
sysdeps/unix/sysv/linux/fxstatat.c
Normal file
106
sysdeps/unix/sysv/linux/fxstatat.c
Normal file
@ -0,0 +1,106 @@
|
||||
/* Copyright (C) 2005 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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
/* Ho hum, if fxstatat == fxstatat64 we must get rid of the prototype or gcc
|
||||
will complain since they don't strictly match. */
|
||||
#define __fxstatat64 __fxstatat64_disable
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
#include <kernel_stat.h>
|
||||
|
||||
#include <sysdep.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <bp-checks.h>
|
||||
|
||||
#include <xstatconv.h>
|
||||
|
||||
/* Get information about the file NAME in BUF. */
|
||||
int
|
||||
__fxstatat (int vers, int fd, const char *file, struct stat *st, int flag)
|
||||
{
|
||||
if (flag & ~AT_SYMLINK_NOFOLLOW)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
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;
|
||||
}
|
||||
|
||||
int result;
|
||||
INTERNAL_SYSCALL_DECL (err);
|
||||
|
||||
if (vers == _STAT_VER_KERNEL)
|
||||
{
|
||||
if (flag & AT_SYMLINK_NOFOLLOW)
|
||||
result = INTERNAL_SYSCALL (lstat, err, 2, CHECK_STRING (file),
|
||||
CHECK_1 ((struct kernel_stat *) st));
|
||||
else
|
||||
result = INTERNAL_SYSCALL (stat, err, 2, CHECK_STRING (file),
|
||||
CHECK_1 ((struct kernel_stat *) st));
|
||||
|
||||
if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef STAT_IS_KERNEL_STAT
|
||||
__set_errno (EINVAL);
|
||||
return -1;
|
||||
#else
|
||||
struct kernel_stat kst;
|
||||
|
||||
if (flag & AT_SYMLINK_NOFOLLOW)
|
||||
result = INTERNAL_SYSCALL (lstat, err, 2, CHECK_STRING (file),
|
||||
__ptrvalue (&kst));
|
||||
else
|
||||
result = INTERNAL_SYSCALL (stat, err, 2, CHECK_STRING (file),
|
||||
__ptrvalue (&kst));
|
||||
|
||||
if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
|
||||
return __xstat_conv (vers, &kst, st);
|
||||
#endif
|
||||
|
||||
__atfct_seterrno (INTERNAL_SYSCALL_ERRNO (result, err), fd, buf);
|
||||
|
||||
return -1;
|
||||
}
|
||||
#ifdef XSTAT_IS_XSTAT64
|
||||
# undef __fxstatat64
|
||||
strong_alias (__fxstatat, __fxstatat64);
|
||||
#endif
|
135
sysdeps/unix/sysv/linux/fxstatat64.c
Normal file
135
sysdeps/unix/sysv/linux/fxstatat64.c
Normal file
@ -0,0 +1,135 @@
|
||||
/* Copyright (C) 2005 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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
#include <kernel_stat.h>
|
||||
|
||||
#include <sysdep.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <bp-checks.h>
|
||||
|
||||
#include "kernel-features.h"
|
||||
|
||||
#if __ASSUME_STAT64_SYSCALL == 0
|
||||
# include <xstatconv.h>
|
||||
#endif
|
||||
|
||||
#ifdef __NR_stat64
|
||||
# if __ASSUME_STAT64_SYSCALL == 0
|
||||
/* The variable is shared between all wrappers around *stat64 calls.
|
||||
This is the definition. */
|
||||
extern int __have_no_stat64;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Get information about the file NAME in BUF. */
|
||||
|
||||
int
|
||||
__fxstatat64 (int vers, int fd, const char *file, struct stat64 *st, int flag)
|
||||
{
|
||||
if (flag & ~AT_SYMLINK_NOFOLLOW)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
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;
|
||||
}
|
||||
|
||||
int result;
|
||||
INTERNAL_SYSCALL_DECL (err);
|
||||
|
||||
#if __ASSUME_STAT64_SYSCALL > 0
|
||||
if (flag & AT_SYMLINK_NOFOLLOW)
|
||||
result = INTERNAL_SYSCALL (lstat64, err, 2, CHECK_STRING (file),
|
||||
CHECK_1 (st));
|
||||
else
|
||||
result = INTERNAL_SYSCALL (stat64, err, 2, CHECK_STRING (file),
|
||||
CHECK_1 (st));
|
||||
if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
|
||||
{
|
||||
# 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;
|
||||
}
|
||||
#else
|
||||
struct kernel_stat kst;
|
||||
# if defined __NR_stat64
|
||||
if (! __have_no_stat64)
|
||||
{
|
||||
if (flag & AT_SYMLINK_NOFOLLOW)
|
||||
result = INTERNAL_SYSCALL (lstat64, err, 2, CHECK_STRING (file),
|
||||
CHECK_1 (st));
|
||||
else
|
||||
result = INTERNAL_SYSCALL (stat64, err, 2, CHECK_STRING (file),
|
||||
CHECK_1 (st));
|
||||
|
||||
if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
|
||||
{
|
||||
# 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;
|
||||
}
|
||||
if (INTERNAL_SYSCALL_ERRNO (result, err) != ENOSYS)
|
||||
goto fail;
|
||||
|
||||
__have_no_stat64 = 1;
|
||||
}
|
||||
# endif
|
||||
|
||||
if (flag & AT_SYMLINK_NOFOLLOW)
|
||||
result = INTERNAL_SYSCALL (lstat, err, 2, CHECK_STRING (file),
|
||||
__ptrvalue (&kst));
|
||||
else
|
||||
result = INTERNAL_SYSCALL (stat, err, 2, CHECK_STRING (file),
|
||||
__ptrvalue (&kst));
|
||||
|
||||
if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
|
||||
return __xstat64_conv (vers, &kst, st);
|
||||
|
||||
fail:
|
||||
__atfct_seterrno (INTERNAL_SYSCALL_ERRNO (result, err), fd, buf);
|
||||
|
||||
return -1;
|
||||
#endif
|
||||
}
|
177
sysdeps/unix/sysv/linux/i386/fchownat.c
Normal file
177
sysdeps/unix/sysv/linux/i386/fchownat.c
Normal file
@ -0,0 +1,177 @@
|
||||
/* Copyright (C) 2005 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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <sysdep.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <shlib-compat.h>
|
||||
#include <bp-checks.h>
|
||||
|
||||
#include <linux/posix_types.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.
|
||||
The new lchown function has the same number as the old chown had and the
|
||||
new chown has a new number. When compiling with headers from Linux > 2.1.8x
|
||||
it's impossible to run this libc with older kernels. In these cases libc
|
||||
has therefore to route calls to chown to the old chown function.
|
||||
*/
|
||||
|
||||
extern int __chown_is_lchown (const char *__file, uid_t __owner,
|
||||
gid_t __group);
|
||||
extern int __real_chown (const char *__file, uid_t __owner, gid_t __group);
|
||||
|
||||
|
||||
#if defined __NR_lchown || __ASSUME_LCHOWN_SYSCALL > 0
|
||||
/* Running under Linux > 2.1.80. */
|
||||
|
||||
# ifdef __NR_chown32
|
||||
# if __ASSUME_32BITUIDS == 0
|
||||
/* This variable is shared with all files that need to check for 32bit
|
||||
uids. */
|
||||
extern int __libc_missing_32bit_uids;
|
||||
# endif
|
||||
# endif /* __NR_chown32 */
|
||||
#endif
|
||||
|
||||
|
||||
int
|
||||
fchownat (int fd, const char *file, uid_t owner, gid_t group, int flag)
|
||||
{
|
||||
if (flag & ~AT_SYMLINK_NOFOLLOW)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
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;
|
||||
}
|
||||
|
||||
int result;
|
||||
INTERNAL_SYSCALL_DECL (err);
|
||||
|
||||
#if defined __NR_lchown || __ASSUME_LCHOWN_SYSCALL > 0
|
||||
# if __ASSUME_LCHOWN_SYSCALL == 0
|
||||
static int __libc_old_chown;
|
||||
|
||||
# ifdef __NR_chown32
|
||||
if (__libc_missing_32bit_uids <= 0)
|
||||
{
|
||||
if (flag & AT_SYMLINK_NOFOLLOW)
|
||||
result = INTERNAL_SYSCALL (lchown32, err, 3, CHECK_STRING (file),
|
||||
owner, group);
|
||||
else
|
||||
result = INTERNAL_SYSCALL (chown32, err, 3, CHECK_STRING (file),
|
||||
owner, group);
|
||||
|
||||
if (!INTERNAL_SYSCALL_ERROR_P (result, err))
|
||||
return result;
|
||||
if (INTERNAL_SYSCALL_ERRNO (result, err) != ENOSYS)
|
||||
goto fail;
|
||||
|
||||
__libc_missing_32bit_uids = 1;
|
||||
}
|
||||
# endif /* __NR_chown32 */
|
||||
|
||||
if (((owner + 1) > (uid_t) ((__kernel_uid_t) -1U))
|
||||
|| ((group + 1) > (gid_t) ((__kernel_gid_t) -1U)))
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!__libc_old_chown && (flag & AT_SYMLINK_NOFOLLOW) == 0)
|
||||
{
|
||||
result = INTERNAL_SYSCALL (chown, err, 3, CHECK_STRING (file), owner,
|
||||
group);
|
||||
|
||||
if (!INTERNAL_SYSCALL_ERROR_P (result, err))
|
||||
return result;
|
||||
if (INTERNAL_SYSCALL_ERRNO (result, err) != ENOSYS)
|
||||
goto fail;
|
||||
|
||||
__libc_old_chown = 1;
|
||||
}
|
||||
|
||||
result = INTERNAL_SYSCALL (lchown, err, 3, CHECK_STRING (file), owner,
|
||||
group);
|
||||
# elif __ASSUME_32BITUIDS
|
||||
/* This implies __ASSUME_LCHOWN_SYSCALL. */
|
||||
result = INTERNAL_SYSCALL (chown32, err, 3, CHECK_STRING (file), owner,
|
||||
group);
|
||||
# else
|
||||
/* !__ASSUME_32BITUIDS && ASSUME_LCHOWN_SYSCALL */
|
||||
# ifdef __NR_chown32
|
||||
if (__libc_missing_32bit_uids <= 0)
|
||||
{
|
||||
result = INTERNAL_SYSCALL (chown32, err, 3, CHECK_STRING (file), owner,
|
||||
group);
|
||||
if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
|
||||
return result;
|
||||
if (INTERNAL_SYSCALL_ERRNO (result, err) != ENOSYS)
|
||||
goto fail;
|
||||
|
||||
__libc_missing_32bit_uids = 1;
|
||||
}
|
||||
# endif /* __NR_chown32 */
|
||||
if (((owner + 1) > (uid_t) ((__kernel_uid_t) -1U))
|
||||
|| ((group + 1) > (gid_t) ((__kernel_gid_t) -1U)))
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
result = INTERNAL_SYSCALL (chown, err, 3, CHECK_STRING (file), owner, group);
|
||||
# endif
|
||||
#else
|
||||
result = INTERNAL_SYSCALL (chown, err, 3, CHECK_STRING (file), owner, group);
|
||||
#endif
|
||||
|
||||
if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 0))
|
||||
{
|
||||
fail:
|
||||
__atfct_seterrno (INTERNAL_SYSCALL_ERRNO (result, err), fd, buf);
|
||||
result = -1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
148
sysdeps/unix/sysv/linux/i386/fxstatat.c
Normal file
148
sysdeps/unix/sysv/linux/i386/fxstatat.c
Normal file
@ -0,0 +1,148 @@
|
||||
/* Copyright (C) 2005 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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
/* Ho hum, if fxstatat == fxstatat64 we must get rid of the prototype or gcc
|
||||
will complain since they don't strictly match. */
|
||||
#define __fxstatat64 __fxstatat64_disable
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
#include <kernel_stat.h>
|
||||
|
||||
#include <sysdep.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <bp-checks.h>
|
||||
|
||||
#include "kernel-features.h"
|
||||
|
||||
#include <xstatconv.h>
|
||||
|
||||
#ifdef __NR_stat64
|
||||
# if __ASSUME_STAT64_SYSCALL == 0
|
||||
/* The variable is shared between all wrappers around *stat64 calls. */
|
||||
extern int __have_no_stat64;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
/* Get information about the file NAME relative to FD in ST. */
|
||||
int
|
||||
__fxstatat (int vers, int fd, const char *file, struct stat *st, int flag)
|
||||
{
|
||||
if (flag & ~AT_SYMLINK_NOFOLLOW)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
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 __ASSUME_STAT64_SYSCALL == 0
|
||||
struct kernel_stat kst;
|
||||
#endif
|
||||
int result;
|
||||
INTERNAL_SYSCALL_DECL (err);
|
||||
|
||||
if (vers == _STAT_VER_KERNEL)
|
||||
{
|
||||
if (flag & AT_SYMLINK_NOFOLLOW)
|
||||
result = INTERNAL_SYSCALL (lstat, err, 2, CHECK_STRING (file),
|
||||
CHECK_1 ((struct kernel_stat *) st));
|
||||
else
|
||||
result = INTERNAL_SYSCALL (stat, err, 2, CHECK_STRING (file),
|
||||
CHECK_1 ((struct kernel_stat *) st));
|
||||
goto out;
|
||||
}
|
||||
|
||||
#if __ASSUME_STAT64_SYSCALL > 0
|
||||
struct stat64 st64;
|
||||
|
||||
if (flag & AT_SYMLINK_NOFOLLOW)
|
||||
result = INTERNAL_SYSCALL (lstat64, err, 2, CHECK_STRING (file),
|
||||
__ptrvalue (&st64));
|
||||
else
|
||||
result = INTERNAL_SYSCALL (stat64, err, 2, CHECK_STRING (file),
|
||||
__ptrvalue (&st64));
|
||||
if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
|
||||
return __xstat32_conv (vers, &st64, st);
|
||||
#else
|
||||
# if defined __NR_stat64
|
||||
/* To support 32 bit UIDs, we have to use stat64. The normal stat
|
||||
call only returns 16 bit UIDs. */
|
||||
if (! __have_no_stat64)
|
||||
{
|
||||
struct stat64 st64;
|
||||
|
||||
if (flag & AT_SYMLINK_NOFOLLOW)
|
||||
result = INTERNAL_SYSCALL (lstat64, err, 2, CHECK_STRING (file),
|
||||
__ptrvalue (&st64));
|
||||
else
|
||||
result = INTERNAL_SYSCALL (stat64, err, 2, CHECK_STRING (file),
|
||||
__ptrvalue (&st64));
|
||||
|
||||
if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
|
||||
result = __xstat32_conv (vers, &st64, st);
|
||||
|
||||
if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1)
|
||||
|| INTERNAL_SYSCALL_ERRNO (result, err) != ENOSYS)
|
||||
goto out;
|
||||
|
||||
__have_no_stat64 = 1;
|
||||
}
|
||||
# endif
|
||||
if (flag & AT_SYMLINK_NOFOLLOW)
|
||||
result = INTERNAL_SYSCALL (lstat, err, 2, CHECK_STRING (file),
|
||||
__ptrvalue (&kst));
|
||||
else
|
||||
result = INTERNAL_SYSCALL (stat, err, 2, CHECK_STRING (file),
|
||||
__ptrvalue (&kst));
|
||||
if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
|
||||
return __xstat_conv (vers, &kst, st);
|
||||
#endif /* __ASSUME_STAT64_SYSCALL */
|
||||
|
||||
out:
|
||||
if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 0))
|
||||
__atfct_seterrno (INTERNAL_SYSCALL_ERRNO (result, err), fd, buf);
|
||||
|
||||
return result;
|
||||
}
|
||||
#ifdef XSTAT_IS_XSTAT64
|
||||
# undef __fxstatat64
|
||||
strong_alias (__fxstatat, __fxstatat64);
|
||||
#endif
|
121
sysdeps/unix/sysv/linux/m68k/fchownat.c
Normal file
121
sysdeps/unix/sysv/linux/m68k/fchownat.c
Normal file
@ -0,0 +1,121 @@
|
||||
/* Copyright (C) 2005 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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <sysdep.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <bp-checks.h>
|
||||
|
||||
#include <linux/posix_types.h>
|
||||
#include "kernel-features.h"
|
||||
|
||||
#ifdef __NR_chown32
|
||||
# if __ASSUME_32BITUIDS == 0
|
||||
/* This variable is shared with all files that need to check for 32bit
|
||||
uids. */
|
||||
extern int __libc_missing_32bit_uids;
|
||||
# endif
|
||||
#endif /* __NR_chown32 */
|
||||
|
||||
int
|
||||
fchownat (int fd, const char *file, uid_t owner, gid_t group, int flag)
|
||||
{
|
||||
if (flag & ~AT_SYMLINK_NOFOLLOW)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
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;
|
||||
}
|
||||
|
||||
int result;
|
||||
INTERNAL_SYSCALL_DECL (err);
|
||||
|
||||
#if __ASSUME_32BITUIDS > 0
|
||||
if (flag & AT_SYMLINK_NOFOLLOW)
|
||||
result = INTERNAL_SYSCALL (lchown32, err, 3, CHECK_STRING (file), owner,
|
||||
group);
|
||||
else
|
||||
result = INTERNAL_SYSCALL (chown32, err, 3, CHECK_STRING (file), owner,
|
||||
group);
|
||||
#else
|
||||
# ifdef __NR_chown32
|
||||
if (__libc_missing_32bit_uids <= 0)
|
||||
{
|
||||
if (flag & AT_SYMLINK_NOFOLLOW)
|
||||
result = INTERNAL_SYSCALL (lchown32, err, 3, CHECK_STRING (file),
|
||||
owner, group);
|
||||
else
|
||||
result = INTERNAL_SYSCALL (chown32, err, 3, CHECK_STRING (file), owner,
|
||||
group);
|
||||
|
||||
if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
|
||||
return result;
|
||||
if (INTERNAL_SYSCALL_ERRNO (result, err) != ENOSYS)
|
||||
goto fail;
|
||||
|
||||
__libc_missing_32bit_uids = 1;
|
||||
}
|
||||
# endif /* __NR_chown32 */
|
||||
|
||||
if (((owner + 1) > (gid_t) ((__kernel_uid_t) -1U))
|
||||
|| ((group + 1) > (gid_t) ((__kernel_gid_t) -1U)))
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (flag & AT_SYMLINK_NOFOLLOW)
|
||||
result = INTERNAL_SYSCALL (lchown, err, 3, CHECK_STRING (file), owner,
|
||||
group);
|
||||
else
|
||||
result = INTERNAL_SYSCALL (chown, err, 3, CHECK_STRING (file), owner,
|
||||
group);
|
||||
#endif
|
||||
|
||||
if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 0))
|
||||
{
|
||||
fail:
|
||||
__atfct_seterrno (INTERNAL_SYSCALL_ERRNO (result, err), fd, buf);
|
||||
result = -1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
1
sysdeps/unix/sysv/linux/m68k/fxstatat.c
Normal file
1
sysdeps/unix/sysv/linux/m68k/fxstatat.c
Normal file
@ -0,0 +1 @@
|
||||
#include <sysdeps/unix/sysv/linux/i386/fxstatat.c>
|
@ -29,6 +29,30 @@
|
||||
#ifndef OPENAT
|
||||
# define OPENAT openat
|
||||
# define MORE_OFLAGS 0
|
||||
|
||||
|
||||
void
|
||||
attribute_hidden
|
||||
__atfct_seterrno (int errval, int fd, const char *buf)
|
||||
{
|
||||
if (buf != NULL && errval == ENOTDIR)
|
||||
{
|
||||
/* This can mean either the file descriptor is invalid or
|
||||
/proc is not mounted. */
|
||||
struct stat64 st;
|
||||
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 (S_ISDIR (st.st_mode)
|
||||
&& (__xstat64 (_STAT_VER, "/proc/self/fd", &st) != 0
|
||||
|| !S_ISDIR (st.st_mode)))
|
||||
errval = ENOSYS;
|
||||
}
|
||||
|
||||
__set_errno (errval);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Open FILE with access OFLAG. Interpret relative paths relative to
|
||||
@ -42,7 +66,7 @@ OPENAT (fd, file, oflag)
|
||||
{
|
||||
char *buf = NULL;
|
||||
|
||||
if (file[0] != '/')
|
||||
if (fd != AT_FDCWD && file[0] != '/')
|
||||
{
|
||||
size_t filelen = strlen (file);
|
||||
static const char procfd[] = "/proc/self/fd/%d/%s";
|
||||
@ -85,26 +109,9 @@ OPENAT (fd, file, oflag)
|
||||
|
||||
if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (res, err), 0))
|
||||
{
|
||||
int errval = INTERNAL_SYSCALL_ERRNO (res, err);
|
||||
if (buf != NULL && errval == ENOTDIR)
|
||||
{
|
||||
/* This can mean either the file desriptor is invalid or
|
||||
/proc is not mounted. */
|
||||
struct stat64 st;
|
||||
if (__fxstat64 (_STAT_VER, fd, &st) != 0)
|
||||
/* errno is already set correctly. */
|
||||
goto out;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
__set_errno (errval);
|
||||
__atfct_seterrno (INTERNAL_SYSCALL_ERRNO (res, err), fd, buf);
|
||||
res = -1;
|
||||
}
|
||||
|
||||
out:
|
||||
return res;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* chown() compatibility.
|
||||
Copyright (C) 1998, 2000, 2002, 2003 Free Software Foundation, Inc.
|
||||
Copyright (C) 1998, 2000, 2002, 2003, 2005 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
|
||||
@ -24,6 +24,8 @@
|
||||
#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
|
||||
@ -34,58 +36,61 @@
|
||||
int
|
||||
__chown (const char *file, uid_t owner, gid_t group)
|
||||
{
|
||||
int err;
|
||||
int old_errno;
|
||||
char link[PATH_MAX+2];
|
||||
char path[2*PATH_MAX+4];
|
||||
int loopct;
|
||||
size_t filelen;
|
||||
static int libc_old_chown = 0 /* -1=old linux, 1=new linux, 0=unknown */;
|
||||
#if __ASSUME_LCHOWN_SYSCALL
|
||||
return INLINE_SYSCALL (chown, 3, file, owner, group);
|
||||
#else
|
||||
int err;
|
||||
int old_errno;
|
||||
char link[PATH_MAX + 2];
|
||||
char path[2 * PATH_MAX + 4];
|
||||
int loopct;
|
||||
size_t filelen;
|
||||
static int libc_old_chown = 0 /* -1=old linux, 1=new linux, 0=unknown */;
|
||||
|
||||
if (libc_old_chown == 1)
|
||||
return INLINE_SYSCALL (chown, 3, __ptrvalue (file), owner, group);
|
||||
if (libc_old_chown == 1)
|
||||
return INLINE_SYSCALL (chown, 3, __ptrvalue (file), owner, group);
|
||||
|
||||
old_errno = errno;
|
||||
old_errno = errno;
|
||||
|
||||
#ifdef __NR_lchown
|
||||
if (libc_old_chown == 0)
|
||||
{
|
||||
err = INLINE_SYSCALL (chown, 3, __ptrvalue (file), owner, group);
|
||||
if (err != -1 || errno != ENOSYS)
|
||||
{
|
||||
libc_old_chown = 1;
|
||||
return err;
|
||||
}
|
||||
libc_old_chown = -1;
|
||||
}
|
||||
#endif
|
||||
# ifdef __NR_lchown
|
||||
if (libc_old_chown == 0)
|
||||
{
|
||||
err = INLINE_SYSCALL (chown, 3, __ptrvalue (file), owner, group);
|
||||
if (err != -1 || errno != ENOSYS)
|
||||
{
|
||||
libc_old_chown = 1;
|
||||
return err;
|
||||
}
|
||||
libc_old_chown = -1;
|
||||
}
|
||||
# endif
|
||||
|
||||
err = __readlink (file, link, PATH_MAX+1);
|
||||
if (err == -1)
|
||||
{
|
||||
errno = old_errno;
|
||||
return __lchown(file, owner, group);
|
||||
}
|
||||
err = __readlink (file, link, PATH_MAX + 1);
|
||||
if (err == -1)
|
||||
{
|
||||
__set_errno (old_errno);
|
||||
return __lchown (file, owner, group);
|
||||
}
|
||||
|
||||
filelen = strlen (file) + 1;
|
||||
if (filelen > sizeof(path))
|
||||
{
|
||||
errno = ENAMETOOLONG;
|
||||
return -1;
|
||||
}
|
||||
memcpy (path, file, filelen);
|
||||
filelen = strlen (file) + 1;
|
||||
if (filelen > sizeof (path))
|
||||
{
|
||||
__set_errno (ENAMETOOLONG);
|
||||
return -1;
|
||||
}
|
||||
memcpy (path, file, filelen);
|
||||
|
||||
/* 'The system has an arbitrary limit...' In practise, we'll hit
|
||||
ENAMETOOLONG before this, usually. */
|
||||
for (loopct = 0; loopct < 128; loopct++)
|
||||
{
|
||||
size_t linklen;
|
||||
/* 'The system has an arbitrary limit...' In practise, we'll hit
|
||||
ENAMETOOLONG before this, usually. */
|
||||
for (loopct = 0; loopct < 128; ++loopct)
|
||||
{
|
||||
size_t linklen;
|
||||
|
||||
if (err >= PATH_MAX+1)
|
||||
{
|
||||
errno = ENAMETOOLONG;
|
||||
return -1;
|
||||
}
|
||||
if (err >= PATH_MAX + 1)
|
||||
{
|
||||
__set_errno (ENAMETOOLONG);
|
||||
return -1;
|
||||
}
|
||||
|
||||
link[err] = 0; /* Null-terminate string, just-in-case. */
|
||||
|
||||
@ -97,28 +102,29 @@ __chown (const char *file, uid_t owner, gid_t group)
|
||||
{
|
||||
filelen = strlen (path);
|
||||
|
||||
while (filelen > 1 && path[filelen-1] == '/')
|
||||
filelen--;
|
||||
while (filelen > 0 && path[filelen-1] != '/')
|
||||
filelen--;
|
||||
if (filelen + linklen > sizeof(path))
|
||||
while (filelen > 1 && path[filelen - 1] == '/')
|
||||
--filelen;
|
||||
while (filelen > 0 && path[filelen - 1] != '/')
|
||||
--filelen;
|
||||
if (filelen + linklen > sizeof (path))
|
||||
{
|
||||
errno = ENAMETOOLONG;
|
||||
return -1;
|
||||
}
|
||||
memcpy (path+filelen, link, linklen);
|
||||
memcpy (path + filelen, link, linklen);
|
||||
}
|
||||
|
||||
err = __readlink(path, link, PATH_MAX+1);
|
||||
err = __readlink (path, link, PATH_MAX + 1);
|
||||
|
||||
if (err == -1)
|
||||
{
|
||||
errno = old_errno;
|
||||
return __lchown(path, owner, group);
|
||||
}
|
||||
}
|
||||
errno = ELOOP;
|
||||
return -1;
|
||||
{
|
||||
__set_errno (old_errno);
|
||||
return __lchown (path, owner, group);
|
||||
}
|
||||
}
|
||||
__set_errno (ELOOP);
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
libc_hidden_def (__chown)
|
||||
|
||||
|
205
sysdeps/unix/sysv/linux/powerpc/fchownat.c
Normal file
205
sysdeps/unix/sysv/linux/powerpc/fchownat.c
Normal file
@ -0,0 +1,205 @@
|
||||
/* Copyright (C) 2005 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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#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)
|
||||
{
|
||||
if (flag & ~AT_SYMLINK_NOFOLLOW)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
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;
|
||||
}
|
||||
|
||||
int result;
|
||||
INTERNAL_SYSCALL_DECL (err);
|
||||
|
||||
#if __ASSUME_LCHOWN_SYSCALL
|
||||
if (flag & AT_SYMLINK_NOFOLLOW)
|
||||
result = INTERNAL_SYSCALL (lchown, err, 3, file, owner, group);
|
||||
else
|
||||
result = INTERNAL_SYSCALL (chown, err, 3, file, owner, group);
|
||||
#else
|
||||
char link[PATH_MAX + 2];
|
||||
char path[2 * PATH_MAX + 4];
|
||||
int loopct;
|
||||
size_t filelen;
|
||||
static int libc_old_chown = 0 /* -1=old linux, 1=new linux, 0=unknown */;
|
||||
|
||||
if (libc_old_chown == 1)
|
||||
{
|
||||
if (flag & AT_SYMLINK_NOFOLLOW)
|
||||
result = INTERNAL_SYSCALL (lchown, err, 3, __ptrvalue (file), owner,
|
||||
group);
|
||||
else
|
||||
result = INTERNAL_SYSCALL (chown, err, 3, __ptrvalue (file), owner,
|
||||
group);
|
||||
goto out;
|
||||
}
|
||||
|
||||
# ifdef __NR_lchown
|
||||
if (flag & AT_SYMLINK_NOFOLLOW)
|
||||
{
|
||||
result = INTERNAL_SYSCALL (lchown, err, 3, __ptrvalue (file), owner,
|
||||
group);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (libc_old_chown == 0)
|
||||
{
|
||||
result = INTERNAL_SYSCALL (chown, err, 3, __ptrvalue (file), owner,
|
||||
group);
|
||||
if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
|
||||
return result;
|
||||
if (INTERNAL_SYSCALL_ERRNO (result, err) != ENOSYS)
|
||||
{
|
||||
libc_old_chown = 1;
|
||||
goto fail;
|
||||
}
|
||||
libc_old_chown = -1;
|
||||
}
|
||||
# else
|
||||
if (flag & AT_SYMLINK_NOFOLLOW)
|
||||
{
|
||||
result = INTERNAL_SYSCALL (chown, err, 3, __ptrvalue (file), owner,
|
||||
group);
|
||||
goto out;
|
||||
}
|
||||
# endif
|
||||
|
||||
result = __readlink (file, link, PATH_MAX + 1);
|
||||
if (result == -1)
|
||||
{
|
||||
# ifdef __NR_lchown
|
||||
result = INTERNAL_SYSCALL (lchown, err, 3, __ptrvalue (file), owner,
|
||||
group);
|
||||
# else
|
||||
result = INTERNAL_SYSCALL (chown, err, 3, __ptrvalue (file), owner,
|
||||
group);
|
||||
# endif
|
||||
goto out;
|
||||
}
|
||||
|
||||
filelen = strlen (file) + 1;
|
||||
if (filelen > sizeof (path))
|
||||
{
|
||||
errno = ENAMETOOLONG;
|
||||
return -1;
|
||||
}
|
||||
memcpy (path, file, filelen);
|
||||
|
||||
/* 'The system has an arbitrary limit...' In practise, we'll hit
|
||||
ENAMETOOLONG before this, usually. */
|
||||
for (loopct = 0; loopct < 128; ++loopct)
|
||||
{
|
||||
size_t linklen;
|
||||
|
||||
if (result >= PATH_MAX + 1)
|
||||
{
|
||||
errno = ENAMETOOLONG;
|
||||
return -1;
|
||||
}
|
||||
|
||||
link[result] = 0; /* Null-terminate string, just-in-case. */
|
||||
|
||||
linklen = strlen (link) + 1;
|
||||
|
||||
if (link[0] == '/')
|
||||
memcpy (path, link, linklen);
|
||||
else
|
||||
{
|
||||
filelen = strlen (path);
|
||||
|
||||
while (filelen > 1 && path[filelen - 1] == '/')
|
||||
--filelen;
|
||||
while (filelen > 0 && path[filelen - 1] != '/')
|
||||
--filelen;
|
||||
if (filelen + linklen > sizeof (path))
|
||||
{
|
||||
errno = ENAMETOOLONG;
|
||||
return -1;
|
||||
}
|
||||
memcpy (path + filelen, link, linklen);
|
||||
}
|
||||
|
||||
result = __readlink (path, link, PATH_MAX + 1);
|
||||
|
||||
if (result == -1)
|
||||
{
|
||||
# ifdef __NR_lchown
|
||||
result = INTERNAL_SYSCALL (lchown, err, 3, path, owner, group);
|
||||
# else
|
||||
result = INTERNAL_SYSCALL (chown, err, 3, path, owner, group);
|
||||
# endif
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
__set_errno (ELOOP);
|
||||
return -1;
|
||||
|
||||
out:
|
||||
#endif
|
||||
|
||||
if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 0))
|
||||
{
|
||||
#if !__ASSUME_LCHOWN_SYSCALL
|
||||
fail:
|
||||
#endif
|
||||
__atfct_seterrno (INTERNAL_SYSCALL_ERRNO (result, err), fd, buf);
|
||||
result = -1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
1
sysdeps/unix/sysv/linux/powerpc/powerpc32/fxstatat.c
Normal file
1
sysdeps/unix/sysv/linux/powerpc/powerpc32/fxstatat.c
Normal file
@ -0,0 +1 @@
|
||||
#include <sysdeps/unix/sysv/linux/i386/fxstatat.c>
|
121
sysdeps/unix/sysv/linux/renameat.c
Normal file
121
sysdeps/unix/sysv/linux/renameat.c
Normal file
@ -0,0 +1,121 @@
|
||||
/* Copyright (C) 2005 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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <sysdep.h>
|
||||
|
||||
|
||||
/* Rename the file OLD relative to OLDFD to NEW relative to NEWFD. */
|
||||
int
|
||||
renameat (oldfd, old, newfd, new)
|
||||
int oldfd;
|
||||
const char *old;
|
||||
int newfd;
|
||||
const char *new;
|
||||
{
|
||||
static const char procfd[] = "/proc/self/fd/%d/%s";
|
||||
char *bufold = NULL;
|
||||
|
||||
if (oldfd != AT_FDCWD && old[0] != '/')
|
||||
{
|
||||
size_t filelen = strlen (old);
|
||||
/* 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);
|
||||
/* 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);
|
||||
|
||||
int result = INTERNAL_SYSCALL (rename, err, 2, old, new);
|
||||
|
||||
if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 0))
|
||||
{
|
||||
int errval = INTERNAL_SYSCALL_ERRNO (result, err);
|
||||
if (errval == ENOTDIR && (bufnew != NULL || bufold != NULL))
|
||||
{
|
||||
/* This can mean either the file descriptor is invalid or
|
||||
/proc is not mounted. */
|
||||
struct stat64 st;
|
||||
|
||||
if (bufnew != NULL)
|
||||
{
|
||||
if (__fxstat64 (_STAT_VER, newfd, &st) != 0)
|
||||
/* errno is already set correctly. */
|
||||
return -1;
|
||||
|
||||
/* 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 (bufold != NULL)
|
||||
{
|
||||
if (__fxstat64 (_STAT_VER, oldfd, &st) != 0)
|
||||
/* errno is already set correctly. */
|
||||
return -1;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
__set_errno (errval);
|
||||
result = -1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
140
sysdeps/unix/sysv/linux/s390/s390-32/fchownat.c
Normal file
140
sysdeps/unix/sysv/linux/s390/s390-32/fchownat.c
Normal file
@ -0,0 +1,140 @@
|
||||
/* Copyright (C) 2005 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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <sysdep.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <shlib-compat.h>
|
||||
#include <bp-checks.h>
|
||||
|
||||
#include <linux/posix_types.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.
|
||||
The new lchown function has the same number as the old chown had and the
|
||||
new chown has a new number. When compiling with headers from Linux > 2.1.8x
|
||||
it's impossible to run this libc with older kernels. In these cases libc
|
||||
has therefore to route calls to chown to the old chown function.
|
||||
*/
|
||||
|
||||
/* Running under Linux > 2.1.80. */
|
||||
|
||||
#ifdef __NR_chown32
|
||||
# if __ASSUME_32BITUIDS == 0
|
||||
/* This variable is shared with all files that need to check for 32bit
|
||||
uids. */
|
||||
extern int __libc_missing_32bit_uids;
|
||||
# endif
|
||||
#endif /* __NR_chown32 */
|
||||
|
||||
int
|
||||
fchownat (int fd, const char *file, uid_t owner, gid_t group, int flag)
|
||||
{
|
||||
if (flag & ~AT_SYMLINK_NOFOLLOW)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
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;
|
||||
}
|
||||
|
||||
int result;
|
||||
INTERNAL_SYSCALL_DECL (err);
|
||||
|
||||
#if __ASSUME_32BITUIDS > 0
|
||||
result = INTERNAL_SYSCALL (chown32, err, 3, CHECK_STRING (file), owner,
|
||||
group);
|
||||
#else
|
||||
static int __libc_old_chown;
|
||||
|
||||
# ifdef __NR_chown32
|
||||
if (__libc_missing_32bit_uids <= 0)
|
||||
{
|
||||
if (flag & AT_SYMLINK_NOFOLLOW)
|
||||
result = INTERNAL_SYSCALL (lchown32, err, 3, CHECK_STRING (file),
|
||||
owner, group);
|
||||
else
|
||||
result = INTERNAL_SYSCALL (chown32, err, 3, CHECK_STRING (file),
|
||||
owner, group);
|
||||
|
||||
if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
|
||||
return result;
|
||||
if (INTERNAL_SYSCALL_ERRNO (result, err) != ENOSYS)
|
||||
goto fail;
|
||||
|
||||
__libc_missing_32bit_uids = 1;
|
||||
}
|
||||
# endif /* __NR_chown32 */
|
||||
if (((owner + 1) > (uid_t) ((__kernel_uid_t) -1U))
|
||||
|| ((group + 1) > (gid_t) ((__kernel_gid_t) -1U)))
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!__libc_old_chown && (flag & AT_SYMLINK_NOFOLLOW) == 0)
|
||||
{
|
||||
result = INTERNAL_SYSCALL (chown, err, 3, CHECK_STRING (file), owner,
|
||||
group);
|
||||
|
||||
if (!INTERNAL_SYSCALL_ERROR_P (result, err))
|
||||
return result;
|
||||
if (INTERNAL_SYSCALL_ERRNO (result, err) != ENOSYS)
|
||||
goto fail;
|
||||
|
||||
__libc_old_chown = 1;
|
||||
}
|
||||
|
||||
result = INTERNAL_SYSCALL (lchown, err, 3, CHECK_STRING (file), owner,
|
||||
group);
|
||||
#endif
|
||||
|
||||
if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 0))
|
||||
{
|
||||
fail:
|
||||
__atfct_seterrno (INTERNAL_SYSCALL_ERRNO (result, err), fd, buf);
|
||||
result = -1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
1
sysdeps/unix/sysv/linux/s390/s390-32/fxstatat.c
Normal file
1
sysdeps/unix/sysv/linux/s390/s390-32/fxstatat.c
Normal file
@ -0,0 +1 @@
|
||||
#include <sysdeps/unix/sysv/linux/i386/fxstatat.c>
|
1
sysdeps/unix/sysv/linux/sh/fchownat.c
Normal file
1
sysdeps/unix/sysv/linux/sh/fchownat.c
Normal file
@ -0,0 +1 @@
|
||||
#include <sysdeps/unix/sysv/linux/m68k/fchownat.c>
|
1
sysdeps/unix/sysv/linux/sh/fxstatat.c
Normal file
1
sysdeps/unix/sysv/linux/sh/fxstatat.c
Normal file
@ -0,0 +1 @@
|
||||
#include <sysdeps/unix/sysv/linux/i386/fxstatat.c>
|
1
sysdeps/unix/sysv/linux/sparc/sparc32/fchownat.c
Normal file
1
sysdeps/unix/sysv/linux/sparc/sparc32/fchownat.c
Normal file
@ -0,0 +1 @@
|
||||
#include <sysdeps/unix/sysv/linux/m68k/fchownat.c>
|
1
sysdeps/unix/sysv/linux/sparc/sparc32/fxstatat.c
Normal file
1
sysdeps/unix/sysv/linux/sparc/sparc32/fxstatat.c
Normal file
@ -0,0 +1 @@
|
||||
#include <sysdeps/unix/sysv/linux/i386/fxstatat.c>
|
1
sysdeps/unix/sysv/linux/sparc/sparc64/fxstatat.c
Normal file
1
sysdeps/unix/sysv/linux/sparc/sparc64/fxstatat.c
Normal file
@ -0,0 +1 @@
|
||||
#include "../../fxstatat.c"
|
74
sysdeps/unix/sysv/linux/unlinkat.c
Normal file
74
sysdeps/unix/sysv/linux/unlinkat.c
Normal file
@ -0,0 +1,74 @@
|
||||
/* Copyright (C) 2005 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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
/* Remove the link named NAME. */
|
||||
int
|
||||
unlinkat (fd, file, flag)
|
||||
int fd;
|
||||
const char *file;
|
||||
int flag;
|
||||
{
|
||||
if (flag & ~AT_REMOVEDIR)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
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;
|
||||
}
|
||||
|
||||
int result;
|
||||
INTERNAL_SYSCALL_DECL (err);
|
||||
|
||||
if (flag & AT_REMOVEDIR)
|
||||
result = INTERNAL_SYSCALL (rmdir, err, 1, file);
|
||||
else
|
||||
result = INTERNAL_SYSCALL (unlink, err, 1, file);
|
||||
|
||||
if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 0))
|
||||
{
|
||||
__atfct_seterrno (INTERNAL_SYSCALL_ERRNO (result, err), fd, buf);
|
||||
result = -1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
78
sysdeps/unix/sysv/linux/wordsize-64/fxstatat.c
Normal file
78
sysdeps/unix/sysv/linux/wordsize-64/fxstatat.c
Normal file
@ -0,0 +1,78 @@
|
||||
/* Copyright (C) 2005 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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
/* Ho hum, since fxstatat == fxstatat64 we must get rid of the
|
||||
prototype or gcc will complain since they don't strictly match. */
|
||||
#define __fxstatat64 __fxstatat64_disable
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <sysdep.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <bp-checks.h>
|
||||
|
||||
/* Get information about the file NAME relative to FD in ST. */
|
||||
int
|
||||
__fxstatat (int vers, int fd, const char *file, struct stat *st, int flag)
|
||||
{
|
||||
if ((vers != _STAT_VER_KERNEL && vers != _STAT_VER_LINUX)
|
||||
|| (flag & ~AT_SYMLINK_NOFOLLOW) != 0)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
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;
|
||||
}
|
||||
|
||||
INTERNAL_SYSCALL_DECL (err);
|
||||
int res;
|
||||
|
||||
if (flag & AT_SYMLINK_NOFOLLOW)
|
||||
res = INTERNAL_SYSCALL (lstat, err, 2, file, CHECK_1 (st));
|
||||
else
|
||||
res = INTERNAL_SYSCALL (stat, err, 2, file, CHECK_1 (st));
|
||||
|
||||
if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (res, err), 0))
|
||||
__atfct_seterrno (INTERNAL_SYSCALL_ERRNO (res, err), fd, buf);
|
||||
|
||||
return res;
|
||||
}
|
||||
#undef __fxstatat64
|
||||
strong_alias (__fxstatat, __fxstatat64);
|
1
sysdeps/unix/sysv/linux/wordsize-64/fxstatat64.c
Normal file
1
sysdeps/unix/sysv/linux/wordsize-64/fxstatat64.c
Normal file
@ -0,0 +1 @@
|
||||
/* fxstatat64 is in fxstatat.c */
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1991-1994,1996-2002,2003 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1991-1994,1996-2002,2003,2005 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
|
||||
@ -70,13 +70,14 @@ typedef void *__restrict __timezone_ptr_t;
|
||||
NOTE: This form of timezone information is obsolete.
|
||||
Use the functions and variables declared in <time.h> instead. */
|
||||
extern int gettimeofday (struct timeval *__restrict __tv,
|
||||
__timezone_ptr_t __tz) __THROW;
|
||||
__timezone_ptr_t __tz) __THROW __nonnull ((1));
|
||||
|
||||
#ifdef __USE_BSD
|
||||
/* Set the current time of day and timezone information.
|
||||
This call is restricted to the super-user. */
|
||||
extern int settimeofday (__const struct timeval *__tv,
|
||||
__const struct timezone *__tz) __THROW;
|
||||
__const struct timezone *__tz)
|
||||
__THROW __nonnull ((1));
|
||||
|
||||
/* Adjust the current time of day by the amount in DELTA.
|
||||
If OLDDELTA is not NULL, it is filled in with the amount
|
||||
@ -136,17 +137,25 @@ extern int setitimer (__itimer_which_t __which,
|
||||
FILE to TVP[1]. If TVP is a null pointer, use the current time instead.
|
||||
Returns 0 on success, -1 on errors. */
|
||||
extern int utimes (__const char *__file, __const struct timeval __tvp[2])
|
||||
__THROW;
|
||||
__THROW __nonnull ((1));
|
||||
|
||||
#ifdef __USE_BSD
|
||||
/* Same as `utimes', but does not follow symbolic links. */
|
||||
extern int lutimes (__const char *__file, __const struct timeval __tvp[2])
|
||||
__THROW;
|
||||
__THROW __nonnull ((1));
|
||||
|
||||
/* Same as `utimes', but takes an open file descriptor instead of a name. */
|
||||
extern int futimes (int __fd, __const struct timeval __tvp[2]) __THROW;
|
||||
#endif
|
||||
|
||||
#ifdef __USE_GNU
|
||||
/* Change the access time of FILE relative to FD to TVP[0] and the
|
||||
modification time of FILE to TVP[1]. If TVP is a null pointer, use
|
||||
the current time instead. Returns 0 on success, -1 on errors. */
|
||||
extern int futimesat (int __fd, __const char *__file,
|
||||
__const struct timeval __tvp[2]) __THROW __nonnull ((2));
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __USE_BSD
|
||||
/* Convenience macros for operations on timevals.
|
||||
|
Loading…
Reference in New Issue
Block a user