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;
}