diff options
Diffstat (limited to 'nptl')
-rw-r--r-- | nptl/ChangeLog | 15 | ||||
-rw-r--r-- | nptl/allocatestack.c | 9 | ||||
-rw-r--r-- | nptl/descr.h | 3 | ||||
-rw-r--r-- | nptl/init.c | 10 | ||||
-rw-r--r-- | nptl/pthread_cancel.c | 17 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/fork.c | 3 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/pt-raise.c | 16 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/pthread_kill.c | 15 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/raise.c | 15 |
9 files changed, 94 insertions, 9 deletions
diff --git a/nptl/ChangeLog b/nptl/ChangeLog index 9dd2465d5b..4fa3910bac 100644 --- a/nptl/ChangeLog +++ b/nptl/ChangeLog @@ -1,3 +1,18 @@ +2003-07-07 Ulrich Drepper <drepper@redhat.com> + + * descr.h (struct pthread): Add pid field. + * allocatestack.c (allocate_stack): Initialize pid field in descriptor. + (__reclaim_stacks): Likewise. + * init.c (sigcancel_handler): If __ASSUME_CORRECT_SI_PID is defined + also check for PID of the signal source. + (__pthread_initialize_minimal_internal): Also initialize pid field + of initial thread's descriptor. + * pthread_cancel.c: Use tgkill instead of tkill if possible. + * sysdeps/unix/sysv/linux/fork.c: Likewise. + * sysdeps/unix/sysv/linux/pt-raise.c: Likewise. + * sysdeps/unix/sysv/linux/pthread_kill.c: Likewise. + * sysdeps/unix/sysv/linux/raise.c: Likewise. + 2003-07-05 Ulrich Drepper <drepper@redhat.com> * sysdeps/pthread/bits/libc-lock.h (__libc_cleanup_push): Renamed. diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c index 223f0e445d..e042cf4840 100644 --- a/nptl/allocatestack.c +++ b/nptl/allocatestack.c @@ -332,6 +332,9 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp, pd->header.sysinfo = THREAD_GETMEM (THREAD_SELF, header.sysinfo); #endif + /* The process ID is also the same as that of the caller. */ + pd->pid = THREAD_GETMEM (THREAD_SELF, pid); + /* Allocate the DTV for this thread. */ if (_dl_allocate_tls (TLS_TPADJ (pd)) == NULL) /* Something went wrong. */ @@ -464,6 +467,9 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp, pd->header.sysinfo = THREAD_GETMEM (THREAD_SELF, header.sysinfo); #endif + /* The process ID is also the same as that of the caller. */ + pd->pid = THREAD_GETMEM (THREAD_SELF, pid); + /* Allocate the DTV for this thread. */ if (_dl_allocate_tls (TLS_TPADJ (pd)) == NULL) { @@ -626,6 +632,9 @@ __reclaim_stacks (void) /* This marks the stack as free. */ curp->tid = 0; + /* The PID field must be initialized for the new process. */ + curp->pid = self->pid; + /* Account for the size of the stack. */ stack_cache_actsize += curp->stackblock_size; } diff --git a/nptl/descr.h b/nptl/descr.h index 26ee42d7c3..fb364b95ca 100644 --- a/nptl/descr.h +++ b/nptl/descr.h @@ -177,6 +177,9 @@ struct pthread /* Two-level array for the thread-specific data. */ struct pthread_key_data *specific[PTHREAD_KEY_1STLEVEL_SIZE]; + /* Process ID - thread group ID in kernel speak. */ + pid_t pid; + /* True if events must be reported. */ bool report_events; diff --git a/nptl/init.c b/nptl/init.c index abc785730a..9c76773504 100644 --- a/nptl/init.c +++ b/nptl/init.c @@ -139,10 +139,12 @@ sigcancel_handler (int sig, siginfo_t *si, void *ctx) correct and might even be a security problem. Try to catch as many incorrect invocations as possible. */ if (sig != SIGCANCEL +#ifdef __ASSUME_CORRECT_SI_PID + /* Kernels before 2.5.75 stored the thread ID and not the process + ID in si_pid so we skip this test. */ + || si->si_pid != THREAD_GETMEM (THREAD_SELF, pid) +#endif || si->si_code != SI_TKILL) - /* XXX The Linux kernel currently does not report the correct PID - in the si->si_pid field. Once this is changed another test - will be added. */ return; struct pthread *self = THREAD_SELF; @@ -202,7 +204,7 @@ __pthread_initialize_minimal_internal (void) /* Minimal initialization of the thread descriptor. */ struct pthread *pd = THREAD_SELF; INTERNAL_SYSCALL_DECL (err); - pd->tid = INTERNAL_SYSCALL (set_tid_address, err, 1, &pd->tid); + pd->pid = pd->tid = INTERNAL_SYSCALL (set_tid_address, err, 1, &pd->tid); 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_cancel.c b/nptl/pthread_cancel.c index 43b65b6c02..9e3dfda6b3 100644 --- a/nptl/pthread_cancel.c +++ b/nptl/pthread_cancel.c @@ -22,6 +22,7 @@ #include "pthreadP.h" #include "atomic.h" #include <sysdep.h> +#include <kernel-features.h> int @@ -61,7 +62,21 @@ pthread_cancel (th) thread as canceled. */ INTERNAL_SYSCALL_DECL (err); - int val = INTERNAL_SYSCALL (tkill, err, 2, pd->tid, SIGCANCEL); + int val; +#if __ASSUME_TGKILL + val = INTERNAL_SYSCALL (tgkill, err, 3, + THREAD_GETMEM (THREAD_SELF, pid), pd->tid, + SIGCANCEL); +#else +# ifdef __NR_tgkill + val = INTERNAL_SYSCALL (tgkill, err, 3, + THREAD_GETMEM (THREAD_SELF, pid), pd->tid, + SIGCANCEL); + if (INTERNAL_SYSCALL_ERROR_P (val, err) + && INTERNAL_SYSCALL_ERRNO (val, err) == ENOSYS) +# endif + val = INTERNAL_SYSCALL (tkill, err, 2, pd->tid, SIGCANCEL); +#endif if (INTERNAL_SYSCALL_ERROR_P (val, err)) result = INTERNAL_SYSCALL_ERRNO (val, err); diff --git a/nptl/sysdeps/unix/sysv/linux/fork.c b/nptl/sysdeps/unix/sysv/linux/fork.c index 8bca6b4ab3..43e1b43e2b 100644 --- a/nptl/sysdeps/unix/sysv/linux/fork.c +++ b/nptl/sysdeps/unix/sysv/linux/fork.c @@ -134,6 +134,9 @@ __libc_fork (void) if (__fork_generation_pointer != NULL) *__fork_generation_pointer += 4; + /* Adjust the PID field for the new process. */ + self->pid = self->tid; + #if HP_TIMING_AVAIL /* The CPU clock of the thread and process have to be set to zero. */ hp_timing_t now; diff --git a/nptl/sysdeps/unix/sysv/linux/pt-raise.c b/nptl/sysdeps/unix/sysv/linux/pt-raise.c index 0c68960e5d..2efd7616bf 100644 --- a/nptl/sysdeps/unix/sysv/linux/pt-raise.c +++ b/nptl/sysdeps/unix/sysv/linux/pt-raise.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002 Free Software Foundation, Inc. +/* Copyright (C) 2002, 2003 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. @@ -21,11 +21,23 @@ #include <signal.h> #include <sysdep.h> #include <tls.h> +#include <kernel-features.h> int raise (sig) int sig; { - return INLINE_SYSCALL (tkill, 2, THREAD_SELF->tid, sig); +#if __ASSUME_TGKILL + return INLINE_SYSCALL (tgkill, 3, THREAD_GETMEM (THREAD_SELF, pid), + THREAD_GETMEM (THREAD_SELF, tid), sig); +#else +# ifdef __NR_tgkill + int res = INLINE_SYSCALL (tgkill, 3, THREAD_GETMEM (THREAD_SELF, pid), + THREAD_GETMEM (THREAD_SELF, tid), sig); + if (res != -1 || errno != ENOSYS) + return res; +# endif + return INLINE_SYSCALL (tkill, 2, THREAD_GETMEM (THREAD_SELF, tid), sig); +#endif } diff --git a/nptl/sysdeps/unix/sysv/linux/pthread_kill.c b/nptl/sysdeps/unix/sysv/linux/pthread_kill.c index 8da195aa0a..6967acd92b 100644 --- a/nptl/sysdeps/unix/sysv/linux/pthread_kill.c +++ b/nptl/sysdeps/unix/sysv/linux/pthread_kill.c @@ -22,6 +22,7 @@ #include <pthreadP.h> #include <tls.h> #include <sysdep.h> +#include <kernel-features.h> int @@ -43,7 +44,19 @@ __pthread_kill (threadid, signo) /* We have a special syscall to do the work. */ INTERNAL_SYSCALL_DECL (err); - int val = INTERNAL_SYSCALL (tkill, err, 2, pd->tid, signo); + int val; +#if __ASSUME_TGKILL + val = INTERNAL_SYSCALL (tgkill, err, 3, THREAD_GETMEM (THREAD_SELF, pid), + pd->tid, signo); +#else +# ifdef __NR_tgkill + val = INTERNAL_SYSCALL (tgkill, err, 3, THREAD_GETMEM (THREAD_SELF, pid), + pd->tid, signo); + if (INTERNAL_SYSCALL_ERROR_P (val, err) + && INTERNAL_SYSCALL_ERRNO (val, err) == ENOSYS) +# endif + val = INTERNAL_SYSCALL (tkill, err, 2, pd->tid, signo); +#endif return (INTERNAL_SYSCALL_ERROR_P (val, err) ? INTERNAL_SYSCALL_ERRNO (val, err) : 0); diff --git a/nptl/sysdeps/unix/sysv/linux/raise.c b/nptl/sysdeps/unix/sysv/linux/raise.c index 24a00b1e4d..25d3ed8afd 100644 --- a/nptl/sysdeps/unix/sysv/linux/raise.c +++ b/nptl/sysdeps/unix/sysv/linux/raise.c @@ -21,6 +21,7 @@ #include <signal.h> #include <sysdep.h> #include <nptl/pthreadP.h> +#include <kernel-features.h> int @@ -28,7 +29,7 @@ raise (sig) int sig; { struct pthread *pd = THREAD_SELF; - pid_t selftid = pd->tid; + pid_t selftid = THREAD_GETMEM (pd, tid); if (selftid == 0) { /* This system call is not supposed to fail. */ @@ -39,9 +40,21 @@ raise (sig) selftid = INLINE_SYSCALL (gettid, 0); #endif THREAD_SETMEM (pd, tid, selftid); + + /* In this case the TID and PID are the same. */ + THREAD_SETMEM (pd, pid, selftid); } +#if __ASSUME_TGKILL + return INLINE_SYSCALL (tgkill, 3, THREAD_GETMEM (pd, pid), selftid, sig); +#else +# ifdef __NR_tgkill + int res = INLINE_SYSCALL (tgkill, 3, THREAD_GETMEM (pd, pid), selftid, sig); + if (res != -1 || errno != ENOSYS) + return res; +# endif return INLINE_SYSCALL (tkill, 2, selftid, sig); +#endif } libc_hidden_def (raise) weak_alias (raise, gsignal) |