Use server file mapping objects.
[wine/multimedia.git] / server / pipe.c
blob4113a68a8833cfe8416ae2f80bfe029e5628bc20
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 int 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 int 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 */
110 if (!add_select_user( pipe->fd,
111 (pipe->side == READ_SIDE) ? READ_EVENT : WRITE_EVENT,
112 &select_ops, pipe ))
114 SET_ERROR( ERROR_OUTOFMEMORY );
115 return 0;
118 add_queue( obj, entry );
119 return 1;
122 static void pipe_remove_queue( struct object *obj, struct wait_queue_entry *entry )
124 struct pipe *pipe = (struct pipe *)grab_object(obj);
125 assert( obj->ops == &pipe_ops );
127 remove_queue( obj, entry );
128 if (!obj->head) /* last on the queue is gone */
129 remove_select_user( pipe->fd );
130 release_object( obj );
133 static int pipe_signaled( struct object *obj, struct thread *thread )
135 struct pipe *pipe = (struct pipe *)obj;
136 struct timeval tv = { 0, 0 };
137 fd_set fds;
139 assert( obj->ops == &pipe_ops );
140 FD_ZERO( &fds );
141 FD_SET( pipe->fd, &fds );
142 if (pipe->side == READ_SIDE)
143 return select( pipe->fd + 1, &fds, NULL, NULL, &tv ) > 0;
144 else
145 return select( pipe->fd + 1, NULL, &fds, NULL, &tv ) > 0;
148 static int pipe_get_read_fd( struct object *obj )
150 struct pipe *pipe = (struct pipe *)obj;
151 assert( obj->ops == &pipe_ops );
153 if (!pipe->other)
155 SET_ERROR( ERROR_BROKEN_PIPE );
156 return -1;
158 if (pipe->side != READ_SIDE) /* FIXME: should not be necessary */
160 SET_ERROR( ERROR_ACCESS_DENIED );
161 return -1;
163 return dup( pipe->fd );
166 static int pipe_get_write_fd( struct object *obj )
168 struct pipe *pipe = (struct pipe *)obj;
169 assert( obj->ops == &pipe_ops );
171 if (!pipe->other)
173 SET_ERROR( ERROR_BROKEN_PIPE );
174 return -1;
176 if (pipe->side != WRITE_SIDE) /* FIXME: should not be necessary */
178 SET_ERROR( ERROR_ACCESS_DENIED );
179 return -1;
181 return dup( pipe->fd );
184 static void pipe_destroy( struct object *obj )
186 struct pipe *pipe = (struct pipe *)obj;
187 assert( obj->ops == &pipe_ops );
189 if (pipe->other) pipe->other->other = NULL;
190 close( pipe->fd );
191 free( pipe );