From 22357ca388fe6c5f34aedefd9b69bc6992b4b571 Mon Sep 17 00:00:00 2001
From: Eric Pouech <eric.pouech@wanadoo.fr>
Date: Tue, 14 Feb 2006 12:24:32 +0100
Subject: [PATCH] server: When possible, use tgkill instead of tkill syscall on
 Linux.

---
 server/context_alpha.c   |  2 +-
 server/context_i386.c    | 12 ++++++++++--
 server/context_powerpc.c |  2 +-
 server/context_sparc.c   |  2 +-
 server/context_x86_64.c  |  2 +-
 server/ptrace.c          |  2 +-
 server/thread.h          |  2 +-
 7 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/server/context_alpha.c b/server/context_alpha.c
index 1f82d8eec15..41771bf00e3 100644
--- a/server/context_alpha.c
+++ b/server/context_alpha.c
@@ -341,7 +341,7 @@ int get_thread_single_step( struct thread *thread )
 }
 
 /* send a signal to a specific thread */
-int tkill( int pid, int sig )
+int tkill( int tgid, int pid, int sig )
 {
     /* FIXME: should do something here */
     errno = ENOSYS;
diff --git a/server/context_i386.c b/server/context_i386.c
index 52b33aaa705..cf334cb7cbf 100644
--- a/server/context_i386.c
+++ b/server/context_i386.c
@@ -560,16 +560,24 @@ int get_thread_single_step( struct thread *thread )
 }
 
 /* send a signal to a specific thread */
-int tkill( int pid, int sig )
+int tkill( int tgid, int pid, int sig )
 {
 #ifdef __linux__
     int ret;
+
     __asm__( "pushl %%ebx\n\t"
              "movl %2,%%ebx\n\t"
              "int $0x80\n\t"
              "popl %%ebx\n\t"
              : "=a" (ret)
-             : "0" (238) /*SYS_tkill*/, "r" (pid), "c" (sig) );
+             : "0" (270) /*SYS_tgkill*/, "r" (tgid), "c" (pid), "d" (sig) );
+    if (ret == -ENOSYS)
+        __asm__( "pushl %%ebx\n\t"
+                 "movl %2,%%ebx\n\t"
+                 "int $0x80\n\t"
+                 "popl %%ebx\n\t"
+                 : "=a" (ret)
+                 : "0" (238) /*SYS_tkill*/, "r" (pid), "c" (sig) );
     if (ret >= 0) return ret;
     errno = -ret;
     return -1;
diff --git a/server/context_powerpc.c b/server/context_powerpc.c
index 72947e0f181..9a438b97902 100644
--- a/server/context_powerpc.c
+++ b/server/context_powerpc.c
@@ -286,7 +286,7 @@ int get_thread_single_step( struct thread *thread )
 }
 
 /* send a signal to a specific thread */
-int tkill( int pid, int sig )
+int tkill( int tgid, int pid, int sig )
 {
     /* FIXME: should do something here */
     errno = ENOSYS;
diff --git a/server/context_sparc.c b/server/context_sparc.c
index b718ff37198..39c3dd33613 100644
--- a/server/context_sparc.c
+++ b/server/context_sparc.c
@@ -179,7 +179,7 @@ int get_thread_single_step( struct thread *thread )
 }
 
 /* send a signal to a specific thread */
-int tkill( int pid, int sig )
+int tkill( int tgid, int pid, int sig )
 {
     /* FIXME: should do something here */
     errno = ENOSYS;
diff --git a/server/context_x86_64.c b/server/context_x86_64.c
index c102510187b..ee8bb318e1e 100644
--- a/server/context_x86_64.c
+++ b/server/context_x86_64.c
@@ -271,7 +271,7 @@ int get_thread_single_step( struct thread *thread )
 }
 
 /* send a signal to a specific thread */
-int tkill( int pid, int sig )
+int tkill( int tgid, int pid, int sig )
 {
 #ifdef __linux__
     int ret;
diff --git a/server/ptrace.c b/server/ptrace.c
index e4cf889d2a7..d7134f2b1de 100644
--- a/server/ptrace.c
+++ b/server/ptrace.c
@@ -187,7 +187,7 @@ int send_thread_signal( struct thread *thread, int sig )
     {
         if (thread->unix_tid != -1)
         {
-            ret = tkill( thread->unix_tid, sig );
+            ret = tkill( thread->unix_pid, thread->unix_tid, sig );
             if (ret == -1 && errno == ENOSYS) ret = kill( thread->unix_pid, sig );
         }
         else ret = kill( thread->unix_pid, sig );
diff --git a/server/thread.h b/server/thread.h
index 01e12184a8b..3bcc576ca31 100644
--- a/server/thread.h
+++ b/server/thread.h
@@ -132,7 +132,7 @@ extern void *get_thread_ip( struct thread *thread );
 extern int get_thread_single_step( struct thread *thread );
 extern void get_thread_context( struct thread *thread, CONTEXT *context, unsigned int flags );
 extern void set_thread_context( struct thread *thread, const CONTEXT *context, unsigned int flags );
-extern int tkill( int pid, int sig );
+extern int tkill( int tgid, int pid, int sig );
 extern int send_thread_signal( struct thread *thread, int sig );
 
 extern unsigned int global_error;  /* global error code for when no thread is current */
-- 
GitLab