From 7a344c14af0d47c4479198bdfe4c8f1923ec5ca1 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 9 Jun 2009 12:11:05 +0200 Subject: [PATCH] server: Avoid a crash when trying to wait on a disconnected pipe client. --- server/fd.c | 6 ++++++ server/file.h | 1 + server/named_pipe.c | 10 +++++++++- 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/server/fd.c b/server/fd.c index d9688e1e0d..a57001a04c 100644 --- a/server/fd.c +++ b/server/fd.c @@ -1710,6 +1710,12 @@ void set_fd_signaled( struct fd *fd, int signaled ) if (signaled) wake_up( fd->user, 0 ); } +/* set or clear the fd signaled state */ +int is_fd_signaled( struct fd *fd ) +{ + return fd->signaled; +} + /* handler for close_handle that refuses to close fd-associated handles in other processes */ int fd_close_handle( struct object *obj, struct process *process, obj_handle_t handle ) { diff --git a/server/file.h b/server/file.h index 1aaa2847f1..aef40f7c1a 100644 --- a/server/file.h +++ b/server/file.h @@ -70,6 +70,7 @@ extern void set_fd_events( struct fd *fd, int events ); extern obj_handle_t lock_fd( struct fd *fd, file_pos_t offset, file_pos_t count, int shared, int wait ); extern void unlock_fd( struct fd *fd, file_pos_t offset, file_pos_t count ); extern void set_fd_signaled( struct fd *fd, int signaled ); +extern int is_fd_signaled( struct fd *fd ); extern int default_fd_signaled( struct object *obj, struct thread *thread ); extern unsigned int default_fd_map_access( struct object *obj, unsigned int access ); diff --git a/server/named_pipe.c b/server/named_pipe.c index 539509e1c2..54ce823046 100644 --- a/server/named_pipe.c +++ b/server/named_pipe.c @@ -176,6 +176,7 @@ static const struct fd_ops pipe_server_fd_ops = /* client end functions */ static void pipe_client_dump( struct object *obj, int verbose ); +static int pipe_client_signaled( struct object *obj, struct thread *thread ); static struct fd *pipe_client_get_fd( struct object *obj ); static void pipe_client_destroy( struct object *obj ); static void pipe_client_flush( struct fd *fd, struct event **event ); @@ -188,7 +189,7 @@ static const struct object_ops pipe_client_ops = no_get_type, /* get_type */ add_queue, /* add_queue */ remove_queue, /* remove_queue */ - default_fd_signaled, /* signaled */ + pipe_client_signaled, /* signaled */ no_satisfied, /* satisfied */ no_signal, /* signal */ pipe_client_get_fd, /* get_fd */ @@ -289,6 +290,13 @@ static void pipe_client_dump( struct object *obj, int verbose ) fprintf( stderr, "Named pipe client server=%p\n", client->server ); } +static int pipe_client_signaled( struct object *obj, struct thread *thread ) +{ + struct pipe_client *client = (struct pipe_client *) obj; + + return client->fd && is_fd_signaled(client->fd); +} + static void named_pipe_destroy( struct object *obj) { struct named_pipe *pipe = (struct named_pipe *) obj; -- 2.32.0.93.g670b81a890