Added SHDoDragDrop() stub.
[wine/multimedia.git] / server / pipe.c
blob00c2863c169c68ee7d5bbae9d19853b833649a44
1 /*
2 * Server-side pipe management
4 * Copyright (C) 1998 Alexandre Julliard
5 */
7 #include <assert.h>
8 #include <fcntl.h>
9 #include <string.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <sys/errno.h>
13 #include <sys/stat.h>
14 #include <sys/time.h>
15 #include <sys/types.h>
16 #include <time.h>
17 #include <unistd.h>
19 #include "winerror.h"
20 #include "winbase.h"
22 #include "handle.h"
23 #include "thread.h"
24 #include "request.h"
26 enum side { READ_SIDE, WRITE_SIDE };
28 struct pipe
30 struct object obj; /* object header */
31 struct pipe *other; /* the pipe other end */
32 struct select_user select; /* select user */
33 enum side side; /* which side of the pipe is this */
36 static void pipe_dump( struct object *obj, int verbose );
37 static int pipe_add_queue( struct object *obj, struct wait_queue_entry *entry );
38 static void pipe_remove_queue( struct object *obj, struct wait_queue_entry *entry );
39 static int pipe_signaled( struct object *obj, struct thread *thread );
40 static int pipe_get_read_fd( struct object *obj );
41 static int pipe_get_write_fd( struct object *obj );
42 static int pipe_get_info( struct object *obj, struct get_file_info_request *req );
43 static void pipe_destroy( struct object *obj );
45 static const struct object_ops pipe_ops =
47 sizeof(struct pipe),
48 pipe_dump,
49 pipe_add_queue,
50 pipe_remove_queue,
51 pipe_signaled,
52 no_satisfied,
53 pipe_get_read_fd,
54 pipe_get_write_fd,
55 no_flush,
56 pipe_get_info,
57 pipe_destroy
61 static struct pipe *create_pipe_side( int fd, int side )
63 struct pipe *pipe;
65 if ((pipe = alloc_object( &pipe_ops )))
67 pipe->select.fd = fd;
68 pipe->select.func = default_select_event;
69 pipe->select.private = pipe;
70 pipe->other = NULL;
71 pipe->side = side;
72 register_select_user( &pipe->select );
74 return pipe;
77 static int create_pipe( struct object *obj[2] )
79 struct pipe *read_pipe;
80 struct pipe *write_pipe;
81 int fd[2];
83 if (pipe( fd ) == -1)
85 file_set_error();
86 return 0;
88 if ((read_pipe = create_pipe_side( fd[0], READ_SIDE )))
90 if ((write_pipe = create_pipe_side( fd[1], WRITE_SIDE )))
92 write_pipe->other = read_pipe;
93 read_pipe->other = write_pipe;
94 obj[0] = &read_pipe->obj;
95 obj[1] = &write_pipe->obj;
96 return 1;
98 release_object( read_pipe );
100 close( fd[0] );
101 close( fd[1] );
102 return 0;
105 static void pipe_dump( struct object *obj, int verbose )
107 struct pipe *pipe = (struct pipe *)obj;
108 assert( obj->ops == &pipe_ops );
109 fprintf( stderr, "Pipe %s-side fd=%d\n",
110 (pipe->side == READ_SIDE) ? "read" : "write", pipe->select.fd );
113 static int pipe_add_queue( struct object *obj, struct wait_queue_entry *entry )
115 struct pipe *pipe = (struct pipe *)obj;
116 assert( obj->ops == &pipe_ops );
117 if (!obj->head) /* first on the queue */
118 set_select_events( &pipe->select,
119 (pipe->side == READ_SIDE) ? READ_EVENT : WRITE_EVENT );
120 add_queue( obj, entry );
121 return 1;
124 static void pipe_remove_queue( struct object *obj, struct wait_queue_entry *entry )
126 struct pipe *pipe = (struct pipe *)grab_object(obj);
127 assert( obj->ops == &pipe_ops );
129 remove_queue( obj, entry );
130 if (!obj->head) /* last on the queue is gone */
131 set_select_events( &pipe->select, 0 );
132 release_object( obj );
135 static int pipe_signaled( struct object *obj, struct thread *thread )
137 int event;
138 struct pipe *pipe = (struct pipe *)obj;
139 assert( obj->ops == &pipe_ops );
141 event = (pipe->side == READ_SIDE) ? READ_EVENT : WRITE_EVENT;
142 if (check_select_events( &pipe->select, event ))
144 /* stop waiting on select() if we are signaled */
145 set_select_events( &pipe->select, 0 );
146 return 1;
148 else
150 /* restart waiting on select() if we are no longer signaled */
151 if (obj->head) set_select_events( &pipe->select, event );
152 return 0;
156 static int pipe_get_read_fd( struct object *obj )
158 struct pipe *pipe = (struct pipe *)obj;
159 assert( obj->ops == &pipe_ops );
161 if (!pipe->other)
163 set_error( ERROR_BROKEN_PIPE );
164 return -1;
166 if (pipe->side != READ_SIDE) /* FIXME: should not be necessary */
168 set_error( ERROR_ACCESS_DENIED );
169 return -1;
171 return dup( pipe->select.fd );
174 static int pipe_get_write_fd( struct object *obj )
176 struct pipe *pipe = (struct pipe *)obj;
177 assert( obj->ops == &pipe_ops );
179 if (!pipe->other)
181 set_error( ERROR_BROKEN_PIPE );
182 return -1;
184 if (pipe->side != WRITE_SIDE) /* FIXME: should not be necessary */
186 set_error( ERROR_ACCESS_DENIED );
187 return -1;
189 return dup( pipe->select.fd );
192 static int pipe_get_info( struct object *obj, struct get_file_info_request *req )
194 req->type = FILE_TYPE_PIPE;
195 req->attr = 0;
196 req->access_time = 0;
197 req->write_time = 0;
198 req->size_high = 0;
199 req->size_low = 0;
200 req->links = 0;
201 req->index_high = 0;
202 req->index_low = 0;
203 req->serial = 0;
204 return 1;
207 static void pipe_destroy( struct object *obj )
209 struct pipe *pipe = (struct pipe *)obj;
210 assert( obj->ops == &pipe_ops );
212 if (pipe->other) pipe->other->other = NULL;
213 unregister_select_user( &pipe->select );
214 close( pipe->select.fd );
217 /* create an anonymous pipe */
218 DECL_HANDLER(create_pipe)
220 struct object *obj[2];
221 int hread = -1, hwrite = -1;
223 if (create_pipe( obj ))
225 hread = alloc_handle( current->process, obj[0],
226 STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|GENERIC_READ,
227 req->inherit );
228 if (hread != -1)
230 hwrite = alloc_handle( current->process, obj[1],
231 STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|GENERIC_WRITE,
232 req->inherit );
233 if (hwrite == -1)
234 close_handle( current->process, hread );
236 release_object( obj[0] );
237 release_object( obj[1] );
239 req->handle_read = hread;
240 req->handle_write = hwrite;