From: Paolo 'Blaisorblade' Giarrusso From: Bodo Stroesser , Paolo 'Blaisorblade' Giarrusso Cc: Ulrich Drepper Using NPTL, getpid() sometimes delivers the wrong pid, since it uses the one buffered in TLS from previous calls. This buffered pid isn't discarded, when a child is created by a clone(). So, as a workaround, UML should use a direct kernel call to bypass the lib. Also, I (Paolo) went replacing all remaining calls of getpid() with os_getpid(), to make sure they use the syscall and not the normal glibc definition. Signed-off-by: Bodo Stroesser Signed-off-by: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton --- 25-akpm/arch/um/kernel/frame.c | 8 ++++---- 25-akpm/arch/um/kernel/main.c | 3 ++- 25-akpm/arch/um/kernel/skas/process.c | 2 +- 25-akpm/arch/um/os-Linux/process.c | 4 ++++ 4 files changed, 11 insertions(+), 6 deletions(-) diff -puN arch/um/kernel/frame.c~uml-use-sys_getpid-bypassing-glibc-fixes-uml-on-gentoo arch/um/kernel/frame.c --- 25/arch/um/kernel/frame.c~uml-use-sys_getpid-bypassing-glibc-fixes-uml-on-gentoo Wed Nov 10 13:40:04 2004 +++ 25-akpm/arch/um/kernel/frame.c Wed Nov 10 13:40:04 2004 @@ -140,7 +140,7 @@ static void child_common(struct common_r } if(sigaltstack(&ss, NULL) < 0){ printf("sigaltstack failed - errno = %d\n", errno); - kill(getpid(), SIGKILL); + kill(os_getpid(), SIGKILL); } if(restorer){ @@ -162,7 +162,7 @@ static void child_common(struct common_r if(err < 0){ printf("sigaction failed - errno = %d\n", errno); - kill(getpid(), SIGKILL); + kill(os_getpid(), SIGKILL); } os_stop_process(os_getpid()); @@ -191,7 +191,7 @@ static void sc_handler(int sig, struct s setup_arch_frame_raw(&raw_sc->common.arch, &sc + 1, raw_sc->common.sr); os_stop_process(os_getpid()); - kill(getpid(), SIGKILL); + kill(os_getpid(), SIGKILL); } static int sc_child(void *arg) @@ -229,7 +229,7 @@ static void si_handler(int sig, siginfo_ ucontext->uc_mcontext.fpregs, raw_si->common.sr); os_stop_process(os_getpid()); - kill(getpid(), SIGKILL); + kill(os_getpid(), SIGKILL); } static int si_child(void *arg) diff -puN arch/um/kernel/main.c~uml-use-sys_getpid-bypassing-glibc-fixes-uml-on-gentoo arch/um/kernel/main.c --- 25/arch/um/kernel/main.c~uml-use-sys_getpid-bypassing-glibc-fixes-uml-on-gentoo Wed Nov 10 13:40:04 2004 +++ 25-akpm/arch/um/kernel/main.c Wed Nov 10 13:40:04 2004 @@ -26,6 +26,7 @@ #include "uml-config.h" #include "irq_user.h" #include "time_user.h" +#include "os.h" /* Set in set_stklim, which is called from main and __wrap_malloc. * __wrap_malloc only calls it if main hasn't started. @@ -175,7 +176,7 @@ int main(int argc, char **argv, char **e } #define CAN_KMALLOC() \ - (kmalloc_ok && CHOOSE_MODE((getpid() != tracing_pid), 1)) + (kmalloc_ok && CHOOSE_MODE((os_getpid() != tracing_pid), 1)) extern void *__real_malloc(int); diff -puN arch/um/kernel/skas/process.c~uml-use-sys_getpid-bypassing-glibc-fixes-uml-on-gentoo arch/um/kernel/skas/process.c --- 25/arch/um/kernel/skas/process.c~uml-use-sys_getpid-bypassing-glibc-fixes-uml-on-gentoo Wed Nov 10 13:40:04 2004 +++ 25-akpm/arch/um/kernel/skas/process.c Wed Nov 10 13:40:04 2004 @@ -30,7 +30,7 @@ int is_skas_winch(int pid, int fd, void *data) { - if(pid != getpid()) + if(pid != os_getpid()) return(0); register_winch_irq(-1, fd, -1, data); diff -puN arch/um/os-Linux/process.c~uml-use-sys_getpid-bypassing-glibc-fixes-uml-on-gentoo arch/um/os-Linux/process.c --- 25/arch/um/os-Linux/process.c~uml-use-sys_getpid-bypassing-glibc-fixes-uml-on-gentoo Wed Nov 10 13:40:04 2004 +++ 25-akpm/arch/um/os-Linux/process.c Wed Nov 10 13:40:04 2004 @@ -107,6 +107,10 @@ void os_usr1_process(int pid) kill(pid, SIGUSR1); } +/*Don't use the glibc version, which caches the result in TLS. It misses some + * syscalls, and also breaks with clone(), which does not unshare the TLS.*/ +inline _syscall0(pid_t, getpid) + int os_getpid(void) { return(getpid()); _