2006-02-12  Ulrich Drepper  <drepper@redhat.com>
	* io/ftw.c: Start using *at functions.
	* io/ftw64.c: Likewise.

	* sysdeps/generic/not-cancel.h: Define openat_not_cancel,
	openat_not_cancel_3, openat64_not_cancel, and openat64_not_cancel_3.
	* sysdeps/unix/sysv/linux/not-cancel.h: Likewise.

	* sysdeps/unix/sysv/linux/openat.c: Create separate _nocancel
	functions.

	* io/fxstatat.c: Add __fxstatat alias.
	* sysdeps/unix/sysv/linux/wordsize-64/fxstatat.c: Likewise.
	* sysdeps/unix/sysv/linux/fxstatat.c: Likewise.  Add support for
	newfstatat syscall.
	* sysdeps/unix/sysv/linux/i386/fxstatat.c: Add __fxstatat alias.
	Add support for fstatat64 syscall.
	* include/sys/stat.h: Declare __fxstatat.
	* io/fxstatat64.c: Add __fxstatat64 alias.
	* sysdeps/unix/sysv/linux/fxstatat64.c: Add support for fstatat64
	syscall.

	* dirent/fdopendir.c: Add __fdopendir alias.
	* sysdeps/unix/fdopendir.c: Likewise.
	* sysdeps/mach/hurd/fdopendir.c: Likewise.
	* include/dirent.h: Add __fdopendir declaration.

	[BZ #2226]
	* libio/wgenops.c (_IO_wsetb): Use correct size of wide char
	buffer in FREE_BUF call.
This commit is contained in:
Ulrich Drepper 2006-02-12 21:41:44 +00:00
parent e32f487e1c
commit d369ad760d
19 changed files with 308 additions and 97 deletions

View file

@ -1,3 +1,35 @@
2006-02-12 Ulrich Drepper <drepper@redhat.com>
* io/ftw.c: Start using *at functions.
* io/ftw64.c: Likewise.
* sysdeps/generic/not-cancel.h: Define openat_not_cancel,
openat_not_cancel_3, openat64_not_cancel, and openat64_not_cancel_3.
* sysdeps/unix/sysv/linux/not-cancel.h: Likewise.
* sysdeps/unix/sysv/linux/openat.c: Create separate _nocancel
functions.
* io/fxstatat.c: Add __fxstatat alias.
* sysdeps/unix/sysv/linux/wordsize-64/fxstatat.c: Likewise.
* sysdeps/unix/sysv/linux/fxstatat.c: Likewise. Add support for
newfstatat syscall.
* sysdeps/unix/sysv/linux/i386/fxstatat.c: Add __fxstatat alias.
Add support for fstatat64 syscall.
* include/sys/stat.h: Declare __fxstatat.
* io/fxstatat64.c: Add __fxstatat64 alias.
* sysdeps/unix/sysv/linux/fxstatat64.c: Add support for fstatat64
syscall.
* dirent/fdopendir.c: Add __fdopendir alias.
* sysdeps/unix/fdopendir.c: Likewise.
* sysdeps/mach/hurd/fdopendir.c: Likewise.
* include/dirent.h: Add __fdopendir declaration.
[BZ #2226]
* libio/wgenops.c (_IO_wsetb): Use correct size of wide char
buffer in FREE_BUF call.
2006-02-08 Ulrich Drepper <drepper@redhat.com>
* sysdeps/unix/sysv/linux/bits/sched.h: Declare unshare.

View file

@ -1,5 +1,5 @@
/* Open a directory stream from a file descriptor. Stub version.
Copyright (C) 2005 Free Software Foundation, Inc.
Copyright (C) 2005, 2006 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,11 +24,12 @@
/* Open a directory stream on FD. */
DIR *
fdopendir (int fd)
__fdopendir (int fd)
{
__set_errno (ENOSYS);
return NULL;
}
weak_alias (__fdopendir, fdopendir)
stub_warning (fdopendir)
#include <stub-tag.h>

View file

@ -6,6 +6,7 @@
/* Now define the internal interfaces. */
extern DIR *__opendir (__const char *__name);
extern DIR *__fdopendir (int __fd);
extern int __closedir (DIR *__dirp);
extern struct dirent *__readdir (DIR *__dirp);
extern struct dirent64 *__readdir64 (DIR *__dirp);
@ -27,4 +28,5 @@ extern int __versionsort64 (const void *a, const void *b)
__attribute_pure__;
extern DIR *__alloc_dir (int fd, bool close_fd, const struct stat64 *statp)
internal_function;
#endif

View file

@ -31,6 +31,7 @@ extern __inline__ int __mknod (__const char *__path, __mode_t __mode,
}
libc_hidden_proto (__xmknodat)
libc_hidden_proto (__fxstatat)
libc_hidden_proto (__fxstatat64)

View file

@ -66,6 +66,7 @@ char *alloca ();
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <not-cancel.h>
#if HAVE_SYS_PARAM_H || defined _LIBC
# include <sys/param.h>
#endif
@ -143,9 +144,11 @@ int rpl_lstat (const char *, struct stat *);
# ifdef _LIBC
# define LXSTAT __lxstat
# define XSTAT __xstat
# define FXSTATAT __fxstatat
# else
# define LXSTAT(V,f,sb) lstat (f,sb)
# define XSTAT(V,f,sb) stat (f,sb)
# define FXSTATAT(V,d,f,sb,m) fstatat (d, f, sb, m)
# endif
# define FTW_FUNC_T __ftw_func_t
# define NFTW_FUNC_T __nftw_func_t
@ -162,6 +165,7 @@ int rpl_lstat (const char *, struct stat *);
struct dir_data
{
DIR *stream;
int streamfd;
char *content;
};
@ -263,7 +267,7 @@ find_object (struct ftw_data *data, struct STAT *st)
static inline int
__attribute ((always_inline))
open_dir_stream (struct ftw_data *data, struct dir_data *dirp)
open_dir_stream (int *dfdp, struct ftw_data *data, struct dir_data *dirp)
{
int result = 0;
@ -324,6 +328,7 @@ open_dir_stream (struct ftw_data *data, struct dir_data *dirp)
{
__closedir (st);
data->dirstreams[data->actdir]->stream = NULL;
data->dirstreams[data->actdir]->streamfd = -1;
data->dirstreams[data->actdir] = NULL;
}
}
@ -332,15 +337,28 @@ open_dir_stream (struct ftw_data *data, struct dir_data *dirp)
/* Open the new stream. */
if (result == 0)
{
const char *name = ((data->flags & FTW_CHDIR)
? data->dirbuf + data->ftw.base: data->dirbuf);
assert (data->dirstreams[data->actdir] == NULL);
dirp->stream = __opendir (name);
if (dfdp != NULL && *dfdp != -1)
{
int fd = openat64_not_cancel_3 (*dfdp, data->dirbuf + data->ftw.base,
O_RDONLY | O_DIRECTORY | O_NDELAY);
dirp->stream = NULL;
if (fd != -1 && (dirp->stream = __fdopendir (fd)) == NULL)
close_not_cancel_no_status (fd);
}
else
{
const char *name = ((data->flags & FTW_CHDIR)
? data->dirbuf + data->ftw.base: data->dirbuf);
dirp->stream = __opendir (name);
}
if (dirp->stream == NULL)
result = -1;
else
{
dirp->streamfd = dirfd (dirp->stream);
dirp->content = NULL;
data->dirstreams[data->actdir] = dirp;
@ -356,7 +374,7 @@ open_dir_stream (struct ftw_data *data, struct dir_data *dirp)
static int
internal_function
process_entry (struct ftw_data *data, struct dir_data *dir, const char *name,
size_t namlen)
size_t namlen, int d_type)
{
struct STAT st;
int result = 0;
@ -383,18 +401,28 @@ process_entry (struct ftw_data *data, struct dir_data *dir, const char *name,
*((char *) __mempcpy (data->dirbuf + data->ftw.base, name, namlen)) = '\0';
if ((data->flags & FTW_CHDIR) == 0)
name = data->dirbuf;
int statres;
if (dir->streamfd != -1)
statres = FXSTATAT (_STAT_VER, dir->streamfd, name, &st,
(data->flags & FTW_PHYS) ? AT_SYMLINK_NOFOLLOW : 0);
else
{
if ((data->flags & FTW_CHDIR) == 0)
name = data->dirbuf;
if (((data->flags & FTW_PHYS)
? LXSTAT (_STAT_VER, name, &st)
: XSTAT (_STAT_VER, name, &st)) < 0)
statres = ((data->flags & FTW_PHYS)
? LXSTAT (_STAT_VER, name, &st)
: XSTAT (_STAT_VER, name, &st));
}
if (statres < 0)
{
if (errno != EACCES && errno != ENOENT)
result = -1;
else if (!(data->flags & FTW_PHYS)
&& LXSTAT (_STAT_VER, name, &st) == 0
&& S_ISLNK (st.st_mode))
&& (d_type == DT_LNK
|| (LXSTAT (_STAT_VER, name, &st) == 0
&& S_ISLNK (st.st_mode))))
flag = FTW_SLN;
else
flag = FTW_NS;
@ -446,7 +474,8 @@ ftw_dir (struct ftw_data *data, struct STAT *st, struct dir_data *old_dir)
/* Open the stream for this directory. This might require that
another stream has to be closed. */
result = open_dir_stream (data, &dir);
result = open_dir_stream (old_dir == NULL ? NULL : &old_dir->streamfd,
data, &dir);
if (result != 0)
{
if (errno == EACCES)
@ -466,6 +495,7 @@ ftw_dir (struct ftw_data *data, struct STAT *st, struct dir_data *old_dir)
fail:
save_err = errno;
__closedir (dir.stream);
dir.streamfd = -1;
__set_errno (save_err);
if (data->actdir-- == 0)
@ -496,7 +526,7 @@ fail:
while (dir.stream != NULL && (d = __readdir64 (dir.stream)) != NULL)
{
result = process_entry (data, &dir, d->d_name, NAMLEN (d));
result = process_entry (data, &dir, d->d_name, NAMLEN (d), d->d_type);
if (result != 0)
break;
}
@ -510,6 +540,7 @@ fail:
assert (dir.content == NULL);
__closedir (dir.stream);
dir.streamfd = -1;
__set_errno (save_err);
if (data->actdir-- == 0)
@ -525,7 +556,8 @@ fail:
{
char *endp = strchr (runp, '\0');
result = process_entry (data, &dir, runp, endp - runp);
// XXX Should store the d_type values as well?!
result = process_entry (data, &dir, runp, endp - runp, DT_UNKNOWN);
runp = endp + 1;
}

View file

@ -1,5 +1,5 @@
/* File tree walker functions. LFS version.
Copyright (C) 1996, 1997, 1998, 2001 Free Software Foundation, Inc.
Copyright (C) 1996, 1997, 1998, 2001, 2006 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
@ -26,6 +26,7 @@
#define STAT stat64
#define LXSTAT __lxstat64
#define XSTAT __xstat64
#define FXSTATAT __fxstatat64
#define FTW_FUNC_T __ftw64_func_t
#define NFTW_FUNC_T __nftw64_func_t

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2005 Free Software Foundation, Inc.
/* Copyright (C) 2005, 2006 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
@ -45,5 +45,6 @@ __fxstatat (int vers, int fd, const char *filename, struct stat *buf, int flag)
__set_errno (ENOSYS);
return -1;
}
libc_hidden_def (__fxstatat)
stub_warning (fstatat)
#include <stub-tag.h>

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2005 Free Software Foundation, Inc.
/* Copyright (C) 2005, 2006 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
@ -46,5 +46,6 @@ __fxstatat64 (int vers, int fd, const char *filename, struct stat64 *buf,
__set_errno (ENOSYS);
return -1;
}
libc_hidden_def (__fxstatat64)
stub_warning (fstatat64)
#include <stub-tag.h>

View file

@ -1,4 +1,4 @@
/* Copyright (C) 1993,1995,1997-2001,2002,2004 Free Software Foundation, Inc.
/* Copyright (C) 1993,1995,1997-2002,2004,2006 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Ulrich Drepper <drepper@cygnus.com>.
Based on the single byte version by Per Bothner <bothner@cygnus.com>.
@ -116,7 +116,7 @@ _IO_wsetb (f, b, eb, a)
int a;
{
if (f->_wide_data->_IO_buf_base && !(f->_flags & _IO_USER_BUF))
FREE_BUF (f->_wide_data->_IO_buf_base, _IO_wblen (f));
FREE_BUF (f->_wide_data->_IO_buf_base, _IO_wblen (f) * sizeof (wchar_t));
f->_wide_data->_IO_buf_base = b;
f->_wide_data->_IO_buf_end = eb;
if (a)

View file

@ -1,5 +1,5 @@
/* Uncancelable versions of cancelable interfaces. Linux/NPTL version.
Copyright (C) 2003 Free Software Foundation, Inc.
Copyright (C) 2003, 2006 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
@ -26,13 +26,21 @@ extern int __close_nocancel (int) attribute_hidden;
extern int __read_nocancel (int, void *, size_t) attribute_hidden;
extern int __write_nocancel (int, const void *, size_t) attribute_hidden;
extern pid_t __waitpid_nocancel (pid_t, int *, int) attribute_hidden;
extern int __openat_nocancel (int fd, const char *fname, int oflag,
mode_t mode) attribute_hidden;
extern int __openat64_nocancel (int fd, const char *fname, int oflag,
mode_t mode) attribute_hidden;
#else
#define __open_nocancel(name, ...) __open (name, __VA_ARGS__)
#define __close_nocancel(fd) __close (fd)
#define __read_nocancel(fd, buf, len) __read (fd, buf, len)
#define __write_nocancel(fd, buf, len) __write (fd, buf, len)
#define __waitpid_nocancel(pid, stat_loc, options) \
# define __open_nocancel(name, ...) __open (name, __VA_ARGS__)
# define __close_nocancel(fd) __close (fd)
# define __read_nocancel(fd, buf, len) __read (fd, buf, len)
# define __write_nocancel(fd, buf, len) __write (fd, buf, len)
# define __waitpid_nocancel(pid, stat_loc, options) \
__waitpid (pid, stat_loc, options)
# define __openat_nocancel(fd, fname, oflag, mode) \
openat (fd, fname, oflag, mode)
# define __openat64_nocancel(fd, fname, oflag, mode) \
openat64 (fd, fname, oflag, mode)
#endif
/* Uncancelable open. */
@ -41,6 +49,16 @@ extern pid_t __waitpid_nocancel (pid_t, int *, int) attribute_hidden;
#define open_not_cancel_2(name, flags) \
__open_nocancel (name, flags)
/* Uncancelable openat. */
#define openat_not_cancel(fd, fname, oflag, mode) \
__openat_nocancel (fd, fname, oflag, mode)
#define openat_not_cancel_3(fd, fname, oflag) \
__openat_nocancel (fd, fname, oflag, 0)
#define openat64_not_cancel(fd, fname, oflag, mode) \
__openat64_nocancel (fd, fname, oflag, mode)
#define openat64_not_cancel_3(fd, fname, oflag) \
__openat64_nocancel (fd, fname, oflag, 0)
/* Uncancelable close. */
#define close_not_cancel(fd) \
__close_nocancel (fd)

View file

@ -1,5 +1,5 @@
/* Uncancelable versions of cancelable interfaces. Generic version.
Copyright (C) 2003 Free Software Foundation, Inc.
Copyright (C) 2003, 2006 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
@ -23,6 +23,14 @@
__libc_open (name, flags, mode)
#define open_not_cancel_2(name, flags) \
__libc_open (name, flags)
#define openat_not_cancel(fd, name, flags, mode) \
__openat (fd, name, flags, mode)
#define openat_not_cancel_3(fd, name, flags) \
__openat (fd, name, flags, 0)
#define openat64_not_cancel(fd, name, flags, mode) \
__openat64 (fd, name, flags, mode)
#define openat64_not_cancel_3(fd, name, flags) \
__openat64 (fd, name, flags, 0)
#define close_not_cancel(fd) \
__close (fd)
#define close_not_cancel_no_status(fd) \

View file

@ -1,5 +1,5 @@
/* Open a directory stream from a file descriptor. Hurd version.
Copyright (C) 2005 Free Software Foundation, Inc.
Copyright (C) 2005, 2006 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
@ -27,7 +27,7 @@ DIR *_hurd_fd_opendir (struct hurd_fd *d); /* opendir.c */
/* Open a directory stream on FD. */
DIR *
fdopendir (int fd)
__fdopendir (int fd)
{
struct hurd_fd *d = _hurd_fd_get (fd);
@ -54,3 +54,4 @@ fdopendir (int fd)
return _hurd_fd_opendir (d);
}
weak_alias (__fdopendir, fdopendir)

View file

@ -25,7 +25,7 @@
DIR *
fdopendir (int fd)
__fdopendir (int fd)
{
struct stat64 statbuf;
@ -49,3 +49,4 @@ fdopendir (int fd)
return __alloc_dir (fd, false, &statbuf);
}
weak_alias (__fdopendir, fdopendir)

View file

@ -37,6 +37,42 @@
int
__fxstatat (int vers, int fd, const char *file, struct stat *st, int flag)
{
int result;
INTERNAL_SYSCALL_DECL (err);
#ifdef STAT_IS_KERNEL_STAT
# define kst (*st)
#else
struct kernel_stat kst;
#endif
#ifdef __NR_newfstatat
# ifndef __ASSUME_ATFCTS
if (__have_atfcts >= 0)
# endif
{
result = INTERNAL_SYSCALL (newfstatat, err, 4, fd, file, &kst, flag);
# ifndef __ASSUME_ATFCTS
if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 1)
&& INTERNAL_SYSCALL_ERRNO (result, err) == ENOSYS)
__have_atfcts = -1;
else
# endif
if (!__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 1))
{
#ifdef STAT_IS_KERNEL_STAT
return 0;
#else
return __xstat_conv (vers, &kst, st);
#endif
}
else
{
__set_errno (INTERNAL_SYSCALL_ERRNO (result, err));
return -1;
}
}
#endif
if (flag & ~AT_SYMLINK_NOFOLLOW)
{
__set_errno (EINVAL);
@ -63,9 +99,6 @@ __fxstatat (int vers, int fd, const char *file, struct stat *st, int flag)
file = buf;
}
int result;
INTERNAL_SYSCALL_DECL (err);
if (vers == _STAT_VER_KERNEL)
{
if (flag & AT_SYMLINK_NOFOLLOW)
@ -85,8 +118,6 @@ __fxstatat (int vers, int fd, const char *file, struct stat *st, int flag)
return -1;
}
#else
struct kernel_stat kst;
if (flag & AT_SYMLINK_NOFOLLOW)
result = INTERNAL_SYSCALL (lstat, err, 2, CHECK_STRING (file),
__ptrvalue (&kst));
@ -102,8 +133,9 @@ __fxstatat (int vers, int fd, const char *file, struct stat *st, int flag)
return -1;
}
libc_hidden_def (__fxstatat)
#ifdef XSTAT_IS_XSTAT64
# undef __fxstatat64
strong_alias (__fxstatat, __fxstatat64);
libc_hidden_ver (__fxstatat, __fxstatat64)
libc_hidden_def (__fxstatat64)
#endif

View file

@ -47,6 +47,38 @@ extern int __have_no_stat64;
int
__fxstatat64 (int vers, int fd, const char *file, struct stat64 *st, int flag)
{
if (__builtin_expect (vers != _STAT_VER_LINUX, 0))
{
__set_errno (EINVAL);
return -1;
}
int result;
INTERNAL_SYSCALL_DECL (err);
#ifdef __NR_fstatat64
# ifndef __ASSUME_ATFCTS
if (__have_atfcts >= 0)
# endif
{
result = INTERNAL_SYSCALL (fstatat64, err, 4, fd, file, st, flag);
# ifndef __ASSUME_ATFCTS
if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 1)
&& INTERNAL_SYSCALL_ERRNO (result, err) == ENOSYS)
__have_atfcts = -1;
else
# endif
if (!__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 1))
return 0;
else
{
__set_errno (INTERNAL_SYSCALL_ERRNO (result, err));
return -1;
}
}
#endif
#ifndef __ASSUME_ATFCTS
if (flag & ~AT_SYMLINK_NOFOLLOW)
{
__set_errno (EINVAL);
@ -73,10 +105,7 @@ __fxstatat64 (int vers, int fd, const char *file, struct stat64 *st, int flag)
file = buf;
}
int result;
INTERNAL_SYSCALL_DECL (err);
#if __ASSUME_STAT64_SYSCALL > 0
# if __ASSUME_STAT64_SYSCALL > 0
if (flag & AT_SYMLINK_NOFOLLOW)
result = INTERNAL_SYSCALL (lstat64, err, 2, CHECK_STRING (file),
CHECK_1 (st));
@ -85,15 +114,15 @@ __fxstatat64 (int vers, int fd, const char *file, struct stat64 *st, int flag)
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 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
# endif
return result;
}
#else
# else
struct kernel_stat kst;
# if defined __NR_stat64
# ifdef __NR_stat64
if (! __have_no_stat64)
{
if (flag & AT_SYMLINK_NOFOLLOW)
@ -105,10 +134,10 @@ __fxstatat64 (int vers, int fd, const char *file, struct stat64 *st, int flag)
if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
{
# if defined _HAVE_STAT64___ST_INO && __ASSUME_ST_INO_64_BIT == 0
# 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
# endif
return result;
}
if (INTERNAL_SYSCALL_ERRNO (result, err) != ENOSYS)
@ -116,7 +145,7 @@ __fxstatat64 (int vers, int fd, const char *file, struct stat64 *st, int flag)
__have_no_stat64 = 1;
}
# endif
# endif
if (flag & AT_SYMLINK_NOFOLLOW)
result = INTERNAL_SYSCALL (lstat, err, 2, CHECK_STRING (file),
@ -129,9 +158,10 @@ __fxstatat64 (int vers, int fd, const char *file, struct stat64 *st, int flag)
return __xstat64_conv (vers, &kst, st);
fail:
#endif
# endif
__atfct_seterrno (INTERNAL_SYSCALL_ERRNO (result, err), fd, buf);
return -1;
#endif
}
libc_hidden_def (__fxstatat64)

View file

@ -48,6 +48,33 @@ extern int __have_no_stat64;
int
__fxstatat (int vers, int fd, const char *file, struct stat *st, int flag)
{
int result;
INTERNAL_SYSCALL_DECL (err);
struct stat64 st64;
#ifdef __NR_fstatat64
# ifndef __ASSUME_ATFCTS
if (__have_atfcts >= 0)
# endif
{
result = INTERNAL_SYSCALL (fstatat64, err, 4, fd, file, &st64, flag);
# ifndef __ASSUME_ATFCTS
if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 1)
&& INTERNAL_SYSCALL_ERRNO (result, err) == ENOSYS)
__have_atfcts = -1;
else
# endif
if (!__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 1))
return __xstat32_conv (vers, &st64, st);
else
{
__set_errno (INTERNAL_SYSCALL_ERRNO (result, err));
return -1;
}
}
#endif
#ifndef __ASSUME_ATFCTS
if (__builtin_expect (flag & ~AT_SYMLINK_NOFOLLOW, 0))
{
__set_errno (EINVAL);
@ -74,12 +101,9 @@ __fxstatat (int vers, int fd, const char *file, struct stat *st, int flag)
file = buf;
}
#if __ASSUME_STAT64_SYSCALL == 0
# if __ASSUME_STAT64_SYSCALL == 0
struct kernel_stat kst;
#endif
int result;
INTERNAL_SYSCALL_DECL (err);
# endif
if (vers == _STAT_VER_KERNEL)
{
if (flag & AT_SYMLINK_NOFOLLOW)
@ -91,8 +115,7 @@ __fxstatat (int vers, int fd, const char *file, struct stat *st, int flag)
goto out;
}
#if __ASSUME_STAT64_SYSCALL > 0
struct stat64 st64;
# if __ASSUME_STAT64_SYSCALL > 0
if (flag & AT_SYMLINK_NOFOLLOW)
result = INTERNAL_SYSCALL (lstat64, err, 2, CHECK_STRING (file),
@ -102,14 +125,12 @@ __fxstatat (int vers, int fd, const char *file, struct stat *st, int flag)
__ptrvalue (&st64));
if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
return __xstat32_conv (vers, &st64, st);
#else
# if defined __NR_stat64
# 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));
@ -126,7 +147,7 @@ __fxstatat (int vers, int fd, const char *file, struct stat *st, int flag)
__have_no_stat64 = 1;
}
# endif
# endif
if (flag & AT_SYMLINK_NOFOLLOW)
result = INTERNAL_SYSCALL (lstat, err, 2, CHECK_STRING (file),
__ptrvalue (&kst));
@ -135,7 +156,7 @@ __fxstatat (int vers, int fd, const char *file, struct stat *st, int flag)
__ptrvalue (&kst));
if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
return __xstat_conv (vers, &kst, st);
#endif /* __ASSUME_STAT64_SYSCALL */
# endif /* __ASSUME_STAT64_SYSCALL */
out:
if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 0))
@ -145,9 +166,11 @@ __fxstatat (int vers, int fd, const char *file, struct stat *st, int flag)
}
return result;
#endif
}
libc_hidden_def (__fxstatat)
#ifdef XSTAT_IS_XSTAT64
# undef __fxstatat64
strong_alias (__fxstatat, __fxstatat64);
libc_hidden_ver (__fxstatat, __fxstatat64)
libc_hidden_def (__fxstatat64)
#endif

View file

@ -1,5 +1,5 @@
/* Uncancelable versions of cancelable interfaces. Linux version.
Copyright (C) 2003 Free Software Foundation, Inc.
Copyright (C) 2003, 2006 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
@ -18,6 +18,7 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <sys/types.h>
#include <sysdep.h>
/* Uncancelable open. */
@ -26,6 +27,20 @@
#define open_not_cancel_2(name, flags) \
INLINE_SYSCALL (open, 2, (const char *) (name), (flags))
/* Uncancelable openat. */
extern int __openat_not_cancel (int fd, const char *fname, int oflag,
mode_t mode) attribute_hidden;
#define openat_not_cancel(fd, fname, oflag, mode) \
__openat_not_cancel (fd, fname, oflag, mode)
#define openat_not_cancel_3(fd, fname, oflag) \
__openat_not_cancel (fd, fname, oflag, 0)
extern int __openat64_not_cancel (int fd, const char *fname, int oflag,
mode_t mode) attribute_hidden;
#define openat64_not_cancel(fd, fname, oflag, mode) \
__openat64_not_cancel (fd, fname, oflag, mode)
#define openat64_not_cancel_3(fd, fname, oflag) \
__openat64_not_cancel (fd, fname, oflag, 0)
/* Uncancelable close. */
#define close_not_cancel(fd) \
INLINE_SYSCALL (close, 1, fd)

View file

@ -25,6 +25,7 @@
#include <sys/stat.h>
#include <kernel-features.h>
#include <sysdep-cancel.h>
#include <not-cancel.h>
#if !defined OPENAT && !defined __ASSUME_ATFCTS
@ -62,23 +63,19 @@ __atfct_seterrno (int errval, int fd, const char *buf)
int __have_atfcts;
#endif
/* Open FILE with access OFLAG. Interpret relative paths relative to
the directory associated with FD. If OFLAG includes O_CREAT, a
third argument is the file protection. */
#define OPENAT_NOT_CANCEL CONCAT (OPENAT)
#define CONCAT(name) CONCAT2 (name)
#define CONCAT2(name) __##name##_nocancel
int
OPENAT (fd, file, oflag)
OPENAT_NOT_CANCEL (fd, file, oflag, mode)
int fd;
const char *file;
int oflag;
mode_t mode;
{
mode_t mode = 0;
if (oflag & O_CREAT)
{
va_list arg;
va_start (arg, oflag);
mode = va_arg (arg, mode_t);
va_end (arg);
}
/* We have to add the O_LARGEFILE flag for openat64. */
#ifdef MORE_OFLAGS
@ -93,16 +90,7 @@ OPENAT (fd, file, oflag)
if (__have_atfcts >= 0)
# endif
{
if (SINGLE_THREAD_P)
res = INLINE_SYSCALL (openat, 4, fd, file, oflag, mode);
else
{
int oldtype = LIBC_CANCEL_ASYNC ();
res = INLINE_SYSCALL (openat, 4, fd, file, oflag, mode);
LIBC_CANCEL_RESET (oldtype);
}
res = INLINE_SYSCALL (openat, 4, fd, file, oflag, mode);
# ifndef __ASSUME_ATFCTS
if (res == -1 && errno == ENOSYS)
@ -130,20 +118,12 @@ OPENAT (fd, file, oflag)
size_t buflen = sizeof (procfd) + sizeof (int) * 3 + filelen;
buf = alloca (buflen);
/* Note: snprintf cannot be canceled. */
__snprintf (buf, buflen, procfd, fd, file);
file = buf;
}
if (SINGLE_THREAD_P)
res = INTERNAL_SYSCALL (open, err, 3, file, oflag, mode);
else
{
int oldtype = LIBC_CANCEL_ASYNC ();
res = INTERNAL_SYSCALL (open, err, 3, file, oflag, mode);
LIBC_CANCEL_RESET (oldtype);
}
res = INTERNAL_SYSCALL (open, err, 3, file, oflag, mode);
if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (res, err), 0))
{
@ -154,3 +134,34 @@ OPENAT (fd, file, oflag)
return res;
#endif
}
/* Open FILE with access OFLAG. Interpret relative paths relative to
the directory associated with FD. If OFLAG includes O_CREAT, a
third argument is the file protection. */
int
OPENAT (fd, file, oflag)
int fd;
const char *file;
int oflag;
{
mode_t mode = 0;
if (oflag & O_CREAT)
{
va_list arg;
va_start (arg, oflag);
mode = va_arg (arg, mode_t);
va_end (arg);
}
if (SINGLE_THREAD_P)
return OPENAT_NOT_CANCEL (fd, file, oflag, mode);
int oldtype = LIBC_CANCEL_ASYNC ();
int res = OPENAT_NOT_CANCEL (fd, file, oflag, mode);
LIBC_CANCEL_RESET (oldtype);
return res;
}

View file

@ -103,6 +103,7 @@ __fxstatat (int vers, int fd, const char *file, struct stat *st, int flag)
return res;
#endif
}
libc_hidden_def (__fxstatat)
#undef __fxstatat64
strong_alias (__fxstatat, __fxstatat64);
strong_alias (__fxstatat64, __GI___fxstatat64)