Added send_thread_signal() function and properly handle errors caused
by the thread having already died when we send it a signal.
Use -1 instead of 0 as invalid Unix pid value.

diff --git a/server/console.c b/server/console.c
index 330daac..2cd08ff 100644
--- a/server/console.c
+++ b/server/console.c
@@ -416,7 +416,7 @@
         while (thread)
         {
             struct thread *next = thread->proc_next;
-            kill( thread->unix_pid, csi->signal );
+            send_thread_signal( thread, csi->signal );
             thread = next;
         }
     }
diff --git a/server/debugger.c b/server/debugger.c
index fdd7461..0e9b875 100644
--- a/server/debugger.c
+++ b/server/debugger.c
@@ -720,11 +720,7 @@
         struct thread *thread;
         for (thread = process->thread_list; thread; thread = thread->proc_next)
         {
-            if (thread->unix_pid)
-            {
-                kill( thread->unix_pid, SIGTRAP );
-                break;
-            }
+            if (send_thread_signal( thread, SIGTRAP )) break;
         }
         if (!thread) set_error( STATUS_ACCESS_DENIED );
     }
diff --git a/server/process.c b/server/process.c
index be62975..785c4cb 100644
--- a/server/process.c
+++ b/server/process.c
@@ -969,7 +969,7 @@
 /* initialize a new process */
 DECL_HANDLER(init_process)
 {
-    if (!current->unix_pid)
+    if (current->unix_pid == -1)
     {
         fatal_protocol_error( current, "init_process: init_thread not called yet\n" );
         return;
diff --git a/server/ptrace.c b/server/ptrace.c
index 2c0c12b..b83ab7d 100644
--- a/server/ptrace.c
+++ b/server/ptrace.c
@@ -93,7 +93,7 @@
     if (thread && (WIFSIGNALED(status) || WIFEXITED(status)))
     {
         thread->attached = 0;
-        thread->unix_pid = 0;
+        thread->unix_pid = -1;
         if (debug_level)
         {
             if (WIFSIGNALED(status))
@@ -136,6 +136,23 @@
     } while (res && res != signal);
 }
 
+/* send a Unix signal to a specific thread */
+int send_thread_signal( struct thread *thread, int sig )
+{
+    int ret = -1;
+
+    if (thread->unix_pid != -1)
+    {
+        ret = kill( thread->unix_pid, sig );
+        if (ret == -1 && errno == ESRCH) /* thread got killed */
+        {
+            thread->unix_pid = -1;
+            thread->attached = 0;
+        }
+    }
+    return (ret != -1);
+}
+
 /* attach to a Unix thread */
 static int attach_thread( struct thread *thread )
 {
@@ -143,7 +160,7 @@
     if (!use_ptrace) return 0;
     if (ptrace( PTRACE_ATTACH, thread->unix_pid, 0, 0 ) == -1)
     {
-        if (errno == ESRCH) thread->unix_pid = 0;  /* process got killed */
+        if (errno == ESRCH) thread->unix_pid = -1;  /* thread got killed */
         return 0;
     }
     if (debug_level) fprintf( stderr, "%04x: *attached*\n", thread->id );
@@ -155,12 +172,13 @@
 /* detach from a Unix thread and kill it */
 void detach_thread( struct thread *thread, int sig )
 {
-    if (!thread->unix_pid) return;
+    if (thread->unix_pid == -1) return;
     if (thread->attached)
     {
         /* make sure it is stopped */
         suspend_thread( thread, 0 );
-        if (sig) kill( thread->unix_pid, sig );
+        if (sig) send_thread_signal( thread, sig );
+        if (thread->unix_pid == -1) return;
         if (debug_level) fprintf( stderr, "%04x: *detached*\n", thread->id );
         ptrace( PTRACE_DETACH, thread->unix_pid, (caddr_t)1, sig );
         thread->suspend = 0;  /* detach makes it continue */
@@ -168,7 +186,7 @@
     }
     else
     {
-        if (sig) kill( thread->unix_pid, sig );
+        if (sig) send_thread_signal( thread, sig );
         if (thread->suspend + thread->process->suspend) continue_thread( thread );
     }
 }
@@ -177,21 +195,21 @@
 void stop_thread( struct thread *thread )
 {
     /* can't stop a thread while initialisation is in progress */
-    if (!thread->unix_pid || !is_process_init_done(thread->process)) return;
+    if (thread->unix_pid == -1 || !is_process_init_done(thread->process)) return;
     /* first try to attach to it */
     if (!thread->attached)
         if (attach_thread( thread )) return;  /* this will have stopped it */
     /* attached already, or attach failed -> send a signal */
-    if (!thread->unix_pid) return;
-    kill( thread->unix_pid, SIGSTOP );
+    if (thread->unix_pid == -1) return;
+    send_thread_signal( thread, SIGSTOP );
     if (thread->attached) wait4_thread( thread, SIGSTOP );
 }
 
 /* make a thread continue (at the Unix level) */
 void continue_thread( struct thread *thread )
 {
-    if (!thread->unix_pid) return;
-    if (!thread->attached) kill( thread->unix_pid, SIGCONT );
+    if (thread->unix_pid == -1) return;
+    if (!thread->attached) send_thread_signal( thread, SIGCONT );
     else ptrace( get_thread_single_step(thread) ? PTRACE_SINGLESTEP : PTRACE_CONT,
                  thread->unix_pid, (caddr_t)1, SIGSTOP );
 }
@@ -206,7 +224,7 @@
         return 1;
     }
     /* can't stop a thread while initialisation is in progress */
-    if (!thread->unix_pid || !is_process_init_done(thread->process)) goto error;
+    if (thread->unix_pid == -1 || !is_process_init_done(thread->process)) goto error;
     thread->suspend++;
     if (attach_thread( thread )) return 1;
     thread->suspend--;
diff --git a/server/thread.c b/server/thread.c
index 2b53d59..1a9244f 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -108,7 +108,7 @@
 {
     int i;
 
-    thread->unix_pid        = 0;  /* not known yet */
+    thread->unix_pid        = -1;  /* not known yet */
     thread->context         = NULL;
     thread->teb             = NULL;
     thread->mutex           = NULL;
@@ -814,7 +814,7 @@
     int reply_fd = thread_get_inflight_fd( current, req->reply_fd );
     int wait_fd = thread_get_inflight_fd( current, req->wait_fd );
 
-    if (current->unix_pid)
+    if (current->unix_pid != -1)
     {
         fatal_protocol_error( current, "init_thread: already running\n" );
         goto error;
diff --git a/server/thread.h b/server/thread.h
index 250174f..a46f389 100644
--- a/server/thread.h
+++ b/server/thread.h
@@ -135,6 +135,7 @@
 extern int write_thread_int( struct thread *thread, int *addr, int data, unsigned int mask );
 extern void *get_thread_ip( struct thread *thread );
 extern int get_thread_single_step( struct thread *thread );
+extern int send_thread_signal( struct thread *thread, int sig );
 
 extern unsigned int global_error;  /* global error code for when no thread is current */