server: When possible, use tgkill instead of tkill syscall on Linux.
diff --git a/server/context_alpha.c b/server/context_alpha.c
index 1f82d8e..41771bf 100644
--- a/server/context_alpha.c
+++ b/server/context_alpha.c
@@ -341,7 +341,7 @@
}
/* 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 52b33aa..cf334cb 100644
--- a/server/context_i386.c
+++ b/server/context_i386.c
@@ -560,16 +560,24 @@
}
/* 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 72947e0..9a438b9 100644
--- a/server/context_powerpc.c
+++ b/server/context_powerpc.c
@@ -286,7 +286,7 @@
}
/* 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 b718ff3..39c3dd3 100644
--- a/server/context_sparc.c
+++ b/server/context_sparc.c
@@ -179,7 +179,7 @@
}
/* 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 c102510..ee8bb31 100644
--- a/server/context_x86_64.c
+++ b/server/context_x86_64.c
@@ -271,7 +271,7 @@
}
/* 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 e4cf889..d7134f2 100644
--- a/server/ptrace.c
+++ b/server/ptrace.c
@@ -187,7 +187,7 @@
{
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 01e12184..3bcc576 100644
--- a/server/thread.h
+++ b/server/thread.h
@@ -132,7 +132,7 @@
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 */