Do not change the WS_CHILD style in SetParent.
[wine.git] / server / pipe.c
blobd86fde86ee3d20503822e81b9a868f4a0ca8f7e8
1 /*
2 * Server-side pipe management
4 * Copyright (C) 1998 Alexandre Julliard
5 */
7 #include "config.h"
9 #include <assert.h>
10 #include <fcntl.h>
11 #include <string.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #ifdef HAVE_SYS_ERRNO_H
15 #include <sys/errno.h>
16 #endif
17 #include <sys/stat.h>
18 #include <sys/time.h>
19 #include <sys/types.h>
20 #include <time.h>
21 #include <unistd.h>
23 #include "winbase.h"
25 #include "handle.h"
26 #include "thread.h"
27 #include "request.h"
29 enum side { READ_SIDE, WRITE_SIDE };
31 struct pipe
33 struct object obj; /* object header */
34 struct pipe *other; /* the pipe other end */
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_get_poll_events( struct object *obj );
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), /* size */
48 pipe_dump, /* dump */
49 default_poll_add_queue, /* add_queue */
50 default_poll_remove_queue, /* remove_queue */
51 default_poll_signaled, /* signaled */
52 no_satisfied, /* satisfied */
53 pipe_get_poll_events, /* get_poll_events */
54 default_poll_event, /* poll_event */
55 pipe_get_read_fd, /* get_read_fd */
56 pipe_get_write_fd, /* get_write_fd */
57 no_flush, /* flush */
58 pipe_get_info, /* get_file_info */
59 pipe_destroy /* destroy */
63 static struct pipe *create_pipe_side( int fd, int side )
65 struct pipe *pipe;
67 if ((pipe = alloc_object( &pipe_ops, fd )))
69 pipe->other = NULL;
70 pipe->side = side;
72 return pipe;
75 static int create_pipe( struct object *obj[2] )
77 struct pipe *read_pipe;
78 struct pipe *write_pipe;
79 int fd[2];
81 if (pipe( fd ) == -1)
83 file_set_error();
84 return 0;
86 if ((read_pipe = create_pipe_side( fd[0], READ_SIDE )))
88 if ((write_pipe = create_pipe_side( fd[1], WRITE_SIDE )))
90 write_pipe->other = read_pipe;
91 read_pipe->other = write_pipe;
92 obj[0] = &read_pipe->obj;
93 obj[1] = &write_pipe->obj;
94 return 1;
96 release_object( read_pipe );
98 else close( fd[1] );
99 return 0;
102 static void pipe_dump( struct object *obj, int verbose )
104 struct pipe *pipe = (struct pipe *)obj;
105 assert( obj->ops == &pipe_ops );
106 fprintf( stderr, "Pipe %s-side fd=%d\n",
107 (pipe->side == READ_SIDE) ? "read" : "write", pipe->obj.fd );
110 static int pipe_get_poll_events( struct object *obj )
112 struct pipe *pipe = (struct pipe *)obj;
113 assert( obj->ops == &pipe_ops );
114 return (pipe->side == READ_SIDE) ? POLLIN : POLLOUT;
117 static int pipe_get_read_fd( struct object *obj )
119 struct pipe *pipe = (struct pipe *)obj;
120 assert( obj->ops == &pipe_ops );
122 if (!pipe->other)
124 set_error( STATUS_PIPE_BROKEN );
125 return -1;
127 if (pipe->side != READ_SIDE) /* FIXME: should not be necessary */
129 set_error( STATUS_ACCESS_DENIED );
130 return -1;
132 return dup( pipe->obj.fd );
135 static int pipe_get_write_fd( struct object *obj )
137 struct pipe *pipe = (struct pipe *)obj;
138 assert( obj->ops == &pipe_ops );
140 if (!pipe->other)
142 set_error( STATUS_PIPE_BROKEN );
143 return -1;
145 if (pipe->side != WRITE_SIDE) /* FIXME: should not be necessary */
147 set_error( STATUS_ACCESS_DENIED );
148 return -1;
150 return dup( pipe->obj.fd );
153 static int pipe_get_info( struct object *obj, struct get_file_info_request *req )
155 req->type = FILE_TYPE_PIPE;
156 req->attr = 0;
157 req->access_time = 0;
158 req->write_time = 0;
159 req->size_high = 0;
160 req->size_low = 0;
161 req->links = 0;
162 req->index_high = 0;
163 req->index_low = 0;
164 req->serial = 0;
165 return 1;
168 static void pipe_destroy( struct object *obj )
170 struct pipe *pipe = (struct pipe *)obj;
171 assert( obj->ops == &pipe_ops );
173 if (pipe->other) pipe->other->other = NULL;
176 /* create an anonymous pipe */
177 DECL_HANDLER(create_pipe)
179 struct object *obj[2];
180 int hread = -1, hwrite = -1;
182 if (create_pipe( obj ))
184 hread = alloc_handle( current->process, obj[0],
185 STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|GENERIC_READ,
186 req->inherit );
187 if (hread != -1)
189 hwrite = alloc_handle( current->process, obj[1],
190 STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|GENERIC_WRITE,
191 req->inherit );
192 if (hwrite == -1)
193 close_handle( current->process, hread );
195 release_object( obj[0] );
196 release_object( obj[1] );
198 req->handle_read = hread;
199 req->handle_write = hwrite;