Added the data structures and macros that will be needed to support
reentrant server requests.

diff --git a/server/request.c b/server/request.c
index 3c619a4..9853e1e 100644
--- a/server/request.c
+++ b/server/request.c
@@ -129,11 +129,14 @@
 }
 
 /* call a request handler */
-static inline void call_req_handler( struct thread *thread, enum request req )
+static inline void call_req_handler( struct thread *thread )
 {
+    enum request req;
     current = thread;
     clear_error();
 
+    req = ((struct request_header *)current->buffer)->req;
+
     if (debug_level) trace_request( req );
 
     if (req < REQ_NB_REQUESTS)
@@ -165,7 +168,7 @@
 void read_request( struct thread *thread )
 {
     int ret;
-    enum request req;
+    char dummy[1];
 
 #ifdef HAVE_MSGHDR_ACCRIGHTS
     msghdr.msg_accrightslen = sizeof(int);
@@ -178,43 +181,42 @@
 
     assert( thread->pass_fd == -1 );
 
-    myiovec.iov_base = (void *)&req;
-    myiovec.iov_len  = sizeof(req);
+    myiovec.iov_base = dummy;
+    myiovec.iov_len  = 1;
 
     ret = recvmsg( thread->obj.fd, &msghdr, 0 );
 #ifndef HAVE_MSGHDR_ACCRIGHTS
     thread->pass_fd = cmsg.fd;
 #endif
 
-    if (ret == sizeof(req))
+    if (ret > 0)
     {
-        call_req_handler( thread, req );
+        call_req_handler( thread );
         thread->pass_fd = -1;
         return;
     }
-    if (ret == -1)
-    {
-        perror("recvmsg");
-        thread->exit_code = 1;
-        kill_thread( thread, 1 );
-        return;
-    }
     if (!ret)  /* closed pipe */
     {
         kill_thread( thread, 0 );
         return;
     }
-    fatal_protocol_error( thread, "partial message received %d/%d\n", ret, sizeof(req) );
+    perror("recvmsg");
+    thread->exit_code = 1;
+    kill_thread( thread, 1 );
 }
 
 /* send a message to a client that is ready to receive something */
 int write_request( struct thread *thread )
 {
     int ret;
+    struct request_header *header = thread->buffer;
+
+    header->error = thread->error;
 
     if (thread->pass_fd == -1)
     {
-        ret = write( thread->obj.fd, &thread->error, sizeof(thread->error) );
+        /* write a single byte; the value is ignored anyway */
+        ret = write( thread->obj.fd, header, 1 );
     }
     else  /* we have an fd to send */
     {
@@ -227,37 +229,28 @@
         cmsg.fd = thread->pass_fd;
 #endif  /* HAVE_MSGHDR_ACCRIGHTS */
 
-        myiovec.iov_base = (void *)&thread->error;
-        myiovec.iov_len  = sizeof(thread->error);
+        myiovec.iov_base = (void *)header;
+        myiovec.iov_len  = 1;
 
         ret = sendmsg( thread->obj.fd, &msghdr, 0 );
         close( thread->pass_fd );
         thread->pass_fd = -1;
     }
-    if (ret == sizeof(thread->error))
+    if (ret > 0)
     {
         set_select_events( &thread->obj, POLLIN );
         return 1;
     }
-    if (ret == -1)
+    if (errno == EWOULDBLOCK) return 0;  /* not a fatal error */
+    if (errno == EPIPE)
     {
-        if (errno == EWOULDBLOCK) return 0;  /* not a fatal error */
-        if (errno == EPIPE)
-        {
-            kill_thread( thread, 0 );  /* normal death */
-        }
-        else
-        {
-            perror("sendmsg");
-            thread->exit_code = 1;
-            kill_thread( thread, 1 );
-        }
+        kill_thread( thread, 0 );  /* normal death */
     }
     else
     {
+        perror("sendmsg");
         thread->exit_code = 1;
         kill_thread( thread, 1 );
-        fprintf( stderr, "Partial message sent %d/%d\n", ret, sizeof(thread->error) );
     }
     return -1;
 }
diff --git a/server/request.h b/server/request.h
index 3ad0d33..aa46902 100644
--- a/server/request.h
+++ b/server/request.h
@@ -48,17 +48,26 @@
     return thread->buffer;
 }
 
+/* get the request vararg data */
+inline static void *get_req_data( const void *req )
+{
+    return ((union generic_request *)req + 1);
+}
+
+
+#define REQUEST_END(req) ((char *)(req) + MAX_REQUEST_LENGTH - sizeof(struct server_buffer_info))
+
 /* get the remaining size in the request buffer for object of a given size */
 static inline int get_req_size( const void *req, const void *ptr, size_t typesize )
 {
-    return ((char *)req + MAX_REQUEST_LENGTH - (char *)ptr) / typesize;
+    return (REQUEST_END(req) - (char *)ptr) / typesize;
 }
 
 /* get the length of a request string, without going past the end of the request */
 static inline size_t get_req_strlen( const void *req, const char *str )
 {
     const char *p = str;
-    while (*p && (p < (char *)req + MAX_REQUEST_LENGTH - 1)) p++;
+    while (*p && (p < REQUEST_END(req) - 1)) p++;
     return p - str;
 }
 
@@ -66,7 +75,7 @@
 static inline size_t get_req_strlenW( const void *req, const WCHAR *str )
 {
     const WCHAR *p = str;
-    while (*p && (p < (WCHAR *)req + MAX_REQUEST_LENGTH/sizeof(WCHAR) - 1)) p++;
+    while (*p && (p < (WCHAR *)REQUEST_END(req) - 1)) p++;
     return p - str;
 }
 
diff --git a/server/thread.c b/server/thread.c
index c00e61e..c1b79fa 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -96,6 +96,7 @@
     if (ftruncate( fd, MAX_REQUEST_LENGTH ) == -1) goto error;
     if ((thread->buffer = mmap( 0, MAX_REQUEST_LENGTH, PROT_READ | PROT_WRITE,
                                 MAP_SHARED, fd, 0 )) == (void*)-1) goto error;
+    thread->buffer_info = (struct server_buffer_info *)((char *)thread->buffer + MAX_REQUEST_LENGTH) - 1;
     /* build the first request into the buffer and send it */
     req = thread->buffer;
     req->pid  = get_process_id( thread->process );
diff --git a/server/thread.h b/server/thread.h
index 7c9ae9e..f0f170b 100644
--- a/server/thread.h
+++ b/server/thread.h
@@ -59,6 +59,7 @@
     int                 affinity;  /* affinity mask */
     int                 suspend;   /* suspend count */
     void               *buffer;    /* buffer for communication with the client */
+    struct server_buffer_info *buffer_info;   /* buffer information structure */
     enum request        last_req;  /* last request received (for debugging) */
 };
 
diff --git a/server/trace.c b/server/trace.c
index 8774c81..34ff39c 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -787,7 +787,6 @@
 
 static void dump_free_console_request( const struct free_console_request *req )
 {
-    fprintf( stderr, " dummy=%d", req->dummy );
 }
 
 static void dump_open_console_request( const struct open_console_request *req )