diff options
-rw-r--r-- | ChangeLog | 36 | ||||
-rw-r--r-- | csu/elf-init.c | 21 | ||||
-rw-r--r-- | csu/libc-start.c | 6 | ||||
-rw-r--r-- | include/stdlib.h | 3 | ||||
-rw-r--r-- | localedata/ChangeLog | 4 | ||||
-rw-r--r-- | localedata/locales/hsb_DE | 24 | ||||
-rw-r--r-- | login/programs/pt_chown.c | 5 | ||||
-rw-r--r-- | nptl/ChangeLog | 10 | ||||
-rw-r--r-- | nptl/Makefile | 2 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/x86_64/cancellation.S | 5 | ||||
-rw-r--r-- | nptl/tst-sem13.c | 46 | ||||
-rw-r--r-- | stdlib/random_r.c | 4 | ||||
-rw-r--r-- | sysdeps/unix/grantpt.c | 59 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/grantpt.c | 42 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/ptsname.c | 37 |
15 files changed, 239 insertions, 65 deletions
@@ -1,3 +1,39 @@ +2009-11-26 Ulrich Drepper <drepper@redhat.com> + + * sysdeps/unix/sysv/linux/ptsname.c (__ptsname_internal): Avoid code + only used on truly ancient kernel if configuration requires a more + recent kernel. + +2009-11-24 Ulrich Drepper <drepper@redhat.com> + + [BZ #3662] + * stdlib/random_r.c: Fix comments for __initstate_r and __setstate_r. + Patch by Christopher Neufeld <glibcbugs0000@cneufeld.ca>. + + * sysdeps/unix/grantpt.c (pts_name): Take additional parameter, + pass it on to __ptsname_internal. + (grantpt): Pass stat64 pointer to pts_name. Remove stat call here. + * sysdeps/unix/sysv/linux/ptsname.c (__ptsname_internal): New function. + All the code from __ptsname_r but take additional parameter. Use that + instead of pointer to local stat64 variable. + (__ptsname_r): Call __ptsname_internal with pointer to local stat64 + variable. + * include/stdlib.h: Declare __ptsname_internal. + + * sysdeps/unix/grantpt.c (grantpt): Use CLOSE_ALL_FDS is available + before the exec. + * sysdeps/unix/sysv/linux/grantpt.c: New file. + * login/programs/pt_chown.c (main): Don't print message on errors + when doing real work. + + * sysdeps/unix/grantpt.c (grantpt): Only get tty group information + once. + + * csu/elf-init.c (__libc_csu_irel): New function. Code to perform + irel relocations split out from... + (__libc_csu_init): ...here. + * csu/libc-start.c [!SHARED]: Call __libc_csu_irel early. + 2009-11-23 Andreas Schwab <schwab@redhat.com> * sysdeps/unix/sysv/linux/x86_64/bits/stat.h: Use struct timespec diff --git a/csu/elf-init.c b/csu/elf-init.c index 7481e69aa6..f828faa601 100644 --- a/csu/elf-init.c +++ b/csu/elf-init.c @@ -89,15 +89,14 @@ extern void _fini (void); /* These functions are passed to __libc_start_main by the startup code. These get statically linked into each program. For dynamically linked programs, this module will come from libc_nonshared.a and differs from - the libc.a module in that it doesn't call the preinit array. */ + the libc.a module in that it doesn't call the preinit array and performs + explicit IREL{,A} relocations. */ -void -__libc_csu_init (int argc, char **argv, char **envp) -{ - /* For dynamically linked executables the preinit array is executed by - the dynamic linker (before initializing any shared object. */ #ifndef LIBC_NONSHARED +void +__libc_csu_irel (void) +{ # ifdef USE_MULTIARCH # ifdef ELF_MACHINE_IRELA { @@ -115,7 +114,17 @@ __libc_csu_init (int argc, char **argv, char **envp) } # endif # endif +} +#endif + +void +__libc_csu_init (int argc, char **argv, char **envp) +{ + /* For dynamically linked executables the preinit array is executed by + the dynamic linker (before initializing any shared object. */ + +#ifndef LIBC_NONSHARED /* For static executables, preinit happens right before init. */ { const size_t size = __preinit_array_end - __preinit_array_start; diff --git a/csu/libc-start.c b/csu/libc-start.c index 80b672f88d..dc7ca55f09 100644 --- a/csu/libc-start.c +++ b/csu/libc-start.c @@ -24,6 +24,9 @@ #include <bp-sym.h> extern void __libc_init_first (int argc, char **argv, char **envp); +#ifndef SHARED +extern void __libc_csu_irel (void); +#endif extern int __libc_multiple_libcs; @@ -134,6 +137,9 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL), } # endif + /* Performe IREL{,A} relocations. */ + __libc_csu_irel (); + /* Initialize the thread library at least a bit since the libgcc functions are using thread functions if these are available and we need to setup errno. */ diff --git a/include/stdlib.h b/include/stdlib.h index d90e6ff4fe..f540bece9c 100644 --- a/include/stdlib.h +++ b/include/stdlib.h @@ -9,6 +9,7 @@ /* Now define the internal interfaces. */ #ifndef __Need_M_And_C +# include <sys/stat.h> __BEGIN_DECLS @@ -77,6 +78,8 @@ extern int __clearenv (void); extern char *__canonicalize_file_name (__const char *__name); extern char *__realpath (__const char *__name, char *__resolved); extern int __ptsname_r (int __fd, char *__buf, size_t __buflen); +extern int __ptsname_internal (int fd, char *buf, size_t buflen, + struct stat64 *stp); extern int __getpt (void); extern int __posix_openpt (int __oflag); diff --git a/localedata/ChangeLog b/localedata/ChangeLog index 077182b4c2..88284268a9 100644 --- a/localedata/ChangeLog +++ b/localedata/ChangeLog @@ -1,3 +1,7 @@ +2009-11-24 Ulrich Drepper <drepper@redhat.com> + + * locales/hsb_DE: Define week, first_weekday, and first_workday. + 2009-11-23 Ulrich Drepper <drepper@redhat.com> * locales/en_DK: Define week, first_weekday, and first_workday. diff --git a/localedata/locales/hsb_DE b/localedata/locales/hsb_DE index 50355af35a..0929897c8a 100644 --- a/localedata/locales/hsb_DE +++ b/localedata/locales/hsb_DE @@ -197,7 +197,7 @@ collating-symbol <SPECIAL> % letter;accent;case;specials order_start forward;backward/ - ;forward;position + ;forward;position % <CAPITAL> or <SMALL> letters first: @@ -2136,16 +2136,16 @@ END LC_NUMERIC LC_TIME abday "<U004E><U006A>";"<U0050><U00F3>";/ - "<U0057><U0075>";"<U0053><U0072>";/ - "<U0160><U0074>";"<U0050><U006A>";/ - "<U0053><U006F>" + "<U0057><U0075>";"<U0053><U0072>";/ + "<U0160><U0074>";"<U0050><U006A>";/ + "<U0053><U006F>" day "<U004E><U006A><U0065><U0064><U017A><U0065><U006C><U0061>";/ - "<U0050><U00F3><U006E><U0064><U017A><U0065><U006C><U0061>";/ - "<U0057><U0075><U0074><U006F><U0072><U0061>";/ - "<U0053><U0072><U006A><U0065><U0064><U0061>";/ - "<U0160><U0074><U0076><U00F3><U0072><U0074><U006B>";/ - "<U0050><U006A><U0061><U0074><U006B>";/ - "<U0053><U006F><U0062><U006F><U0074><U0061>" + "<U0050><U00F3><U006E><U0064><U017A><U0065><U006C><U0061>";/ + "<U0057><U0075><U0074><U006F><U0072><U0061>";/ + "<U0053><U0072><U006A><U0065><U0064><U0061>";/ + "<U0160><U0074><U0076><U00F3><U0072><U0074><U006B>";/ + "<U0050><U006A><U0061><U0074><U006B>";/ + "<U0053><U006F><U0062><U006F><U0074><U0061>" abmon "<U004A><U0061><U006E>";"<U0046><U0065><U0062>";/ "<U004D><U011B><U0072>";"<U0041><U0070><U0072>";/ "<U004D><U0065><U006A>";"<U004A><U0075><U006E>";/ @@ -2172,6 +2172,10 @@ t_fmt_ampm "" date_fmt "<U0025><U0061><U0020><U0025><U0062><U0020><U0025><U0065>/ <U0020><U0025><U0048><U003A><U0025><U004D><U003A><U0025><U0053><U0020>/ <U0025><U005A><U0020><U0025><U0059>" + +week 7;19971130;4 +first_weekday 2 +first_workday 2 END LC_TIME LC_PAPER diff --git a/login/programs/pt_chown.c b/login/programs/pt_chown.c index 7e279a5f3b..4c36f2ceac 100644 --- a/login/programs/pt_chown.c +++ b/login/programs/pt_chown.c @@ -154,8 +154,7 @@ main (int argc, char *argv[]) # define ncap_list (sizeof (cap_list) / sizeof (cap_list[0])) cap_t caps = cap_init (); if (caps == NULL) - error (FAIL_ENOMEM, errno, - _("Failed to initialize drop of capabilities")); + return FAIL_ENOMEM; /* There is no reason why these should not work. */ cap_set_flag (caps, CAP_PERMITTED, ncap_list, cap_list, CAP_SET); @@ -166,7 +165,7 @@ main (int argc, char *argv[]) cap_free (caps); if (__builtin_expect (res != 0, 0)) - error (FAIL_EXEC, errno, _("cap_set_proc failed")); + return FAIL_EXEC; } #endif diff --git a/nptl/ChangeLog b/nptl/ChangeLog index 181af50038..7e22d35cbe 100644 --- a/nptl/ChangeLog +++ b/nptl/ChangeLog @@ -1,3 +1,13 @@ +2009-11-27 Andreas Schwab <schwab@redhat.com> + + * sysdeps/unix/sysv/linux/x86_64/cancellation.S: Reload + THREAD_SELF->cancelhandling after returning from futex call. + +2009-11-24 Ulrich Drepper <drepper@redhat.com> + + * tst-sem13.c: New file. + * Makefile (tests): Add tst-sem13. + 2009-11-22 Roland McGrath <roland@redhat.com> * sysdeps/unix/sysv/linux/i386/dl-sysdep.h: # include "i686/dl-sysdep.h" diff --git a/nptl/Makefile b/nptl/Makefile index e8180021ec..34940b59d6 100644 --- a/nptl/Makefile +++ b/nptl/Makefile @@ -216,7 +216,7 @@ tests = tst-typesizes \ tst-once1 tst-once2 tst-once3 tst-once4 \ tst-key1 tst-key2 tst-key3 tst-key4 \ tst-sem1 tst-sem2 tst-sem3 tst-sem4 tst-sem5 tst-sem6 tst-sem7 \ - tst-sem8 tst-sem9 tst-sem10 tst-sem11 tst-sem12 \ + tst-sem8 tst-sem9 tst-sem10 tst-sem11 tst-sem12 tst-sem13 \ tst-barrier1 tst-barrier2 tst-barrier3 tst-barrier4 \ tst-align tst-align2 tst-align3 \ tst-basic1 tst-basic2 tst-basic3 tst-basic4 tst-basic5 tst-basic6 \ diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/cancellation.S b/nptl/sysdeps/unix/sysv/linux/x86_64/cancellation.S index 0d48ec6fcd..680696200a 100644 --- a/nptl/sysdeps/unix/sysv/linux/x86_64/cancellation.S +++ b/nptl/sysdeps/unix/sysv/linux/x86_64/cancellation.S @@ -96,8 +96,8 @@ ENTRY(__pthread_disable_asynccancel) cmpxchgl %r11d, %fs:CANCELHANDLING jnz 2b -3: movl %r11d, %eax - andl $(TCB_CANCELING_BITMASK|TCB_CANCELED_BITMASK), %eax + movl %r11d, %eax +3: andl $(TCB_CANCELING_BITMASK|TCB_CANCELED_BITMASK), %eax cmpl $TCB_CANCELING_BITMASK, %eax je 4f 1: ret @@ -111,5 +111,6 @@ ENTRY(__pthread_disable_asynccancel) addq $CANCELHANDLING, %rdi LOAD_PRIVATE_FUTEX_WAIT (%esi) syscall + movl %fs:CANCELHANDLING, %eax jmp 3b END(__pthread_disable_asynccancel) diff --git a/nptl/tst-sem13.c b/nptl/tst-sem13.c new file mode 100644 index 0000000000..8756b2262f --- /dev/null +++ b/nptl/tst-sem13.c @@ -0,0 +1,46 @@ +#include <errno.h> +#include <semaphore.h> +#include <stdio.h> +#include <unistd.h> +#include <pthread.h> +#include <internaltypes.h> + + +static int +do_test (void) +{ + union + { + sem_t s; + struct new_sem ns; + } u; + + if (sem_init (&u.s, 0, 0) != 0) + { + puts ("sem_init failed"); + return 1; + } + + struct timespec ts = { 0, 1000000001 }; /* Invalid. */ + errno = 0; + if (sem_timedwait (&u.s, &ts) >= 0) + { + puts ("sem_timedwait did not fail"); + return 1; + } + if (errno != EINVAL) + { + puts ("sem_timedwait did not fail with EINVAL"); + return 1; + } + if (u.ns.nwaiters != 0) + { + puts ("nwaiters modified"); + return 1; + } + + return 0; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/stdlib/random_r.c b/stdlib/random_r.c index 90a157f9c1..51a2e8c812 100644 --- a/stdlib/random_r.c +++ b/stdlib/random_r.c @@ -228,7 +228,7 @@ weak_alias (__srandom_r, srandom_r) lose this information and will be able to restart with setstate. Note: The first thing we do is save the current state, if any, just like setstate so that it doesn't matter when initstate is called. - Returns a pointer to the old state. */ + Returns 0 on success, non-zero on failure. */ int __initstate_r (seed, arg_state, n, buf) unsigned int seed; @@ -296,7 +296,7 @@ weak_alias (__initstate_r, initstate_r) location into the zeroth word of the state information. Note that due to the order in which things are done, it is OK to call setstate with the same state as the current state - Returns a pointer to the old state information. */ + Returns 0 on success, non-zero on failure. */ int __setstate_r (arg_state, buf) char *arg_state; diff --git a/sysdeps/unix/grantpt.c b/sysdeps/unix/grantpt.c index 8c299e9147..260e8273f8 100644 --- a/sysdeps/unix/grantpt.c +++ b/sysdeps/unix/grantpt.c @@ -38,7 +38,7 @@ this buffer, a sufficiently long buffer is allocated using malloc, and returned in PTS. 0 is returned upon success, -1 otherwise. */ static int -pts_name (int fd, char **pts, size_t buf_len) +pts_name (int fd, char **pts, size_t buf_len, struct stat64 *stp) { int rv; char *buf = *pts; @@ -49,7 +49,7 @@ pts_name (int fd, char **pts, size_t buf_len) if (buf_len) { - rv = __ptsname_r (fd, buf, buf_len); + rv = __ptsname_internal (fd, buf, buf_len, stp); if (rv != 0) { if (rv == ENOTTY) @@ -108,15 +108,8 @@ grantpt (int fd) #endif char *buf = _buf; struct stat64 st; - char *grtmpbuf; - struct group grbuf; - size_t grbuflen = __sysconf (_SC_GETGR_R_SIZE_MAX); - struct group *p; - uid_t uid; - gid_t gid; - pid_t pid; - - if (__builtin_expect (pts_name (fd, &buf, sizeof (_buf)), 0)) + + if (__builtin_expect (pts_name (fd, &buf, sizeof (_buf), &st), 0)) { int save_errno = errno; @@ -126,34 +119,42 @@ grantpt (int fd) return -1; /* If the filedescriptor is no TTY, grantpt has to set errno - to EINVAL. */ + to EINVAL. */ if (save_errno == ENOTTY) - __set_errno (EINVAL); + __set_errno (EINVAL); else __set_errno (save_errno); return -1; } - if (__xstat64 (_STAT_VER, buf, &st) < 0) - goto cleanup; - /* Make sure that we own the device. */ - uid = __getuid (); + uid_t uid = __getuid (); if (st.st_uid != uid) { if (__chown (buf, uid, st.st_gid) < 0) goto helper; } - /* Get the group ID of the special `tty' group. */ - if (grbuflen == (size_t) -1L) - /* `sysconf' does not support _SC_GETGR_R_SIZE_MAX. - Try a moderate value. */ - grbuflen = 1024; - grtmpbuf = (char *) __alloca (grbuflen); - __getgrnam_r (TTY_GROUP, &grbuf, grtmpbuf, grbuflen, &p); - gid = p ? p->gr_gid : __getgid (); + static int tty_gid = -1; + if (__builtin_expect (tty_gid == -1, 0)) + { + char *grtmpbuf; + struct group grbuf; + size_t grbuflen = __sysconf (_SC_GETGR_R_SIZE_MAX); + struct group *p; + + /* Get the group ID of the special `tty' group. */ + if (grbuflen == (size_t) -1L) + /* `sysconf' does not support _SC_GETGR_R_SIZE_MAX. + Try a moderate value. */ + grbuflen = 1024; + grtmpbuf = (char *) __alloca (grbuflen); + __getgrnam_r (TTY_GROUP, &grbuf, grtmpbuf, grbuflen, &p); + if (p != NULL) + tty_gid = p->gr_gid; + } + gid_t gid = tty_gid == -1 ? __getgid () : tty_gid; /* Make sure the group of the device is that special group. */ if (st.st_gid != gid) @@ -174,9 +175,9 @@ grantpt (int fd) goto cleanup; /* We have to use the helper program. */ - helper: + helper:; - pid = __fork (); + pid_t pid = __fork (); if (pid == -1) goto cleanup; else if (pid == 0) @@ -190,6 +191,10 @@ grantpt (int fd) if (__dup2 (fd, PTY_FILENO) < 0) _exit (FAIL_EBADF); +#ifdef CLOSE_ALL_FDS + CLOSE_ALL_FDS (); +#endif + execle (_PATH_PT_CHOWN, basename (_PATH_PT_CHOWN), NULL, NULL); _exit (FAIL_EXEC); } diff --git a/sysdeps/unix/sysv/linux/grantpt.c b/sysdeps/unix/sysv/linux/grantpt.c new file mode 100644 index 0000000000..f2fc60f83a --- /dev/null +++ b/sysdeps/unix/sysv/linux/grantpt.c @@ -0,0 +1,42 @@ +#include <assert.h> +#include <ctype.h> +#include <dirent.h> +#include <errno.h> +#include <fcntl.h> +#include <paths.h> +#include <stdlib.h> +#include <unistd.h> + +#include "not-cancel.h" +#include "pty-private.h" + + +/* Close all file descriptors except the one specified. */ +static void +close_all_fds (void) +{ + DIR *dir = __opendir ("/proc/self/fd"); + if (dir != NULL) + { + struct dirent64 *d; + while ((d = __readdir64 (dir)) != NULL) + if (isdigit (d->d_name[0])) + { + char *endp; + long int fd = strtol (d->d_name, &endp, 10); + if (*endp == '\0' && fd != PTY_FILENO && fd != dirfd (dir)) + close_not_cancel_no_status (fd); + } + + __closedir (dir); + + int nullfd = open_not_cancel_2 (_PATH_DEVNULL, O_RDONLY); + assert (nullfd == STDIN_FILENO); + nullfd = open_not_cancel_2 (_PATH_DEVNULL, O_WRONLY); + assert (nullfd == STDOUT_FILENO); + __dup2 (STDOUT_FILENO, STDERR_FILENO); + } +} +#define CLOSE_ALL_FDS() close_all_fds() + +#include <sysdeps/unix/grantpt.c> diff --git a/sysdeps/unix/sysv/linux/ptsname.c b/sysdeps/unix/sysv/linux/ptsname.c index 9c364b18b4..129d09085e 100644 --- a/sysdeps/unix/sysv/linux/ptsname.c +++ b/sysdeps/unix/sysv/linux/ptsname.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1998, 2000, 2001, 2002 Free Software Foundation, Inc. +/* Copyright (C) 1998, 2000, 2001, 2002, 2009 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Zack Weinberg <zack@rabi.phys.columbia.edu>, 1998. @@ -67,14 +67,10 @@ ptsname (int fd) } -/* Store at most BUFLEN characters of the pathname of the slave pseudo - terminal associated with the master FD is open on in BUF. - Return 0 on success, otherwise an error number. */ int -__ptsname_r (int fd, char *buf, size_t buflen) +__ptsname_internal (int fd, char *buf, size_t buflen, struct stat64 *stp) { int save_errno = errno; - struct stat64 st; unsigned int ptyno; if (buf == NULL) @@ -93,7 +89,7 @@ __ptsname_r (int fd, char *buf, size_t buflen) if (__ioctl (fd, TIOCGPTN, &ptyno) == 0) { /* Buffer we use to print the number in. For a maximum size for - `int' of 8 bytes we never need more than 20 digits. */ + `int' of 8 bytes we never need more than 20 digits. */ char numbuf[21]; const char *devpts = _PATH_DEVPTS; const size_t devptslen = strlen (_PATH_DEVPTS); @@ -121,21 +117,23 @@ __ptsname_r (int fd, char *buf, size_t buflen) return ERANGE; } - if (__fxstat64 (_STAT_VER, fd, &st) < 0) + if (__fxstat64 (_STAT_VER, fd, stp) < 0) return errno; /* Check if FD really is a master pseudo terminal. */ - if (! MASTER_P (st.st_rdev)) + if (! MASTER_P (stp->st_rdev)) { __set_errno (ENOTTY); return ENOTTY; } - ptyno = minor (st.st_rdev); + ptyno = minor (stp->st_rdev); +#if __LINUX_KERNEL_VERSION >= 131443 /* This is for the old BSD pseudo terminals. As of Linux - 2.1.115 these are no longer supported. */ - if (major (st.st_rdev) == 4) + 2.1.115 these are no longer supported. */ + if (major (stp->st_rdev) == 4) ptyno -= 128; +#endif if (ptyno / 16 >= strlen (__libc_ptyname1)) { @@ -149,12 +147,12 @@ __ptsname_r (int fd, char *buf, size_t buflen) p[2] = '\0'; } - if (__xstat64 (_STAT_VER, buf, &st) < 0) + if (__xstat64 (_STAT_VER, buf, stp) < 0) return errno; /* Check if the name we're about to return really corresponds to a slave pseudo terminal. */ - if (! S_ISCHR (st.st_mode) || ! SLAVE_P (st.st_rdev)) + if (! S_ISCHR (stp->st_mode) || ! SLAVE_P (stp->st_rdev)) { /* This really is a configuration problem. */ __set_errno (ENOTTY); @@ -164,4 +162,15 @@ __ptsname_r (int fd, char *buf, size_t buflen) __set_errno (save_errno); return 0; } + + +/* Store at most BUFLEN characters of the pathname of the slave pseudo + terminal associated with the master FD is open on in BUF. + Return 0 on success, otherwise an error number. */ +int +__ptsname_r (int fd, char *buf, size_t buflen) +{ + struct stat64 st; + return __ptsname_internal (fd, buf, buflen, &st); +} weak_alias (__ptsname_r, ptsname_r) |