Added MenuItemFromPoint stub.
[wine/dcerpc.git] / server / pipe.c
blobc99a8afe460965aacbdcaf223eda72ddd4338664
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 #ifdef HAVE_SYS_ERRNO_H
13 #include <sys/errno.h>
14 #endif
15 #include <sys/stat.h>
16 #include <sys/time.h>
17 #include <sys/types.h>
18 #include <time.h>
19 #include <unistd.h>
21 #include "winerror.h"
22 #include "winbase.h"
24 #include "handle.h"
25 #include "thread.h"
26 #include "request.h"
28 enum side { READ_SIDE, WRITE_SIDE };
30 struct pipe
32 struct object obj; /* object header */
33 struct pipe *other; /* the pipe other end */
34 struct select_user select; /* select user */
35 enum side side; /* which side of the pipe is this */
38 static void pipe_dump( struct object *obj, int verbose );
39 static int pipe_add_queue( struct object *obj, struct wait_queue_entry *entry );
40 static void pipe_remove_queue( struct object *obj, struct wait_queue_entry *entry );
41 static int pipe_signaled( struct object *obj, struct thread *thread );
42 static int pipe_get_read_fd( struct object *obj );
43 static int pipe_get_write_fd( struct object *obj );
44 static int pipe_get_info( struct object *obj, struct get_file_info_request *req );
45 static void pipe_destroy( struct object *obj );
47 static const struct object_ops pipe_ops =
49 sizeof(struct pipe),
50 pipe_dump,
51 pipe_add_queue,
52 pipe_remove_queue,
53 pipe_signaled,
54 no_satisfied,
55 pipe_get_read_fd,
56 pipe_get_write_fd,
57 no_flush,
58 pipe_get_info,
59 pipe_destroy
63 static struct pipe *create_pipe_side( int fd, int side )
65 struct pipe *pipe;
67 if ((pipe = alloc_object( &pipe_ops )))
69 pipe->select.fd = fd;
70 pipe->select.func = default_select_event;
71 pipe->select.private = pipe;
72 pipe->other = NULL;
73 pipe->side = side;
74 register_select_user( &pipe->select );
76 return pipe;
79 static int create_pipe( struct object *obj[2] )
81 struct pipe *read_pipe;
82 struct pipe *write_pipe;
83 int fd[2];
85 if (pipe( fd ) == -1)
87 file_set_error();
88 return 0;
90 if ((read_pipe = create_pipe_side( fd[0], READ_SIDE )))
92 if ((write_pipe = create_pipe_side( fd[1], WRITE_SIDE )))
94 write_pipe->other = read_pipe;
95 read_pipe->other = write_pipe;
96 obj[0] = &read_pipe->obj;
97 obj[1] = &write_pipe->obj;
98 return 1;
100 release_object( read_pipe );
102 close( fd[0] );
103 close( fd[1] );
104 return 0;
107 static void pipe_dump( struct object *obj, int verbose )
109 struct pipe *pipe = (struct pipe *)obj;
110 assert( obj->ops == &pipe_ops );
111 fprintf( stderr, "Pipe %s-side fd=%d\n",
112 (pipe->side == READ_SIDE) ? "read" : "write", pipe->select.fd );
115 static int pipe_add_queue( struct object *obj, struct wait_queue_entry *entry )
117 struct pipe *pipe = (struct pipe *)obj;
118 assert( obj->ops == &pipe_ops );
119 if (!obj->head) /* first on the queue */
120 set_select_events( &pipe->select,
121 (pipe->side == READ_SIDE) ? READ_EVENT : WRITE_EVENT );
122 add_queue( obj, entry );
123 return 1;
126 static void pipe_remove_queue( struct object *obj, struct wait_queue_entry *entry )
128 struct pipe *pipe = (struct pipe *)grab_object(obj);
129 assert( obj->ops == &pipe_ops );
131 remove_queue( obj, entry );
132 if (!obj->head) /* last on the queue is gone */
133 set_select_events( &pipe->select, 0 );
134 release_object( obj );
137 static int pipe_signaled( struct object *obj, struct thread *thread )
139 int event;
140 struct pipe *pipe = (struct pipe *)obj;
141 assert( obj->ops == &pipe_ops );
143 event = (pipe->side == READ_SIDE) ? READ_EVENT : WRITE_EVENT;
144 if (check_select_events( &pipe->select, event ))
146 /* stop waiting on select() if we are signaled */
147 set_select_events( &pipe->select, 0 );
148 return 1;
150 else
152 /* restart waiting on select() if we are no longer signaled */
153 if (obj->head) set_select_events( &pipe->select, event );
154 return 0;
158 static int pipe_get_read_fd( struct object *obj )
160 struct pipe *pipe = (struct pipe *)obj;
161 assert( obj->ops == &pipe_ops );
163 if (!pipe->other)
165 set_error( ERROR_BROKEN_PIPE );
166 return -1;
168 if (pipe->side != READ_SIDE) /* FIXME: should not be necessary */
170 set_error( ERROR_ACCESS_DENIED );
171 return -1;
173 return dup( pipe->select.fd );
176 static int pipe_get_write_fd( struct object *obj )
178 struct pipe *pipe = (struct pipe *)obj;
179 assert( obj->ops == &pipe_ops );
181 if (!pipe->other)
183 set_error( ERROR_BROKEN_PIPE );
184 return -1;
186 if (pipe->side != WRITE_SIDE) /* FIXME: should not be necessary */
188 set_error( ERROR_ACCESS_DENIED );
189 return -1;
191 return dup( pipe->select.fd );
194 static int pipe_get_info( struct object *obj, struct get_file_info_request *req )
196 req->type = FILE_TYPE_PIPE;
197 req->attr = 0;
198 req->access_time = 0;
199 req->write_time = 0;
200 req->size_high = 0;
201 req->size_low = 0;
202 req->links = 0;
203 req->index_high = 0;
204 req->index_low = 0;
205 req->serial = 0;
206 return 1;
209 static void pipe_destroy( struct object *obj )
211 struct pipe *pipe = (struct pipe *)obj;
212 assert( obj->ops == &pipe_ops );
214 if (pipe->other) pipe->other->other = NULL;
215 unregister_select_user( &pipe->select );
216 close( pipe->select.fd );
219 /* create an anonymous pipe */
220 DECL_HANDLER(create_pipe)
222 struct object *obj[2];
223 int hread = -1, hwrite = -1;
225 if (create_pipe( obj ))
227 hread = alloc_handle( current->process, obj[0],
228 STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|GENERIC_READ,
229 req->inherit );
230 if (hread != -1)
232 hwrite = alloc_handle( current->process, obj[1],
233 STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|GENERIC_WRITE,
234 req->inherit );
235 if (hwrite == -1)
236 close_handle( current->process, hread );
238 release_object( obj[0] );
239 release_object( obj[1] );
241 req->handle_read = hread;
242 req->handle_write = hwrite;