diff options
author | Jakub Jelinek <jakub@redhat.com> | 2006-02-13 07:30:06 +0000 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2006-02-13 07:30:06 +0000 |
commit | bb786851edfb584a36b3f2674eb024af6f33f319 (patch) | |
tree | 4243fee7b513ae79b63f94593d5e9e0b2bbe86c5 | |
parent | a7343889536746d3c1902f85c2075ee19ee58c7a (diff) | |
download | glibc-bb786851edfb584a36b3f2674eb024af6f33f319.tar glibc-bb786851edfb584a36b3f2674eb024af6f33f319.tar.gz glibc-bb786851edfb584a36b3f2674eb024af6f33f319.tar.bz2 glibc-bb786851edfb584a36b3f2674eb024af6f33f319.zip |
Updated to fedora-glibc-20060213T0650
35 files changed, 606 insertions, 183 deletions
@@ -1,3 +1,51 @@ +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. + * sysdeps/unix/sysv/linux/Versions [libc, GLIBC_2.4]: Export + unshare. + * sysdeps/unix/sysv/linux/syscalls.list: Add unshare syscall. + + * sysdeps/unix/Makefile ($(objpfx)stub-syscalls.c): Add some + preprocessor magic so that the compiler won't see the prototypes + for the functions we are defining as stubs. + +2006-02-05 Ulrich Drepper <drepper@redhat.com> + + * io/ftw.c (ftw_startup): Use fchdir to return to original + directory for FTW_CHDIR. + 2006-02-03 Ulrich Drepper <drepper@redhat.com> * manual/stdio.texi (Formatted Output Functions): Fix make_message diff --git a/dirent/fdopendir.c b/dirent/fdopendir.c index ed30e89e7e..275cfd58fe 100644 --- a/dirent/fdopendir.c +++ b/dirent/fdopendir.c @@ -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> diff --git a/fedora/branch.mk b/fedora/branch.mk index 644327ec67..e9760460ca 100644 --- a/fedora/branch.mk +++ b/fedora/branch.mk @@ -3,5 +3,5 @@ glibc-branch := fedora glibc-base := HEAD DIST_BRANCH := devel COLLECTION := dist-fc4 -fedora-sync-date := 2006-02-04 07:58 UTC -fedora-sync-tag := fedora-glibc-20060204T0758 +fedora-sync-date := 2006-02-13 06:50 UTC +fedora-sync-tag := fedora-glibc-20060213T0650 diff --git a/fedora/glibc.spec.in b/fedora/glibc.spec.in index 0c22cc8b45..5547e9a22a 100644 --- a/fedora/glibc.spec.in +++ b/fedora/glibc.spec.in @@ -1,4 +1,4 @@ -%define glibcrelease 36 +%define glibcrelease 37 %define auxarches i586 i686 athlon sparcv9 alphaev6 %define prelinkarches noarch %define xenarches i686 athlon @@ -294,7 +294,7 @@ cat > override_headers/asm/unistd.h <<EOF #define __NR_mknodat 297 #define __NR_fchownat 298 #define __NR_futimesat 299 -#define __NR_newfstatat 300 +#define __NR_fstatat64 300 #define __NR_unlinkat 301 #define __NR_renameat 302 #define __NR_linkat 303 @@ -307,34 +307,61 @@ cat > override_headers/asm/unistd.h <<EOF #define __NR_pselect6 308 #define __NR_ppoll 309 #endif +#ifndef __NR_unshare +#define __NR_unshare 310 +#endif %endif %ifarch ia64 #ifndef __NR_timer_create -#define __NR_timer_create 1248 -#define __NR_timer_settime 1249 -#define __NR_timer_gettime 1250 -#define __NR_timer_getoverrun 1251 -#define __NR_timer_delete 1252 -#define __NR_clock_settime 1253 -#define __NR_clock_gettime 1254 -#define __NR_clock_getres 1255 -#define __NR_clock_nanosleep 1256 +#define __NR_timer_create 1248 +#define __NR_timer_settime 1249 +#define __NR_timer_gettime 1250 +#define __NR_timer_getoverrun 1251 +#define __NR_timer_delete 1252 +#define __NR_clock_settime 1253 +#define __NR_clock_gettime 1254 +#define __NR_clock_getres 1255 +#define __NR_clock_nanosleep 1256 #endif #ifndef __NR_mq_open -#define __NR_mq_open 1262 -#define __NR_mq_unlink 1263 -#define __NR_mq_timedsend 1264 -#define __NR_mq_timedreceive 1265 -#define __NR_mq_notify 1266 -#define __NR_mq_getsetattr 1267 +#define __NR_mq_open 1262 +#define __NR_mq_unlink 1263 +#define __NR_mq_timedsend 1264 +#define __NR_mq_timedreceive 1265 +#define __NR_mq_notify 1266 +#define __NR_mq_getsetattr 1267 #endif #ifndef __NR_waitid -#define __NR_waitid 1270 +#define __NR_waitid 1270 #endif #ifndef __NR_inotify_init -#define __NR_inotify_init 1277 -#define __NR_inotify_add_watch 1278 -#define __NR_inotify_rm_watch 1279 +#define __NR_inotify_init 1277 +#define __NR_inotify_add_watch 1278 +#define __NR_inotify_rm_watch 1279 +#endif +#ifndef __NR_openat +#define __NR_openat 1281 +#define __NR_mkdirat 1282 +#define __NR_mknodat 1283 +#define __NR_fchownat 1284 +#define __NR_futimesat 1285 +#define __NR_newfstatat 1286 +#define __NR_unlinkat 1287 +#define __NR_renameat 1288 +#define __NR_linkat 1289 +#define __NR_symlinkat 1290 +#define __NR_readlinkat 1291 +#define __NR_fchmodat 1292 +#define __NR_faccessat 1293 +#endif +#if 0 +#ifndef __NR_pselect6 +#define __NR_pselect6 1294 +#define __NR_ppoll 1295 +#endif +#endif +#ifndef __NR_unshare +#define __NR_unshare 1296 #endif %endif %ifarch ppc @@ -368,6 +395,9 @@ cat > override_headers/asm/unistd.h <<EOF #define __NR_pselect6 280 #define __NR_ppoll 281 #endif +#ifndef __NR_unshare +#define __NR_unshare 282 +#endif %endif %ifarch ppc64 #ifndef __NR_utimes @@ -393,6 +423,9 @@ cat > override_headers/asm/unistd.h <<EOF #define __NR_pselect6 280 #define __NR_ppoll 281 #endif +#ifndef __NR_unshare +#define __NR_unshare 282 +#endif %endif %ifarch s390 #ifndef __NR_timer_create @@ -429,6 +462,28 @@ cat > override_headers/asm/unistd.h <<EOF #define __NR_inotify_add_watch 285 #define __NR_inotify_rm_watch 286 #endif +#ifndef __NR_openat +#define __NR_openat 288 +#define __NR_mkdirat 289 +#define __NR_mknodat 290 +#define __NR_fchownat 291 +#define __NR_futimesat 292 +#define __NR_fstatat64 293 +#define __NR_unlinkat 294 +#define __NR_renameat 295 +#define __NR_linkat 296 +#define __NR_symlinkat 297 +#define __NR_readlinkat 298 +#define __NR_fchmodat 299 +#define __NR_faccessat 300 +#endif +#ifndef __NR_pselect6 +#define __NR_pselect6 301 +#define __NR_ppoll 302 +#endif +#ifndef __NR_unshare +#define __NR_unshare 303 +#endif %endif %ifarch s390x #ifndef __NR_timer_create @@ -458,6 +513,28 @@ cat > override_headers/asm/unistd.h <<EOF #define __NR_inotify_add_watch 285 #define __NR_inotify_rm_watch 286 #endif +#ifndef __NR_openat +#define __NR_openat 288 +#define __NR_mkdirat 289 +#define __NR_mknodat 290 +#define __NR_fchownat 291 +#define __NR_futimesat 292 +#define __NR_newfstatat 293 +#define __NR_unlinkat 294 +#define __NR_renameat 295 +#define __NR_linkat 296 +#define __NR_symlinkat 297 +#define __NR_readlinkat 298 +#define __NR_fchmodat 299 +#define __NR_faccessat 300 +#endif +#ifndef __NR_pselect6 +#define __NR_pselect6 301 +#define __NR_ppoll 302 +#endif +#ifndef __NR_unshare +#define __NR_unshare 303 +#endif %endif %ifarch sparc sparcv9 sparc64 #ifndef __NR_mq_open @@ -500,6 +577,9 @@ cat > override_headers/asm/unistd.h <<EOF #define __NR_pselect6 297 #define __NR_ppoll 298 #endif +#ifndef __NR_unshare +#define __NR_unshare 299 +#endif %endif %ifarch x86_64 #ifndef __NR_mq_open @@ -533,6 +613,18 @@ cat > override_headers/asm/unistd.h <<EOF #define __NR_fchmodat 268 #define __NR_faccessat 269 #endif +#ifndef __NR_pselect6 +#define __NR_pselect6 270 +#define __NR_ppoll 271 +#endif +#ifndef __NR_unshare +#define __NR_unshare 272 +#endif +%endif +%ifnarch %{ix86} x86_64 +/* FIXME: Reenable it when the kernel side is more stable. */ +#undef __NR_newfstatat +#undef __NR_fstatat64 %endif #endif EOF @@ -1240,6 +1332,11 @@ rm -f *.filelist* %endif %changelog +* Mon Feb 13 2006 Jakub Jelinek <jakub@redhat.com> 2.3.90-37 +- update from CVS + - *at fixes + - unshare syscall wrapper + * Sat Feb 4 2006 Jakub Jelinek <jakub@redhat.com> 2.3.90-36 - update from CVS - fix frequency setting for ITIMER_PROF (#179938, BZ#2268) diff --git a/include/dirent.h b/include/dirent.h index 681024fd02..8f23aee234 100644 --- a/include/dirent.h +++ b/include/dirent.h @@ -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 diff --git a/include/sys/stat.h b/include/sys/stat.h index 72105a45a9..66898b1760 100644 --- a/include/sys/stat.h +++ b/include/sys/stat.h @@ -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) @@ -1,5 +1,5 @@ /* File tree walker functions. - Copyright (C) 1996-2003, 2004 Free Software Foundation, Inc. + Copyright (C) 1996-2003, 2004, 2006 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. @@ -36,7 +36,7 @@ char *alloca (); # endif #endif -#if defined _LIBC +#ifdef _LIBC # include <dirent.h> # define NAMLEN(dirent) _D_EXACT_NAMLEN (dirent) #else @@ -59,12 +59,14 @@ char *alloca (); #endif #include <errno.h> +#include <fcntl.h> #include <ftw.h> #include <limits.h> #include <search.h> #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 @@ -142,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 @@ -161,6 +165,7 @@ int rpl_lstat (const char *, struct stat *); struct dir_data { DIR *stream; + int streamfd; char *content; }; @@ -262,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; @@ -323,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; } } @@ -331,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; @@ -355,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; @@ -382,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; + + statres = ((data->flags & FTW_PHYS) + ? LXSTAT (_STAT_VER, name, &st) + : XSTAT (_STAT_VER, name, &st)); + } - if (((data->flags & FTW_PHYS) - ? LXSTAT (_STAT_VER, name, &st) - : XSTAT (_STAT_VER, name, &st)) < 0) + 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; @@ -445,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) @@ -465,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) @@ -495,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; } @@ -509,6 +540,7 @@ fail: assert (dir.content == NULL); __closedir (dir.stream); + dir.streamfd = -1; __set_errno (save_err); if (data->actdir-- == 0) @@ -524,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; } @@ -585,6 +618,7 @@ ftw_startup (const char *dir, int is_nftw, void *func, int descriptors, struct STAT st; int result = 0; int save_err; + int cwdfd = -1; char *cwd = NULL; char *cp; @@ -639,11 +673,26 @@ ftw_startup (const char *dir, int is_nftw, void *func, int descriptors, /* Now go to the directory containing the initial file/directory. */ if (flags & FTW_CHDIR) { - /* GNU extension ahead. */ - cwd = __getcwd (NULL, 0); - if (cwd == NULL) - result = -1; - else if (data.ftw.base > 0) + /* We have to be able to go back to the current working + directory. The best way to do this is to use a file + descriptor. */ + cwdfd = __open (".", O_RDONLY | O_DIRECTORY); + if (cwdfd == -1) + { + /* Try getting the directory name. This can be needed if + the current directory is executable but not readable. */ + if (errno == EACCES) + /* GNU extension ahead. */ + cwd = __getcwd (NULL, 0); + + if (cwd == NULL) + goto out_fail; + } + else if (data.maxdir > 1) + /* Account for the file descriptor we use here. */ + --data.maxdir; + + if (data.ftw.base > 0) { /* Change to the directory the file is in. In data.dirbuf we have a writable copy of the file name. Just NUL @@ -713,7 +762,13 @@ ftw_startup (const char *dir, int is_nftw, void *func, int descriptors, } /* Return to the start directory (if necessary). */ - if (cwd != NULL) + if (cwdfd != -1) + { + int save_err = errno; + __fchdir (cwdfd); + __set_errno (save_err); + } + else if (cwd != NULL) { int save_err = errno; __chdir (cwd); @@ -722,6 +777,7 @@ ftw_startup (const char *dir, int is_nftw, void *func, int descriptors, } /* Free all memory. */ + out_fail: save_err = errno; __tdestroy (data.known_objects, free); free (data.dirbuf); @@ -755,7 +811,7 @@ NFTW_NAME (path, func, descriptors, flags) } #else -#include <shlib-compat.h> +# include <shlib-compat.h> int NFTW_NEW_NAME (const char *, NFTW_FUNC_T, int, int); @@ -777,7 +833,7 @@ NFTW_NEW_NAME (path, func, descriptors, flags) versioned_symbol (libc, NFTW_NEW_NAME, NFTW_NAME, GLIBC_2_3_3); -#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_3_3) +# if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_3_3) /* Older nftw* version just ignored all unknown flags. */ @@ -796,5 +852,5 @@ NFTW_OLD_NAME (path, func, descriptors, flags) } compat_symbol (libc, NFTW_OLD_NAME, NFTW_NAME, GLIBC_2_1); -#endif +# endif #endif diff --git a/io/ftw64.c b/io/ftw64.c index 7913b7af17..39e6ceabf8 100644 --- a/io/ftw64.c +++ b/io/ftw64.c @@ -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 diff --git a/io/fxstatat.c b/io/fxstatat.c index 62f7fe3efb..2486c73c84 100644 --- a/io/fxstatat.c +++ b/io/fxstatat.c @@ -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> diff --git a/io/fxstatat64.c b/io/fxstatat64.c index ba95b73e81..20bdd610c3 100644 --- a/io/fxstatat64.c +++ b/io/fxstatat64.c @@ -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> diff --git a/libio/wgenops.c b/libio/wgenops.c index a9cc7bf210..355fd2603d 100644 --- a/libio/wgenops.c +++ b/libio/wgenops.c @@ -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) diff --git a/nptl/ChangeLog b/nptl/ChangeLog index a03b311003..a19d95e75c 100644 --- a/nptl/ChangeLog +++ b/nptl/ChangeLog @@ -1,3 +1,25 @@ +2006-02-12 Ulrich Drepper <drepper@redhat.com> + + * allocatestack.c (allocate_stack): Initialize robust_list. + * init.c (__pthread_initialize_minimal_internal): Likewise. + * descr.h (struct xid_command): Pretty printing. + (struct pthread): Use __pthread_list_t or __pthread_slist_t for + robust_list. Adjust macros. + * pthread_create.c (start_thread): Adjust robust_list handling. + * phtread_mutex_unlock.c: Don't allow unlocking from any thread + but the owner for all robust mutex types. + * sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h: Define + __pthread_list_t and __pthread_slist_t. Use them in pthread_mutex_t. + * sysdeps/pthread/pthread.h: Adjust mutex initializers. + + * sysdeps/unix/sysv/linux/i386/not-cancel.h: Define openat_not_cancel, + openat_not_cancel_3, openat64_not_cancel, and openat64_not_cancel_3. + +2006-02-08 Jakub Jelinek <jakub@redhat.com> + + * sysdeps/unix/sysv/linux/i386/lowlevellock.h (lll_futex_wait, + lll_futex_timedwait, lll_wait_tid): Add "memory" clobber. + 2006-01-20 Kaz Kojima <kkojima@rr.iij4u.or.jp> * sysdeps/unix/sysv/linux/sh/lowlevellock.h (lll_futex_wait): diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c index e6bcc2170f..046a2470fc 100644 --- a/nptl/allocatestack.c +++ b/nptl/allocatestack.c @@ -1,5 +1,4 @@ -/* Copyright (C) 2002, 2003, 2004, 2005 - Free Software Foundation, Inc. +/* Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. @@ -366,6 +365,12 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp, /* The process ID is also the same as that of the caller. */ pd->pid = THREAD_GETMEM (THREAD_SELF, pid); + /* List of robust mutexes. */ +#ifdef __PTHREAD_MUTEX_HAVE_PREV + pd->robust_list.__prev = &pd->robust_list; +#endif + pd->robust_list.__next = &pd->robust_list; + /* Allocate the DTV for this thread. */ if (_dl_allocate_tls (TLS_TPADJ (pd)) == NULL) { @@ -500,6 +505,12 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp, /* The process ID is also the same as that of the caller. */ pd->pid = THREAD_GETMEM (THREAD_SELF, pid); + /* List of robust mutexes. */ +#ifdef __PTHREAD_MUTEX_HAVE_PREV + pd->robust_list.__prev = &pd->robust_list; +#endif + pd->robust_list.__next = &pd->robust_list; + /* Allocate the DTV for this thread. */ if (_dl_allocate_tls (TLS_TPADJ (pd)) == NULL) { diff --git a/nptl/descr.h b/nptl/descr.h index 6dcc574c24..6984138537 100644 --- a/nptl/descr.h +++ b/nptl/descr.h @@ -97,7 +97,7 @@ struct pthread_unwind_buf struct xid_command { int syscall_no; - long id[3]; + long int id[3]; volatile int cntr; }; @@ -135,46 +135,45 @@ struct pthread pid_t pid; /* List of robust mutexes the thread is holding. */ - struct __pthread_mutex_s *robust_list; - #ifdef __PTHREAD_MUTEX_HAVE_PREV + __pthread_list_t robust_list; + # define ENQUEUE_MUTEX(mutex) \ do { \ - mutex->__data.__next = THREAD_GETMEM (THREAD_SELF, robust_list); \ - THREAD_SETMEM (THREAD_SELF, robust_list, &mutex->__data); \ - if (mutex->__data.__next != NULL) \ - mutex->__data.__next->__prev = &mutex->__data; \ - mutex->__data.__prev = NULL; \ + __pthread_list_t *next = THREAD_GETMEM (THREAD_SELF, robust_list.__next); \ + next->__prev = &mutex->__data.__list; \ + mutex->__data.__list.__next = next; \ + mutex->__data.__list.__prev = &THREAD_SELF->robust_list; \ + THREAD_SETMEM (THREAD_SELF, robust_list.__next, &mutex->__data.__list); \ } while (0) # define DEQUEUE_MUTEX(mutex) \ do { \ - if (mutex->__data.__prev == NULL) \ - THREAD_SETMEM (THREAD_SELF, robust_list, mutex->__data.__next); \ - else \ - mutex->__data.__prev->__next = mutex->__data.__next; \ - if (mutex->__data.__next != NULL) \ - mutex->__data.__next->__prev = mutex->__data.__prev; \ - mutex->__data.__prev = NULL; \ - mutex->__data.__next = NULL; \ + mutex->__data.__list.__next->__prev = mutex->__data.__list.__prev; \ + mutex->__data.__list.__prev->__next = mutex->__data.__list.__next; \ + mutex->__data.__list.__prev = NULL; \ + mutex->__data.__list.__next = NULL; \ } while (0) #else + __pthread_slist_t robust_list; + # define ENQUEUE_MUTEX(mutex) \ do { \ - mutex->__data.__next = THREAD_GETMEM (THREAD_SELF, robust_list); \ - THREAD_SETMEM (THREAD_SELF, robust_list, &mutex->__data); \ + mutex->__data.__list.__next \ + = THREAD_GETMEM (THREAD_SELF, robust_list.__next); \ + THREAD_SETMEM (THREAD_SELF, robust_list.__next, &mutex->__data.__list); \ } while (0) # define DEQUEUE_MUTEX(mutex) \ do { \ - struct __pthread_mutex_s *runp = THREAD_GETMEM (THREAD_SELF, robust_list);\ - if (runp == &mutex->__data) \ + __pthread_slist_t *runp = THREAD_GETMEM (THREAD_SELF, robust_list.__next);\ + if (runp == &mutex->__data.__list) \ THREAD_SETMEM (THREAD_SELF, robust_list, runp->__next); \ else \ { \ - while (runp->__next != &mutex->__data) \ + while (runp->__next != &mutex->__data.__list) \ runp = runp->__next; \ \ runp->__next = runp->__next->__next; \ - mutex->__data.__next = NULL; \ + mutex->__data.__list.__next = NULL; \ } \ } while (0) #endif diff --git a/nptl/init.c b/nptl/init.c index 1f79eba62a..cb63ff7a6d 100644 --- a/nptl/init.c +++ b/nptl/init.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc. +/* Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. @@ -247,6 +247,10 @@ __pthread_initialize_minimal_internal (void) struct pthread *pd = THREAD_SELF; INTERNAL_SYSCALL_DECL (err); pd->pid = pd->tid = INTERNAL_SYSCALL (set_tid_address, err, 1, &pd->tid); +#ifdef __PTHREAD_MUTEX_HAVE_PREV + pd->robust_list.__prev = &pd->robust_list; +#endif + pd->robust_list.__next = &pd->robust_list; THREAD_SETMEM (pd, specific[0], &pd->specific_1stblock[0]); THREAD_SETMEM (pd, user_stack, true); if (LLL_LOCK_INITIALIZER != 0) diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c index 94d424b1f2..b1253b2243 100644 --- a/nptl/pthread_create.c +++ b/nptl/pthread_create.c @@ -311,12 +311,17 @@ start_thread (void *arg) atomic_bit_set (&pd->cancelhandling, EXITING_BIT); /* If this thread has any robust mutexes locked, handle them now. */ - struct __pthread_mutex_s *robust = THREAD_GETMEM (pd, robust_list); - if (__builtin_expect (robust != NULL, 0)) +#if __WORDSIZE == 64 + __pthread_list_t *robust = pd->robust_list.__next; +#else + __pthread_slist_t *robust = pd->robust_list.__next; +#endif + if (__builtin_expect (robust != &pd->robust_list, 0)) { do { - struct __pthread_mutex_s *this = robust; + struct __pthread_mutex_s *this = (struct __pthread_mutex_s *) + ((char *) robust - offsetof (struct __pthread_mutex_s, __list)); robust = robust->__next; assert (lll_mutex_islocked (this->__lock)); @@ -324,17 +329,20 @@ start_thread (void *arg) --this->__nusers; assert (this->__owner != PTHREAD_MUTEX_NOTRECOVERABLE); this->__owner = PTHREAD_MUTEX_OWNERDEAD; - this->__next = NULL; + this->__list.__next = NULL; #ifdef __PTHREAD_MUTEX_HAVE_PREV - this->__prev = NULL; + this->__list.__prev = NULL; #endif lll_mutex_unlock (this->__lock); } - while (robust != NULL); + while (robust != &pd->robust_list); /* Clean up so that the thread descriptor can be reused. */ - THREAD_SETMEM (pd, robust_list, NULL); + pd->robust_list.__next = &pd->robust_list; +#ifdef __PTHREAD_MUTEX_HAVE_PREV + pd->robust_list.__prev = &pd->robust_list; +#endif } /* If the thread is detached free the TCB. */ diff --git a/nptl/pthread_mutex_unlock.c b/nptl/pthread_mutex_unlock.c index babce51a6f..4d87381065 100644 --- a/nptl/pthread_mutex_unlock.c +++ b/nptl/pthread_mutex_unlock.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc. +/* Copyright (C) 2002, 2003, 2005, 2006 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. @@ -76,15 +76,12 @@ __pthread_mutex_unlock_usercnt (mutex, decr) goto robust; case PTHREAD_MUTEX_ROBUST_PRIVATE_ERRORCHECK_NP: - /* Error checking mutex. */ + case PTHREAD_MUTEX_ROBUST_PRIVATE_NP: + case PTHREAD_MUTEX_ROBUST_PRIVATE_ADAPTIVE_NP: if (abs (mutex->__data.__owner) != THREAD_GETMEM (THREAD_SELF, tid) || ! lll_mutex_islocked (mutex->__data.__lock)) return EPERM; - /* FALLTHROUGH */ - - case PTHREAD_MUTEX_ROBUST_PRIVATE_NP: - case PTHREAD_MUTEX_ROBUST_PRIVATE_ADAPTIVE_NP: /* If the previous owner died and the caller did not succeed in making the state consistent, mark the mutex as unrecoverable and make all waiters. */ diff --git a/nptl/sysdeps/pthread/pthread.h b/nptl/sysdeps/pthread/pthread.h index d887e37aee..f4935e07b4 100644 --- a/nptl/sysdeps/pthread/pthread.h +++ b/nptl/sysdeps/pthread/pthread.h @@ -74,14 +74,14 @@ enum /* Mutex initializers. */ #if __WORDSIZE == 64 # define PTHREAD_MUTEX_INITIALIZER \ - { { 0, 0, 0, 0, 0, 0, 0, 0 } } + { { 0, 0, 0, 0, 0, 0, { 0, 0 } } } # ifdef __USE_GNU # define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP \ - { { 0, 0, 0, 0, PTHREAD_MUTEX_RECURSIVE_NP, 0, 0, 0 } } + { { 0, 0, 0, 0, PTHREAD_MUTEX_RECURSIVE_NP, 0, { 0, 0 } } } # define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP \ - { { 0, 0, 0, 0, PTHREAD_MUTEX_ERRORCHECK_NP, 0, 0, 0 } } + { { 0, 0, 0, 0, PTHREAD_MUTEX_ERRORCHECK_NP, 0, { 0, 0 } } } # define PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP \ - { { 0, 0, 0, 0, PTHREAD_MUTEX_ADAPTIVE_NP, 0, 0, 0 } } + { { 0, 0, 0, 0, PTHREAD_MUTEX_ADAPTIVE_NP, 0, { 0, 0 } } } # endif #else # define PTHREAD_MUTEX_INITIALIZER \ diff --git a/nptl/sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h b/nptl/sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h index 662f3e54a8..f53d0e5a72 100644 --- a/nptl/sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h +++ b/nptl/sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h @@ -43,6 +43,12 @@ typedef union } pthread_attr_t; +typedef struct __pthread_internal_slist +{ + struct __pthread_internal_slist *__next; +} __pthread_slist_t; + + /* Data structures for mutex handling. The structure of the attribute type is not exposed on purpose. */ typedef union @@ -59,7 +65,7 @@ typedef union __extension__ union { int __spins; - struct __pthread_mutex_s *__next; + __pthread_slist_t __list; }; } __data; char __size[__SIZEOF_PTHREAD_MUTEX_T]; diff --git a/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h index fd1ee4569d..b233d9747f 100644 --- a/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h +++ b/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h @@ -75,7 +75,8 @@ : "=a" (__status) \ : "0" (SYS_futex), LLL_EBX_REG (futex), "S" (0), \ "c" (FUTEX_WAIT), "d" (_val), \ - "i" (offsetof (tcbhead_t, sysinfo))); \ + "i" (offsetof (tcbhead_t, sysinfo)) \ + : "memory"); \ __status; \ }) @@ -90,7 +91,8 @@ : "=a" (__status) \ : "0" (SYS_futex), LLL_EBX_REG (futex), "S" (timeout), \ "c" (FUTEX_WAIT), "d" (_val), \ - "i" (offsetof (tcbhead_t, sysinfo))); \ + "i" (offsetof (tcbhead_t, sysinfo)) \ + : "memory"); \ __status; \ }) @@ -346,7 +348,8 @@ extern int lll_unlock_wake_cb (int *__futex) attribute_hidden; : "=&a" (__ignore) \ : "i" (SYS_futex), LLL_EBX_REG (&tid), "S" (0), \ "c" (FUTEX_WAIT), "d" (_tid), \ - "i" (offsetof (tcbhead_t, sysinfo))); \ + "i" (offsetof (tcbhead_t, sysinfo)) \ + : "memory"); \ } while (0) extern int __lll_timedwait_tid (int *tid, const struct timespec *abstime) diff --git a/nptl/sysdeps/unix/sysv/linux/i386/not-cancel.h b/nptl/sysdeps/unix/sysv/linux/i386/not-cancel.h index cc3282fbdd..91584948ae 100644 --- a/nptl/sysdeps/unix/sysv/linux/i386/not-cancel.h +++ b/nptl/sysdeps/unix/sysv/linux/i386/not-cancel.h @@ -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) diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h b/nptl/sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h index 81942bc86c..693387a266 100644 --- a/nptl/sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h +++ b/nptl/sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h @@ -57,6 +57,20 @@ typedef union } pthread_attr_t; +#if __WORDSIZE == 64 +typedef struct __pthread_internal_list +{ + struct __pthread_internal_list *__prev; + struct __pthread_internal_list *__next; +} __pthread_list_t; +#else +typedef struct __pthread_internal_slist +{ + struct __pthread_internal_slist *__next; +} __pthread_slist_t; +#endif + + /* Data structures for mutex handling. The structure of the attribute type is not exposed on purpose. */ typedef union @@ -74,15 +88,14 @@ typedef union int __kind; #if __WORDSIZE == 64 int __spins; - struct __pthread_mutex_s *__next; - struct __pthread_mutex_s *__prev; + __pthread_list_t __list; # define __PTHREAD_MUTEX_HAVE_PREV 1 #else unsigned int __nusers; __extension__ union { int __spins; - struct __pthread_mutex_s *__next; + __pthread_slist_t __list; }; #endif } __data; diff --git a/sysdeps/generic/not-cancel.h b/sysdeps/generic/not-cancel.h index 396e0421f9..427be6475f 100644 --- a/sysdeps/generic/not-cancel.h +++ b/sysdeps/generic/not-cancel.h @@ -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) \ diff --git a/sysdeps/mach/hurd/fdopendir.c b/sysdeps/mach/hurd/fdopendir.c index 37dd4bc82e..c9caac30d7 100644 --- a/sysdeps/mach/hurd/fdopendir.c +++ b/sysdeps/mach/hurd/fdopendir.c @@ -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) diff --git a/sysdeps/unix/Makefile b/sysdeps/unix/Makefile index 5b326e032c..c1da42f953 100644 --- a/sysdeps/unix/Makefile +++ b/sysdeps/unix/Makefile @@ -1,4 +1,4 @@ -# Copyright (C) 1991,1992,1993,1994,1995,1996,1997,1998,1999,2003 +# Copyright (C) 1991,1992,1993,1994,1995,1996,1997,1998,1999,2003, 2006 # Free Software Foundation, Inc. # This file is part of the GNU C Library. @@ -294,7 +294,13 @@ sysdep_routines += stub-syscalls $(objpfx)stub-syscalls.c: $(common-objpfx)sysd-syscalls \ $(..)sysdeps/unix/Makefile $(make-target-directory) - (echo '#include <errno.h>'; \ + (for call in $(unix-stub-syscalls); do \ + echo "#define $$call RENAMED_$$call"; \ + done; \ + echo '#include <errno.h>'; \ + for call in $(unix-stub-syscalls); do \ + echo "#undef $$call"; \ + done; \ echo 'long int _no_syscall (void)'; \ echo '{ __set_errno (ENOSYS); return -1L; }'; \ for call in $(unix-stub-syscalls); do \ diff --git a/sysdeps/unix/fdopendir.c b/sysdeps/unix/fdopendir.c index 528f180fcb..565ce1ed72 100644 --- a/sysdeps/unix/fdopendir.c +++ b/sysdeps/unix/fdopendir.c @@ -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) diff --git a/sysdeps/unix/sysv/linux/Versions b/sysdeps/unix/sysv/linux/Versions index 436573a428..fed28f2db0 100644 --- a/sysdeps/unix/sysv/linux/Versions +++ b/sysdeps/unix/sysv/linux/Versions @@ -118,6 +118,8 @@ libc { GLIBC_2.4 { inotify_init; inotify_add_watch; inotify_rm_watch; + unshare; + #errlist-compat 132 _sys_errlist; sys_errlist; _sys_nerr; sys_nerr; } diff --git a/sysdeps/unix/sysv/linux/bits/sched.h b/sysdeps/unix/sysv/linux/bits/sched.h index 2ca7df0d13..4a95a263f7 100644 --- a/sysdeps/unix/sysv/linux/bits/sched.h +++ b/sysdeps/unix/sysv/linux/bits/sched.h @@ -69,10 +69,13 @@ struct sched_param __BEGIN_DECLS -/* Clone current process. */ #ifdef __USE_MISC +/* Clone current process. */ extern int clone (int (*__fn) (void *__arg), void *__child_stack, int __flags, void *__arg, ...) __THROW; + +/* Unshare the specified resources. */ +extern int unshare (int __flags) __THROW; #endif __END_DECLS diff --git a/sysdeps/unix/sysv/linux/fxstatat.c b/sysdeps/unix/sysv/linux/fxstatat.c index 77debf71d3..c1c416abd7 100644 --- a/sysdeps/unix/sysv/linux/fxstatat.c +++ b/sysdeps/unix/sysv/linux/fxstatat.c @@ -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 diff --git a/sysdeps/unix/sysv/linux/fxstatat64.c b/sysdeps/unix/sysv/linux/fxstatat64.c index 220d4abfcf..cb932b8e59 100644 --- a/sysdeps/unix/sysv/linux/fxstatat64.c +++ b/sysdeps/unix/sysv/linux/fxstatat64.c @@ -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) diff --git a/sysdeps/unix/sysv/linux/i386/fxstatat.c b/sysdeps/unix/sysv/linux/i386/fxstatat.c index 65fab5179c..b077435553 100644 --- a/sysdeps/unix/sysv/linux/i386/fxstatat.c +++ b/sysdeps/unix/sysv/linux/i386/fxstatat.c @@ -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 diff --git a/sysdeps/unix/sysv/linux/not-cancel.h b/sysdeps/unix/sysv/linux/not-cancel.h index 9418417b45..ece8d69ecf 100644 --- a/sysdeps/unix/sysv/linux/not-cancel.h +++ b/sysdeps/unix/sysv/linux/not-cancel.h @@ -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) diff --git a/sysdeps/unix/sysv/linux/openat.c b/sysdeps/unix/sysv/linux/openat.c index 4c1f302ab0..38ffe85b56 100644 --- a/sysdeps/unix/sysv/linux/openat.c +++ b/sysdeps/unix/sysv/linux/openat.c @@ -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; +} diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list index 88e1f5a294..053d7e0ccf 100644 --- a/sysdeps/unix/sysv/linux/syscalls.list +++ b/sysdeps/unix/sysv/linux/syscalls.list @@ -73,6 +73,7 @@ sigaltstack - sigaltstack i:PP __sigaltstack sigaltstack sysinfo EXTRA sysinfo i:p sysinfo swapon - swapon i:si __swapon swapon swapoff - swapoff i:s __swapoff swapoff +unshare EXTRA unshare i:i unshare uselib EXTRA uselib i:s uselib wait4 - wait4 i:iWiP __wait4 wait4 diff --git a/sysdeps/unix/sysv/linux/wordsize-64/fxstatat.c b/sysdeps/unix/sysv/linux/wordsize-64/fxstatat.c index 0c37495575..8b1c932ba9 100644 --- a/sysdeps/unix/sysv/linux/wordsize-64/fxstatat.c +++ b/sysdeps/unix/sysv/linux/wordsize-64/fxstatat.c @@ -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) |