Attaching the debugger to a running process should work again
(reported by Eric Pouech). Misc cleanups.

diff --git a/server/ptrace.c b/server/ptrace.c
index ae35c23..e2b19fc 100644
--- a/server/ptrace.c
+++ b/server/ptrace.c
@@ -123,7 +123,7 @@
 
     do
     {
-        if ((res = wait4( thread->unix_pid, &status, WUNTRACED, NULL )) == -1)
+        if ((res = wait4( get_ptrace_pid(thread), &status, WUNTRACED, NULL )) == -1)
         {
             if (errno == ECHILD)  /* must have died */
             {
@@ -137,6 +137,12 @@
     } while (res && res != signal);
 }
 
+/* return the Unix pid to use in ptrace calls for a given thread */
+int get_ptrace_pid( struct thread *thread )
+{
+    return thread->unix_pid;
+}
+
 /* send a Unix signal to a specific thread */
 int send_thread_signal( struct thread *thread, int sig )
 {
@@ -159,7 +165,7 @@
 {
     /* this may fail if the client is already being debugged */
     if (!use_ptrace) return 0;
-    if (ptrace( PTRACE_ATTACH, thread->unix_pid, 0, 0 ) == -1)
+    if (ptrace( PTRACE_ATTACH, get_ptrace_pid(thread), 0, 0 ) == -1)
     {
         if (errno == ESRCH) thread->unix_pid = -1;  /* thread got killed */
         return 0;
@@ -181,12 +187,43 @@
         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 );
+        ptrace( PTRACE_DETACH, get_ptrace_pid(thread), (caddr_t)1, sig );
         thread->attached = 0;
     }
     else if (sig) send_thread_signal( thread, sig );
 }
 
+/* attach to a Unix process with ptrace */
+int attach_process( struct process *process )
+{
+    struct thread *thread;
+    int ret = 1;
+
+    if (!process->thread_list)  /* need at least one running thread */
+    {
+        set_error( STATUS_ACCESS_DENIED );
+        return 0;
+    }
+    for (thread = process->thread_list; thread; thread = thread->proc_next)
+    {
+        if (thread->attached) continue;
+        if (suspend_for_ptrace( thread )) resume_after_ptrace( thread );
+        else ret = 0;
+    }
+    return ret;
+}
+
+/* detach from a ptraced Unix process */
+void detach_process( struct process *process )
+{
+    struct thread *thread;
+
+    for (thread = process->thread_list; thread; thread = thread->proc_next)
+    {
+        if (thread->attached) detach_thread( thread, 0 );
+    }
+}
+
 /* suspend a thread to allow using ptrace on it */
 /* you must do a resume_after_ptrace when finished with the thread */
 int suspend_for_ptrace( struct thread *thread )
@@ -212,14 +249,14 @@
     if (thread->unix_pid == -1) return;
     assert( thread->attached );
     ptrace( get_thread_single_step(thread) ? PTRACE_SINGLESTEP : PTRACE_CONT,
-            thread->unix_pid, (caddr_t)1, 0 /* cancel the SIGSTOP */ );
+            get_ptrace_pid(thread), (caddr_t)1, 0 /* cancel the SIGSTOP */ );
 }
 
 /* read an int from a thread address space */
 int read_thread_int( struct thread *thread, const int *addr, int *data )
 {
     errno = 0;
-    *data = ptrace( PTRACE_PEEKDATA, thread->unix_pid, (caddr_t)addr, 0 );
+    *data = ptrace( PTRACE_PEEKDATA, get_ptrace_pid(thread), (caddr_t)addr, 0 );
     if ( *data == -1 && errno)
     {
         file_set_error();
@@ -237,7 +274,7 @@
         if (read_thread_int( thread, addr, &res ) == -1) return -1;
         data = (data & mask) | (res & ~mask);
     }
-    if ((res = ptrace( PTRACE_POKEDATA, thread->unix_pid, (caddr_t)addr, data )) == -1)
+    if ((res = ptrace( PTRACE_POKEDATA, get_ptrace_pid(thread), (caddr_t)addr, data )) == -1)
         file_set_error();
     return res;
 }