Moved process structure definition to process.h.
Added suspend/resume_process.
Moved handle table back into the process structure.

diff --git a/server/handle.c b/server/handle.c
index a99583b..5ba8d26 100644
--- a/server/handle.c
+++ b/server/handle.c
@@ -41,29 +41,27 @@
 
 /* grow a handle table */
 /* return 1 if OK, 0 on error */
-static int grow_handle_table( struct handle_table *table )
+static int grow_handle_table( struct process *process )
 {
     struct handle_entry *new_entries;
-    int count = table->count;
+    int count = process->handle_count;
 
     if (count >= INT_MAX / 2) return 0;
     count *= 2;
-    if (!(new_entries = realloc( table->entries, count * sizeof(struct handle_entry) )))
+    if (!(new_entries = realloc( process->entries, count * sizeof(struct handle_entry) )))
     {
         SET_ERROR( ERROR_OUTOFMEMORY );
         return 0;
     }
-    table->count   = count;
-    table->entries = new_entries;
+    process->handle_count = count;
+    process->entries      = new_entries;
     return 1;
 }
 
 /* allocate a handle for an object, incrementing its refcount */
 /* return the handle, or -1 on error */
-int alloc_handle( struct process *process, void *obj, unsigned int access,
-                  int inherit )
+int alloc_handle( struct process *process, void *obj, unsigned int access, int inherit )
 {
-    struct handle_table *table = get_process_handles( process );
     struct handle_entry *entry;
     int handle;
 
@@ -72,16 +70,16 @@
 
     /* find the first free entry */
 
-    if (!(entry = table->entries)) return -1;
-    for (handle = 0; handle <= table->last; handle++, entry++)
+    if (!(entry = process->entries)) return -1;
+    for (handle = 0; handle <= process->handle_last; handle++, entry++)
         if (!entry->ptr) goto found;
 
-    if (handle >= table->count)
+    if (handle >= process->handle_count)
     {
-        if (!grow_handle_table( table )) return -1;
-        entry = table->entries + handle;  /* the table may have moved */
+        if (!grow_handle_table( process )) return -1;
+        entry = process->entries + handle;  /* the table may have moved */
     }
-    table->last = handle;
+    process->handle_last = handle;
 
  found:
     entry->ptr    = grab_object( obj );
@@ -92,7 +90,6 @@
 /* return an handle entry, or NULL if the handle is invalid */
 static struct handle_entry *get_handle( struct process *process, int handle )
 {
-    struct handle_table *table;
     struct handle_entry *entry;
 
     if (HANDLE_IS_GLOBAL(handle))
@@ -100,10 +97,9 @@
         handle = HANDLE_GLOBAL_TO_LOCAL(handle);
         process = initial_process;
     }
-    table = get_process_handles( process );
     handle--;  /* handles start at 1 */
-    if ((handle < 0) || (handle > table->last)) goto error;
-    entry = table->entries + handle;
+    if ((handle < 0) || (handle > process->handle_last)) goto error;
+    entry = process->entries + handle;
     if (!entry->ptr) goto error;
     return entry;
 
@@ -114,26 +110,26 @@
 
 /* attempt to shrink a table */
 /* return 1 if OK, 0 on error */
-static int shrink_handle_table( struct handle_table *table )
+static int shrink_handle_table( struct process *process )
 {
     struct handle_entry *new_entries;
-    struct handle_entry *entry = table->entries + table->last;
-    int count = table->count;
+    struct handle_entry *entry = process->entries + process->handle_last;
+    int count = process->handle_count;
 
-    while (table->last >= 0)
+    while (process->handle_last >= 0)
     {
         if (entry->ptr) break;
-        table->last--;
+        process->handle_last--;
         entry--;
     }
-    if (table->last >= count / 4) return 1;  /* no need to shrink */
+    if (process->handle_last >= count / 4) return 1;  /* no need to shrink */
     if (count < MIN_HANDLE_ENTRIES * 2) return 1;  /* too small to shrink */
     count /= 2;
-    if (!(new_entries = realloc( table->entries,
+    if (!(new_entries = realloc( process->entries,
                                  count * sizeof(struct handle_entry) )))
         return 0;
-    table->count   = count;
-    table->entries = new_entries;
+    process->handle_count = count;
+    process->entries      = new_entries;
     return 1;
 }
 
@@ -141,34 +137,30 @@
 /* return 1 if OK, 0 on error */
 int copy_handle_table( struct process *process, struct process *parent )
 {
-    struct handle_table *parent_table;
-    struct handle_table *table = get_process_handles( process );
     struct handle_entry *ptr;
     int i, count, last;
 
     if (!parent)  /* first process */
     {
         if (!initial_process) initial_process = process;
-        parent_table = NULL;
         count = MIN_HANDLE_ENTRIES;
         last  = -1;
     }
     else
     {
-        parent_table = get_process_handles( parent );
-        assert( parent_table->entries );
-        count = parent_table->count;
-        last  = parent_table->last;
+        assert( parent->entries );
+        count = parent->handle_count;
+        last  = parent->handle_last;
     }
 
     if (!(ptr = mem_alloc( count * sizeof(struct handle_entry)))) return 0;
-    table->entries = ptr;
-    table->count   = count;
-    table->last    = last;
+    process->entries      = ptr;
+    process->handle_count = count;
+    process->handle_last  = last;
 
     if (last >= 0)
     {
-        memcpy( ptr, parent_table->entries, (last + 1) * sizeof(struct handle_entry) );
+        memcpy( ptr, parent->entries, (last + 1) * sizeof(struct handle_entry) );
         for (i = 0; i <= last; i++, ptr++)
         {
             if (!ptr->ptr) continue;
@@ -177,7 +169,7 @@
         }
     }
     /* attempt to shrink the table */
-    shrink_handle_table( table );
+    shrink_handle_table( process );
     return 1;
 }
 
@@ -185,7 +177,6 @@
 /* return 1 if OK, 0 on error */
 int close_handle( struct process *process, int handle )
 {
-    struct handle_table *table;
     struct handle_entry *entry;
     struct object *obj;
 
@@ -194,12 +185,11 @@
         handle = HANDLE_GLOBAL_TO_LOCAL(handle);
         process = initial_process;
     }
-    table = get_process_handles( process );
     if (!(entry = get_handle( process, handle ))) return 0;
     if (entry->access & RESERVED_CLOSE_PROTECT) return 0;  /* FIXME: error code */
     obj = entry->ptr;
     entry->ptr = NULL;
-    if (handle-1 == table->last) shrink_handle_table( table );
+    if (handle-1 == process->handle_last) shrink_handle_table( process );
     release_object( obj );
     return 1;
 }
@@ -269,21 +259,20 @@
 /* free the process handle entries */
 void free_handles( struct process *process )
 {
-    struct handle_table *table = get_process_handles( process );
     struct handle_entry *entry;
     int handle;
 
-    if (!(entry = table->entries)) return;
-    for (handle = 0; handle <= table->last; handle++, entry++)
+    if (!(entry = process->entries)) return;
+    for (handle = 0; handle <= process->handle_last; handle++, entry++)
     {
         struct object *obj = entry->ptr;
         entry->ptr = NULL;
         if (obj) release_object( obj );
     }
-    free( table->entries );
-    table->count   = 0;
-    table->last    = -1;
-    table->entries = NULL;
+    free( process->entries );
+    process->handle_count = 0;
+    process->handle_last  = -1;
+    process->entries      = NULL;
 }
 
 /* open a new handle to an existing object */
@@ -308,13 +297,12 @@
 /* dump a handle table on stdout */
 void dump_handles( struct process *process )
 {
-    struct handle_table *table = get_process_handles( process );
     struct handle_entry *entry;
     int i;
 
-    if (!table->entries) return;
-    entry = table->entries;
-    for (i = 0; i <= table->last; i++, entry++)
+    if (!process->entries) return;
+    entry = process->entries;
+    for (i = 0; i <= process->handle_last; i++, entry++)
     {
         if (!entry->ptr) continue;
         printf( "%5d: %p %08x ", i + 1, entry->ptr, entry->access );
diff --git a/server/handle.h b/server/handle.h
index cb991e8..827dbc6 100644
--- a/server/handle.h
+++ b/server/handle.h
@@ -13,16 +13,6 @@
 
 struct process;
 struct object_ops;
-struct handle_entry;
-
-/* handle structures */
-
-struct handle_table
-{
-    int count;
-    int last;
-    struct handle_entry *entries;
-};
 
 /* handle functions */
 
diff --git a/server/process.c b/server/process.c
index 6d435aa..de97ff4 100644
--- a/server/process.c
+++ b/server/process.c
@@ -6,6 +6,7 @@
 
 #include <assert.h>
 #include <limits.h>
+#include <signal.h>
 #include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -23,24 +24,6 @@
 
 /* process structure */
 
-struct process
-{
-    struct object        obj;             /* object header */
-    struct process      *next;            /* system-wide process list */
-    struct process      *prev;
-    struct thread       *thread_list;     /* head of the thread list */
-    struct handle_table  handles;         /* handle table */
-    int                  exit_code;       /* process exit code */
-    int                  running_threads; /* number of threads running in this process */
-    struct timeval       start_time;      /* absolute time at process start */
-    struct timeval       end_time;        /* absolute time at process end */
-    int                  priority;        /* priority class */
-    int                  affinity;        /* process affinity mask */
-    struct object       *console_in;      /* console input */
-    struct object       *console_out;     /* console output */
-    struct new_process_request *info;     /* startup info (freed after startup) */
-};
-
 static struct process initial_process;
 static struct process *first_process = &initial_process;
 static int running_processes;
@@ -73,10 +56,14 @@
     process->next            = NULL;
     process->prev            = NULL;
     process->thread_list     = NULL;
+    process->debug_next      = NULL;
+    process->debug_prev      = NULL;
+    process->debugger        = NULL;
     process->exit_code       = 0x103;  /* STILL_ACTIVE */
     process->running_threads = 0;
     process->priority        = NORMAL_PRIORITY_CLASS;
     process->affinity        = 1;
+    process->suspend         = 0;
     process->console_in      = NULL;
     process->console_out     = NULL;
     process->info            = NULL;
@@ -200,12 +187,6 @@
                                              access, &process_ops );
 }
 
-/* get a pointer to the process handle table */
-struct handle_table *get_process_handles( struct process *process )
-{
-    return &process->handles;
-}
-
 /* retrieve the initialization info for a new process */
 static int get_process_init_info( struct process *process, struct init_process_reply *reply )
 {
@@ -261,8 +242,37 @@
     release_object( thread );
 }
 
+/* suspend all the threads of a process */
+void suspend_process( struct process *process )
+{
+    if (!process->suspend++)
+    {
+        struct thread *thread = process->thread_list;
+        for (; thread; thread = thread->proc_next)
+        {
+            if (!thread->suspend && thread->unix_pid)
+                kill( thread->unix_pid, SIGSTOP );
+        }
+    }
+}
+
+/* resume all the threads of a process */
+void resume_process( struct process *process )
+{
+    assert (process->suspend > 0);
+    if (!--process->suspend)
+    {
+        struct thread *thread = process->thread_list;
+        for (; thread; thread = thread->proc_next)
+        {
+            if (!thread->suspend && thread->unix_pid)
+                kill( thread->unix_pid, SIGCONT );
+        }
+    }
+}
+
 /* kill a process on the spot */
-static void kill_process( struct process *process, int exit_code )
+void kill_process( struct process *process, int exit_code )
 {
     while (process->thread_list)
         kill_thread( process->thread_list, exit_code );
diff --git a/server/process.h b/server/process.h
index 3414443..b9b44fc 100644
--- a/server/process.h
+++ b/server/process.h
@@ -15,8 +15,31 @@
 
 /* process structures */
 
-struct process;
-struct handle_table;
+struct handle_entry;
+
+struct process
+{
+    struct object        obj;             /* object header */
+    struct process      *next;            /* system-wide process list */
+    struct process      *prev;
+    struct thread       *thread_list;     /* head of the thread list */
+    struct process      *debug_next;      /* per-debugger process list */
+    struct process      *debug_prev;
+    struct thread       *debugger;        /* thread debugging this process */
+    struct handle_entry *entries;         /* handle entries */
+    int                  handle_last;     /* last valid handle */
+    int                  handle_count;    /* allocated table entries */
+    int                  exit_code;       /* process exit code */
+    int                  running_threads; /* number of threads running in this process */
+    struct timeval       start_time;      /* absolute time at process start */
+    struct timeval       end_time;        /* absolute time at process end */
+    int                  priority;        /* priority class */
+    int                  affinity;        /* process affinity mask */
+    int                  suspend;         /* global process suspend count */
+    struct object       *console_in;      /* console input */
+    struct object       *console_out;     /* console output */
+    struct new_process_request *info;     /* startup info (freed after startup) */
+};
 
 struct process_snapshot
 {
@@ -31,11 +54,14 @@
 extern struct process *create_initial_process(void);
 extern struct process *get_process_from_id( void *id );
 extern struct process *get_process_from_handle( int handle, unsigned int access );
-extern struct handle_table *get_process_handles( struct process *process );
+extern int process_set_debugger( struct process *process, struct thread *thread );
 extern void add_process_thread( struct process *process,
                                 struct thread *thread );
 extern void remove_process_thread( struct process *process,
                                    struct thread *thread );
+extern void suspend_process( struct process *process );
+extern void resume_process( struct process *process );
+extern void kill_process( struct process *process, int exit_code );
 extern int alloc_console( struct process *process );
 extern int free_console( struct process *process );
 extern struct object *get_console( struct process *process, int output );