Added several file server requests
[wine/multimedia.git] / server / pipe.c
blob7bce13381cd411864019f59c66d64230115c5eee
1 /*
2 * Server-side pipe management
4 * Copyright (C) 1998 Alexandre Julliard
5 */
7 #include <assert.h>
8 #include <fcntl.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <sys/errno.h>
12 #include <sys/stat.h>
13 #include <sys/time.h>
14 #include <sys/types.h>
15 #include <time.h>
16 #include <unistd.h>
18 #include "winerror.h"
19 #include "winnt.h"
20 #include "server/thread.h"
22 enum side { READ_SIDE, WRITE_SIDE };
24 struct pipe
26 struct object obj; /* object header */
27 struct pipe *other; /* the pipe other end */
28 int fd; /* Unix file descriptor */
29 enum side side; /* which side of the pipe is this */
32 static void pipe_dump( struct object *obj, int verbose );
33 static void pipe_add_queue( struct object *obj, struct wait_queue_entry *entry );
34 static void pipe_remove_queue( struct object *obj, struct wait_queue_entry *entry );
35 static int pipe_signaled( struct object *obj, struct thread *thread );
36 static int pipe_get_read_fd( struct object *obj );
37 static int pipe_get_write_fd( struct object *obj );
38 static void pipe_destroy( struct object *obj );
40 static const struct object_ops pipe_ops =
42 pipe_dump,
43 pipe_add_queue,
44 pipe_remove_queue,
45 pipe_signaled,
46 no_satisfied,
47 pipe_get_read_fd,
48 pipe_get_write_fd,
49 no_flush,
50 pipe_destroy
53 static const struct select_ops select_ops =
55 default_select_event,
56 NULL /* we never set a timeout on a pipe */
59 int create_pipe( struct object *obj[2] )
61 struct pipe *newpipe[2];
62 int fd[2];
64 if (pipe( fd ) == -1)
66 file_set_error();
67 return 0;
69 if (!(newpipe[0] = mem_alloc( sizeof(struct pipe) )))
71 close( fd[0] );
72 close( fd[1] );
73 return 0;
75 if (!(newpipe[1] = mem_alloc( sizeof(struct pipe) )))
77 close( fd[0] );
78 close( fd[1] );
79 free( newpipe[0] );
80 return 0;
82 init_object( &newpipe[0]->obj, &pipe_ops, NULL );
83 init_object( &newpipe[1]->obj, &pipe_ops, NULL );
84 newpipe[0]->fd = fd[0];
85 newpipe[0]->other = newpipe[1];
86 newpipe[0]->side = READ_SIDE;
87 newpipe[1]->fd = fd[1];
88 newpipe[1]->other = newpipe[0];
89 newpipe[1]->side = WRITE_SIDE;
90 obj[0] = &newpipe[0]->obj;
91 obj[1] = &newpipe[1]->obj;
92 CLEAR_ERROR();
93 return 1;
96 static void pipe_dump( struct object *obj, int verbose )
98 struct pipe *pipe = (struct pipe *)obj;
99 assert( obj->ops == &pipe_ops );
100 printf( "Pipe %s-side fd=%d\n",
101 (pipe->side == READ_SIDE) ? "read" : "write", pipe->fd );
104 static void pipe_add_queue( struct object *obj, struct wait_queue_entry *entry )
106 struct pipe *pipe = (struct pipe *)obj;
107 assert( obj->ops == &pipe_ops );
108 if (!obj->head) /* first on the queue */
109 add_select_user( pipe->fd,
110 (pipe->side == READ_SIDE) ? READ_EVENT : WRITE_EVENT,
111 &select_ops, pipe );
112 add_queue( obj, entry );
115 static void pipe_remove_queue( struct object *obj, struct wait_queue_entry *entry )
117 struct pipe *pipe = (struct pipe *)grab_object(obj);
118 assert( obj->ops == &pipe_ops );
120 remove_queue( obj, entry );
121 if (!obj->head) /* last on the queue is gone */
122 remove_select_user( pipe->fd );
123 release_object( obj );
126 static int pipe_signaled( struct object *obj, struct thread *thread )
128 struct pipe *pipe = (struct pipe *)obj;
129 struct timeval tv = { 0, 0 };
130 fd_set fds;
132 assert( obj->ops == &pipe_ops );
133 FD_ZERO( &fds );
134 FD_SET( pipe->fd, &fds );
135 if (pipe->side == READ_SIDE)
136 return select( pipe->fd + 1, &fds, NULL, NULL, &tv ) > 0;
137 else
138 return select( pipe->fd + 1, NULL, &fds, NULL, &tv ) > 0;
141 static int pipe_get_read_fd( struct object *obj )
143 struct pipe *pipe = (struct pipe *)obj;
144 assert( obj->ops == &pipe_ops );
146 if (!pipe->other)
148 SET_ERROR( ERROR_BROKEN_PIPE );
149 return -1;
151 if (pipe->side != READ_SIDE) /* FIXME: should not be necessary */
153 SET_ERROR( ERROR_ACCESS_DENIED );
154 return -1;
156 return dup( pipe->fd );
159 static int pipe_get_write_fd( struct object *obj )
161 struct pipe *pipe = (struct pipe *)obj;
162 assert( obj->ops == &pipe_ops );
164 if (!pipe->other)
166 SET_ERROR( ERROR_BROKEN_PIPE );
167 return -1;
169 if (pipe->side != WRITE_SIDE) /* FIXME: should not be necessary */
171 SET_ERROR( ERROR_ACCESS_DENIED );
172 return -1;
174 return dup( pipe->fd );
177 static void pipe_destroy( struct object *obj )
179 struct pipe *pipe = (struct pipe *)obj;
180 assert( obj->ops == &pipe_ops );
182 if (pipe->other) pipe->other->other = NULL;
183 close( pipe->fd );
184 free( pipe );