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
29 #include <sys/types.h>
40 enum side
{ READ_SIDE
, WRITE_SIDE
};
44 struct object obj
; /* object header */
45 struct fd
*fd
; /* pipe file descriptor */
46 struct pipe
*other
; /* the pipe other end */
47 enum side side
; /* which side of the pipe is this */
50 static void pipe_dump( struct object
*obj
, int verbose
);
51 static struct fd
*pipe_get_fd( struct object
*obj
);
52 static void pipe_destroy( struct object
*obj
);
54 static int pipe_get_poll_events( struct fd
*fd
);
55 static int pipe_get_info( struct fd
*fd
, struct get_file_info_reply
*reply
, int *flags
);
57 static const struct object_ops pipe_ops
=
59 sizeof(struct pipe
), /* size */
61 default_fd_add_queue
, /* add_queue */
62 default_fd_remove_queue
, /* remove_queue */
63 default_fd_signaled
, /* signaled */
64 no_satisfied
, /* satisfied */
65 pipe_get_fd
, /* get_fd */
66 pipe_destroy
/* destroy */
69 static const struct fd_ops pipe_fd_ops
=
71 pipe_get_poll_events
, /* get_poll_events */
72 default_poll_event
, /* poll_event */
74 pipe_get_info
, /* get_file_info */
75 no_queue_async
/* queue_async */
79 static struct pipe
*create_pipe_side( int fd
, int side
)
83 if ((pipe
= alloc_object( &pipe_ops
)))
88 if (!(pipe
->fd
= create_anonymous_fd( &pipe_fd_ops
, fd
, &pipe
->obj
)))
90 release_object( pipe
);
96 static int create_pipe( struct object
*obj
[2] )
98 struct pipe
*read_pipe
;
99 struct pipe
*write_pipe
;
102 if (pipe( fd
) == -1)
107 if ((read_pipe
= create_pipe_side( fd
[0], READ_SIDE
)))
109 if ((write_pipe
= create_pipe_side( fd
[1], WRITE_SIDE
)))
111 write_pipe
->other
= read_pipe
;
112 read_pipe
->other
= write_pipe
;
113 obj
[0] = &read_pipe
->obj
;
114 obj
[1] = &write_pipe
->obj
;
117 release_object( read_pipe
);
123 static void pipe_dump( struct object
*obj
, int verbose
)
125 struct pipe
*pipe
= (struct pipe
*)obj
;
126 assert( obj
->ops
== &pipe_ops
);
127 fprintf( stderr
, "Pipe %s-side fd=%p\n",
128 (pipe
->side
== READ_SIDE
) ? "read" : "write", pipe
->fd
);
131 static int pipe_get_poll_events( struct fd
*fd
)
133 struct pipe
*pipe
= get_fd_user( fd
);
134 assert( pipe
->obj
.ops
== &pipe_ops
);
135 return (pipe
->side
== READ_SIDE
) ? POLLIN
: POLLOUT
;
138 static struct fd
*pipe_get_fd( struct object
*obj
)
140 struct pipe
*pipe
= (struct pipe
*)obj
;
141 assert( obj
->ops
== &pipe_ops
);
145 set_error( STATUS_PIPE_BROKEN
);
148 return (struct fd
*)grab_object( pipe
->fd
);
151 static int pipe_get_info( struct fd
*fd
, struct get_file_info_reply
*reply
, int *flags
)
155 reply
->type
= FILE_TYPE_PIPE
;
157 reply
->access_time
= 0;
158 reply
->write_time
= 0;
159 reply
->size_high
= 0;
162 reply
->index_high
= 0;
163 reply
->index_low
= 0;
167 return FD_TYPE_DEFAULT
;
170 static void pipe_destroy( struct object
*obj
)
172 struct pipe
*pipe
= (struct pipe
*)obj
;
173 assert( obj
->ops
== &pipe_ops
);
175 if (pipe
->other
) pipe
->other
->other
= NULL
;
176 if (pipe
->fd
) release_object( pipe
->fd
);
179 /* create an anonymous pipe */
180 DECL_HANDLER(create_pipe
)
182 struct object
*obj
[2];
183 obj_handle_t hread
= 0, hwrite
= 0;
185 if (create_pipe( obj
))
187 hread
= alloc_handle( current
->process
, obj
[0],
188 STANDARD_RIGHTS_REQUIRED
|SYNCHRONIZE
|GENERIC_READ
,
192 hwrite
= alloc_handle( current
->process
, obj
[1],
193 STANDARD_RIGHTS_REQUIRED
|SYNCHRONIZE
|GENERIC_WRITE
,
195 if (!hwrite
) close_handle( current
->process
, hread
, NULL
);
197 release_object( obj
[0] );
198 release_object( obj
[1] );
200 reply
->handle_read
= hread
;
201 reply
->handle_write
= hwrite
;