2 * Server-side pipe management
4 * Copyright (C) 1998 Alexandre Julliard
12 #include <sys/errno.h>
15 #include <sys/types.h>
21 #include "server/thread.h"
23 enum side { READ_SIDE, WRITE_SIDE };
27 struct object obj; /* object header */
28 struct pipe *other; /* the pipe other end */
29 int fd; /* Unix file descriptor */
30 enum side side; /* which side of the pipe is this */
33 static void pipe_dump( struct object *obj, int verbose );
34 static int pipe_add_queue( struct object *obj, struct wait_queue_entry *entry );
35 static void pipe_remove_queue( struct object *obj, struct wait_queue_entry *entry );
36 static int pipe_signaled( struct object *obj, struct thread *thread );
37 static int pipe_get_read_fd( struct object *obj );
38 static int pipe_get_write_fd( struct object *obj );
39 static int pipe_get_info( struct object *obj, struct get_file_info_reply *reply );
40 static void pipe_destroy( struct object *obj );
42 static const struct object_ops pipe_ops =
56 static const struct select_ops select_ops =
59 NULL /* we never set a timeout on a pipe */
62 int create_pipe( struct object *obj[2] )
64 struct pipe *newpipe[2];
72 if (!(newpipe[0] = mem_alloc( sizeof(struct pipe) )))
78 if (!(newpipe[1] = mem_alloc( sizeof(struct pipe) )))
85 init_object( &newpipe[0]->obj, &pipe_ops, NULL );
86 init_object( &newpipe[1]->obj, &pipe_ops, NULL );
87 newpipe[0]->fd = fd[0];
88 newpipe[0]->other = newpipe[1];
89 newpipe[0]->side = READ_SIDE;
90 newpipe[1]->fd = fd[1];
91 newpipe[1]->other = newpipe[0];
92 newpipe[1]->side = WRITE_SIDE;
93 obj[0] = &newpipe[0]->obj;
94 obj[1] = &newpipe[1]->obj;
99 static void pipe_dump( struct object *obj, int verbose )
101 struct pipe *pipe = (struct pipe *)obj;
102 assert( obj->ops == &pipe_ops );
103 fprintf( stderr, "Pipe %s-side fd=%d\n",
104 (pipe->side == READ_SIDE) ? "read" : "write", pipe->fd );
107 static int pipe_add_queue( struct object *obj, struct wait_queue_entry *entry )
109 struct pipe *pipe = (struct pipe *)obj;
110 assert( obj->ops == &pipe_ops );
111 if (!obj->head) /* first on the queue */
113 if (!add_select_user( pipe->fd,
114 (pipe->side == READ_SIDE) ? READ_EVENT : WRITE_EVENT,
117 SET_ERROR( ERROR_OUTOFMEMORY );
121 add_queue( obj, entry );
125 static void pipe_remove_queue( struct object *obj, struct wait_queue_entry *entry )
127 struct pipe *pipe = (struct pipe *)grab_object(obj);
128 assert( obj->ops == &pipe_ops );
130 remove_queue( obj, entry );
131 if (!obj->head) /* last on the queue is gone */
132 remove_select_user( pipe->fd );
133 release_object( obj );
136 static int pipe_signaled( struct object *obj, struct thread *thread )
138 struct pipe *pipe = (struct pipe *)obj;
139 struct timeval tv = { 0, 0 };
142 assert( obj->ops == &pipe_ops );
144 FD_SET( pipe->fd, &fds );
145 if (pipe->side == READ_SIDE)
146 return select( pipe->fd + 1, &fds, NULL, NULL, &tv ) > 0;
148 return select( pipe->fd + 1, NULL, &fds, NULL, &tv ) > 0;
151 static int pipe_get_read_fd( struct object *obj )
153 struct pipe *pipe = (struct pipe *)obj;
154 assert( obj->ops == &pipe_ops );
158 SET_ERROR( ERROR_BROKEN_PIPE );
161 if (pipe->side != READ_SIDE) /* FIXME: should not be necessary */
163 SET_ERROR( ERROR_ACCESS_DENIED );
166 return dup( pipe->fd );
169 static int pipe_get_write_fd( struct object *obj )
171 struct pipe *pipe = (struct pipe *)obj;
172 assert( obj->ops == &pipe_ops );
176 SET_ERROR( ERROR_BROKEN_PIPE );
179 if (pipe->side != WRITE_SIDE) /* FIXME: should not be necessary */
181 SET_ERROR( ERROR_ACCESS_DENIED );
184 return dup( pipe->fd );
187 static int pipe_get_info( struct object *obj, struct get_file_info_reply *reply )
189 memset( reply, 0, sizeof(*reply) );
190 reply->type = FILE_TYPE_PIPE;
194 static void pipe_destroy( struct object *obj )
196 struct pipe *pipe = (struct pipe *)obj;
197 assert( obj->ops == &pipe_ops );
199 if (pipe->other) pipe->other->other = NULL;