Added wine_server_fd_to_handle to replace FILE_DupUnixHandle.
[wine/multimedia.git] / server / pipe.c
blobd135a2250a78f72ac2e44755630069c002e2e067
1 /*
2 * Server-side pipe management
4 * Copyright (C) 1998 Alexandre Julliard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include "config.h"
23 #include <assert.h>
24 #include <fcntl.h>
25 #include <string.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #ifdef HAVE_SYS_ERRNO_H
29 #include <sys/errno.h>
30 #endif
31 #include <sys/time.h>
32 #include <sys/types.h>
33 #include <time.h>
34 #include <unistd.h>
36 #include "winbase.h"
38 #include "handle.h"
39 #include "thread.h"
40 #include "request.h"
42 enum side { READ_SIDE, WRITE_SIDE };
44 struct pipe
46 struct object obj; /* object header */
47 struct pipe *other; /* the pipe other end */
48 enum side side; /* which side of the pipe is this */
51 static void pipe_dump( struct object *obj, int verbose );
52 static int pipe_get_poll_events( struct object *obj );
53 static int pipe_get_fd( struct object *obj );
54 static int pipe_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags );
55 static void pipe_destroy( struct object *obj );
57 static const struct object_ops pipe_ops =
59 sizeof(struct pipe), /* size */
60 pipe_dump, /* dump */
61 default_poll_add_queue, /* add_queue */
62 default_poll_remove_queue, /* remove_queue */
63 default_poll_signaled, /* signaled */
64 no_satisfied, /* satisfied */
65 pipe_get_poll_events, /* get_poll_events */
66 default_poll_event, /* poll_event */
67 pipe_get_fd, /* get_fd */
68 no_flush, /* flush */
69 pipe_get_info, /* get_file_info */
70 NULL, /* queue_async */
71 pipe_destroy /* destroy */
75 static struct pipe *create_pipe_side( int fd, int side )
77 struct pipe *pipe;
79 if ((pipe = alloc_object( &pipe_ops, fd )))
81 pipe->other = NULL;
82 pipe->side = side;
84 return pipe;
87 static int create_pipe( struct object *obj[2] )
89 struct pipe *read_pipe;
90 struct pipe *write_pipe;
91 int fd[2];
93 if (pipe( fd ) == -1)
95 file_set_error();
96 return 0;
98 if ((read_pipe = create_pipe_side( fd[0], READ_SIDE )))
100 if ((write_pipe = create_pipe_side( fd[1], WRITE_SIDE )))
102 write_pipe->other = read_pipe;
103 read_pipe->other = write_pipe;
104 obj[0] = &read_pipe->obj;
105 obj[1] = &write_pipe->obj;
106 return 1;
108 release_object( read_pipe );
110 else close( fd[1] );
111 return 0;
114 static void pipe_dump( struct object *obj, int verbose )
116 struct pipe *pipe = (struct pipe *)obj;
117 assert( obj->ops == &pipe_ops );
118 fprintf( stderr, "Pipe %s-side fd=%d\n",
119 (pipe->side == READ_SIDE) ? "read" : "write", pipe->obj.fd );
122 static int pipe_get_poll_events( struct object *obj )
124 struct pipe *pipe = (struct pipe *)obj;
125 assert( obj->ops == &pipe_ops );
126 return (pipe->side == READ_SIDE) ? POLLIN : POLLOUT;
129 static int pipe_get_fd( struct object *obj )
131 struct pipe *pipe = (struct pipe *)obj;
132 assert( obj->ops == &pipe_ops );
134 if (!pipe->other)
136 set_error( STATUS_PIPE_BROKEN );
137 return -1;
139 return pipe->obj.fd;
142 static int pipe_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags )
144 if (reply)
146 reply->type = FILE_TYPE_PIPE;
147 reply->attr = 0;
148 reply->access_time = 0;
149 reply->write_time = 0;
150 reply->size_high = 0;
151 reply->size_low = 0;
152 reply->links = 0;
153 reply->index_high = 0;
154 reply->index_low = 0;
155 reply->serial = 0;
157 *flags = 0;
158 return FD_TYPE_DEFAULT;
161 static void pipe_destroy( struct object *obj )
163 struct pipe *pipe = (struct pipe *)obj;
164 assert( obj->ops == &pipe_ops );
166 if (pipe->other) pipe->other->other = NULL;
169 /* create an anonymous pipe */
170 DECL_HANDLER(create_pipe)
172 struct object *obj[2];
173 obj_handle_t hread = 0, hwrite = 0;
175 if (create_pipe( obj ))
177 hread = alloc_handle( current->process, obj[0],
178 STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|GENERIC_READ,
179 req->inherit );
180 if (hread)
182 hwrite = alloc_handle( current->process, obj[1],
183 STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|GENERIC_WRITE,
184 req->inherit );
185 if (!hwrite) close_handle( current->process, hread, NULL );
187 release_object( obj[0] );
188 release_object( obj[1] );
190 reply->handle_read = hread;
191 reply->handle_write = hwrite;