2 * Server-side pipe management
4 * Copyright (C) 1998 Alexandre Julliard
14 #ifdef HAVE_SYS_ERRNO_H
15 #include <sys/errno.h>
19 #include <sys/types.h>
30 enum side
{ READ_SIDE
, WRITE_SIDE
};
34 struct object obj
; /* object header */
35 struct pipe
*other
; /* the pipe other end */
36 struct select_user select
; /* select user */
37 enum side side
; /* which side of the pipe is this */
40 static void pipe_dump( struct object
*obj
, int verbose
);
41 static int pipe_add_queue( struct object
*obj
, struct wait_queue_entry
*entry
);
42 static void pipe_remove_queue( struct object
*obj
, struct wait_queue_entry
*entry
);
43 static int pipe_signaled( struct object
*obj
, struct thread
*thread
);
44 static int pipe_get_read_fd( struct object
*obj
);
45 static int pipe_get_write_fd( struct object
*obj
);
46 static int pipe_get_info( struct object
*obj
, struct get_file_info_request
*req
);
47 static void pipe_destroy( struct object
*obj
);
49 static const struct object_ops pipe_ops
=
65 static struct pipe
*create_pipe_side( int fd
, int side
)
69 if ((pipe
= alloc_object( &pipe_ops
)))
72 pipe
->select
.func
= default_select_event
;
73 pipe
->select
.private = pipe
;
76 register_select_user( &pipe
->select
);
81 static int create_pipe( struct object
*obj
[2] )
83 struct pipe
*read_pipe
;
84 struct pipe
*write_pipe
;
92 if ((read_pipe
= create_pipe_side( fd
[0], READ_SIDE
)))
94 if ((write_pipe
= create_pipe_side( fd
[1], WRITE_SIDE
)))
96 write_pipe
->other
= read_pipe
;
97 read_pipe
->other
= write_pipe
;
98 obj
[0] = &read_pipe
->obj
;
99 obj
[1] = &write_pipe
->obj
;
102 release_object( read_pipe
);
109 static void pipe_dump( struct object
*obj
, int verbose
)
111 struct pipe
*pipe
= (struct pipe
*)obj
;
112 assert( obj
->ops
== &pipe_ops
);
113 fprintf( stderr
, "Pipe %s-side fd=%d\n",
114 (pipe
->side
== READ_SIDE
) ? "read" : "write", pipe
->select
.fd
);
117 static int pipe_add_queue( struct object
*obj
, struct wait_queue_entry
*entry
)
119 struct pipe
*pipe
= (struct pipe
*)obj
;
120 assert( obj
->ops
== &pipe_ops
);
121 if (!obj
->head
) /* first on the queue */
122 set_select_events( &pipe
->select
,
123 (pipe
->side
== READ_SIDE
) ? READ_EVENT
: WRITE_EVENT
);
124 add_queue( obj
, entry
);
128 static void pipe_remove_queue( struct object
*obj
, struct wait_queue_entry
*entry
)
130 struct pipe
*pipe
= (struct pipe
*)grab_object(obj
);
131 assert( obj
->ops
== &pipe_ops
);
133 remove_queue( obj
, entry
);
134 if (!obj
->head
) /* last on the queue is gone */
135 set_select_events( &pipe
->select
, 0 );
136 release_object( obj
);
139 static int pipe_signaled( struct object
*obj
, struct thread
*thread
)
142 struct pipe
*pipe
= (struct pipe
*)obj
;
143 assert( obj
->ops
== &pipe_ops
);
145 event
= (pipe
->side
== READ_SIDE
) ? READ_EVENT
: WRITE_EVENT
;
146 if (check_select_events( &pipe
->select
, event
))
148 /* stop waiting on select() if we are signaled */
149 set_select_events( &pipe
->select
, 0 );
154 /* restart waiting on select() if we are no longer signaled */
155 if (obj
->head
) set_select_events( &pipe
->select
, event
);
160 static int pipe_get_read_fd( struct object
*obj
)
162 struct pipe
*pipe
= (struct pipe
*)obj
;
163 assert( obj
->ops
== &pipe_ops
);
167 set_error( ERROR_BROKEN_PIPE
);
170 if (pipe
->side
!= READ_SIDE
) /* FIXME: should not be necessary */
172 set_error( ERROR_ACCESS_DENIED
);
175 return dup( pipe
->select
.fd
);
178 static int pipe_get_write_fd( struct object
*obj
)
180 struct pipe
*pipe
= (struct pipe
*)obj
;
181 assert( obj
->ops
== &pipe_ops
);
185 set_error( ERROR_BROKEN_PIPE
);
188 if (pipe
->side
!= WRITE_SIDE
) /* FIXME: should not be necessary */
190 set_error( ERROR_ACCESS_DENIED
);
193 return dup( pipe
->select
.fd
);
196 static int pipe_get_info( struct object
*obj
, struct get_file_info_request
*req
)
198 req
->type
= FILE_TYPE_PIPE
;
200 req
->access_time
= 0;
211 static void pipe_destroy( struct object
*obj
)
213 struct pipe
*pipe
= (struct pipe
*)obj
;
214 assert( obj
->ops
== &pipe_ops
);
216 if (pipe
->other
) pipe
->other
->other
= NULL
;
217 unregister_select_user( &pipe
->select
);
218 close( pipe
->select
.fd
);
221 /* create an anonymous pipe */
222 DECL_HANDLER(create_pipe
)
224 struct object
*obj
[2];
225 int hread
= -1, hwrite
= -1;
227 if (create_pipe( obj
))
229 hread
= alloc_handle( current
->process
, obj
[0],
230 STANDARD_RIGHTS_REQUIRED
|SYNCHRONIZE
|GENERIC_READ
,
234 hwrite
= alloc_handle( current
->process
, obj
[1],
235 STANDARD_RIGHTS_REQUIRED
|SYNCHRONIZE
|GENERIC_WRITE
,
238 close_handle( current
->process
, hread
);
240 release_object( obj
[0] );
241 release_object( obj
[1] );
243 req
->handle_read
= hread
;
244 req
->handle_write
= hwrite
;