From: Jacek Caban Subject: [PATCH 04/10] server: Introduced new pipe_end struct containing common parts of pipe_client and pipe_server. Message-Id: Date: Wed, 23 Nov 2016 11:52:20 +0100 Signed-off-by: Jacek Caban --- server/named_pipe.c | 99 ++++++++++++++++++++++++++++------------------------- 1 file changed, 53 insertions(+), 46 deletions(-) diff --git a/server/named_pipe.c b/server/named_pipe.c index 76ab6bf..b47892a 100644 --- a/server/named_pipe.c +++ b/server/named_pipe.c @@ -65,10 +65,16 @@ enum pipe_state struct named_pipe; -struct pipe_server +struct pipe_end { struct object obj; /* object header */ struct fd *fd; /* pipe file descriptor */ + unsigned int flags; /* pipe flags */ +}; + +struct pipe_server +{ + struct pipe_end pipe_end; /* common header for pipe_client and pipe_server */ struct fd *ioctl_fd; /* file descriptor for ioctls when not connected */ struct list entry; /* entry in named pipe servers list */ enum pipe_state state; /* server state */ @@ -76,16 +82,13 @@ struct pipe_server struct named_pipe *pipe; struct timeout_user *flush_poll; unsigned int options; /* pipe options */ - unsigned int pipe_flags; }; struct pipe_client { - struct object obj; /* object header */ - struct fd *fd; /* pipe file descriptor */ + struct pipe_end pipe_end; /* common header for pipe_client and pipe_server */ struct pipe_server *server; /* server that this client is connected to */ unsigned int flags; /* file flags */ - unsigned int pipe_flags; }; struct named_pipe @@ -307,7 +310,7 @@ static int pipe_client_signaled( struct object *obj, struct wait_queue_entry *en { struct pipe_client *client = (struct pipe_client *) obj; - return client->fd && is_fd_signaled(client->fd); + return client->pipe_end.fd && is_fd_signaled(client->pipe_end.fd); } static void named_pipe_destroy( struct object *obj) @@ -322,8 +325,8 @@ static void named_pipe_destroy( struct object *obj) static struct fd *pipe_client_get_fd( struct object *obj ) { struct pipe_client *client = (struct pipe_client *) obj; - if (client->fd) - return (struct fd *) grab_object( client->fd ); + if (client->pipe_end.fd) + return (struct fd *) grab_object( client->pipe_end.fd ); set_error( STATUS_PIPE_DISCONNECTED ); return NULL; } @@ -336,15 +339,15 @@ static void set_server_state( struct pipe_server *server, enum pipe_state state { case ps_connected_server: case ps_wait_disconnect: - assert( server->fd ); + assert( server->pipe_end.fd ); break; case ps_wait_open: case ps_idle_server: - assert( !server->fd ); + assert( !server->pipe_end.fd ); set_no_fd_status( server->ioctl_fd, STATUS_PIPE_LISTENING ); break; case ps_wait_connect: - assert( !server->fd ); + assert( !server->pipe_end.fd ); set_no_fd_status( server->ioctl_fd, STATUS_PIPE_DISCONNECTED ); break; } @@ -354,7 +357,7 @@ static struct fd *pipe_server_get_fd( struct object *obj ) { struct pipe_server *server = (struct pipe_server *) obj; - return (struct fd *)grab_object( server->fd ? server->fd : server->ioctl_fd ); + return (struct fd *)grab_object( server->pipe_end.fd ? server->pipe_end.fd : server->ioctl_fd ); } @@ -365,7 +368,7 @@ static void notify_empty( struct pipe_server *server ) assert( server->state == ps_connected_server ); remove_timeout_user( server->flush_poll ); server->flush_poll = NULL; - fd_async_wake_up( server->fd, ASYNC_TYPE_WAIT, STATUS_SUCCESS ); + fd_async_wake_up( server->pipe_end.fd, ASYNC_TYPE_WAIT, STATUS_SUCCESS ); } static void do_disconnect( struct pipe_server *server ) @@ -374,14 +377,14 @@ static void do_disconnect( struct pipe_server *server ) if (server->client) { assert( server->client->server == server ); - assert( server->client->fd ); - release_object( server->client->fd ); - server->client->fd = NULL; + assert( server->client->pipe_end.fd ); + release_object( server->client->pipe_end.fd ); + server->client->pipe_end.fd = NULL; } - assert( server->fd ); - shutdown( get_unix_fd( server->fd ), SHUT_RDWR ); - release_object( server->fd ); - server->fd = NULL; + assert( server->pipe_end.fd ); + shutdown( get_unix_fd( server->pipe_end.fd ), SHUT_RDWR ); + release_object( server->pipe_end.fd ); + server->pipe_end.fd = NULL; } static void pipe_server_destroy( struct object *obj) @@ -390,7 +393,7 @@ static void pipe_server_destroy( struct object *obj) assert( obj->ops == &pipe_server_ops ); - if (server->fd) + if (server->pipe_end.fd) { notify_empty( server ); do_disconnect( server ); @@ -438,7 +441,7 @@ static void pipe_client_destroy( struct object *obj) server->client = NULL; client->server = NULL; } - if (client->fd) release_object( client->fd ); + if (client->pipe_end.fd) release_object( client->pipe_end.fd ); } static void named_pipe_device_dump( struct object *obj, int verbose ) @@ -520,7 +523,7 @@ static int pipe_data_remaining( struct pipe_server *server ) assert( server->client ); - fd = get_unix_fd( server->client->fd ); + fd = get_unix_fd( server->client->pipe_end.fd ); if (fd < 0) return 0; pfd.fd = fd; @@ -544,7 +547,7 @@ static void check_flushed( void *arg ) else { server->flush_poll = NULL; - fd_async_wake_up( server->fd, ASYNC_TYPE_WAIT, STATUS_SUCCESS ); + fd_async_wake_up( server->pipe_end.fd, ASYNC_TYPE_WAIT, STATUS_SUCCESS ); } } @@ -558,7 +561,7 @@ static obj_handle_t pipe_server_flush( struct fd *fd, const async_data_t *async_ if (!pipe_data_remaining( server )) return 0; - if ((async = fd_queue_async( server->fd, async_data, NULL, ASYNC_TYPE_WAIT ))) + if ((async = fd_queue_async( server->pipe_end.fd, async_data, NULL, ASYNC_TYPE_WAIT ))) { /* there's no unix way to be alerted when a pipe becomes empty, so resort to polling */ if (!server->flush_poll) @@ -632,7 +635,7 @@ static obj_handle_t pipe_server_ioctl( struct fd *fd, ioctl_code_t code, const a { case ps_connected_server: assert( server->client ); - assert( server->client->fd ); + assert( server->client->pipe_end.fd ); notify_empty( server ); @@ -670,6 +673,12 @@ static struct pipe_server *get_pipe_server_obj( struct process *process, return (struct pipe_server *) obj; } +static void init_pipe_end( struct pipe_end *pipe_end, unsigned int pipe_flags ) +{ + pipe_end->fd = NULL; + pipe_end->flags = pipe_flags; +} + static struct pipe_server *create_pipe_server( struct named_pipe *pipe, unsigned int options, unsigned int pipe_flags ) { @@ -679,16 +688,15 @@ static struct pipe_server *create_pipe_server( struct named_pipe *pipe, unsigned if (!server) return NULL; - server->fd = NULL; server->pipe = pipe; server->client = NULL; server->flush_poll = NULL; server->options = options; - server->pipe_flags = pipe_flags; + init_pipe_end( &server->pipe_end, pipe_flags ); list_add_head( &pipe->servers, &server->entry ); grab_object( pipe ); - if (!(server->ioctl_fd = alloc_pseudo_fd( &pipe_server_fd_ops, &server->obj, options ))) + if (!(server->ioctl_fd = alloc_pseudo_fd( &pipe_server_fd_ops, &server->pipe_end.obj, options ))) { release_object( server ); return NULL; @@ -705,10 +713,9 @@ static struct pipe_client *create_pipe_client( unsigned int flags, unsigned int if (!client) return NULL; - client->fd = NULL; client->server = NULL; client->flags = flags; - client->pipe_flags = pipe_flags; + init_pipe_end( &client->pipe_end, pipe_flags ); return client; } @@ -776,7 +783,7 @@ static struct object *named_pipe_open_file( struct object *obj, unsigned int acc { if (!socketpair( PF_UNIX, SOCK_STREAM, 0, fds )) { - assert( !server->fd ); + assert( !server->pipe_end.fd ); /* for performance reasons, only set nonblocking mode when using * overlapped I/O. Otherwise, we will be doing too much busy @@ -795,13 +802,13 @@ static struct object *named_pipe_open_file( struct object *obj, unsigned int acc setsockopt( fds[1], SOL_SOCKET, SO_SNDBUF, &pipe->outsize, sizeof(pipe->outsize) ); } - client->fd = create_anonymous_fd( &pipe_client_fd_ops, fds[1], &client->obj, options ); - server->fd = create_anonymous_fd( &pipe_server_fd_ops, fds[0], &server->obj, server->options ); - if (client->fd && server->fd) + client->pipe_end.fd = create_anonymous_fd( &pipe_client_fd_ops, fds[1], &client->pipe_end.obj, options ); + server->pipe_end.fd = create_anonymous_fd( &pipe_server_fd_ops, fds[0], &server->pipe_end.obj, server->options ); + if (client->pipe_end.fd && server->pipe_end.fd) { - allow_fd_caching( client->fd ); - allow_fd_caching( server->fd ); - fd_copy_completion( server->ioctl_fd, server->fd ); + allow_fd_caching( client->pipe_end.fd ); + allow_fd_caching( server->pipe_end.fd ); + fd_copy_completion( server->ioctl_fd, server->pipe_end.fd ); if (server->state == ps_wait_open) fd_async_wake_up( server->ioctl_fd, ASYNC_TYPE_WAIT, STATUS_SUCCESS ); set_server_state( server, ps_connected_server ); @@ -822,7 +829,7 @@ static struct object *named_pipe_open_file( struct object *obj, unsigned int acc } } release_object( server ); - return &client->obj; + return &client->pipe_end.obj; } static obj_handle_t named_pipe_device_ioctl( struct fd *fd, ioctl_code_t code, @@ -948,10 +955,10 @@ DECL_HANDLER(create_named_pipe) { reply->handle = alloc_handle( current->process, server, req->access, objattr->attributes ); server->pipe->instances++; - if (sd) default_set_sd( &server->obj, sd, OWNER_SECURITY_INFORMATION | - GROUP_SECURITY_INFORMATION | - DACL_SECURITY_INFORMATION | - SACL_SECURITY_INFORMATION ); + if (sd) default_set_sd( &server->pipe_end.obj, sd, OWNER_SECURITY_INFORMATION | + GROUP_SECURITY_INFORMATION | + DACL_SECURITY_INFORMATION | + SACL_SECURITY_INFORMATION ); release_object( server ); } @@ -976,7 +983,7 @@ DECL_HANDLER(get_named_pipe_info) server = client->server; } - reply->flags = client ? client->pipe_flags : server->pipe_flags; + reply->flags = client ? client->pipe_end.flags : server->pipe_end.flags; if (server) { reply->sharing = server->pipe->sharing; @@ -1024,11 +1031,11 @@ DECL_HANDLER(set_named_pipe_info) } else if (client) { - client->pipe_flags = server->pipe->flags | req->flags; + client->pipe_end.flags = server->pipe->flags | req->flags; } else { - server->pipe_flags = server->pipe->flags | req->flags; + server->pipe_end.flags = server->pipe->flags | req->flags; } if (client)