2 * Server-side pipe management
4 * Copyright (C) 1998 Alexandre Julliard
12 #include <sys/errno.h>
15 #include <sys/types.h>
21 #include "server/thread.h"
23 enum side
{ READ_SIDE
, WRITE_SIDE
};
27 struct object obj
; /* object header */
28 struct pipe
*other
; /* the pipe other end */
29 int fd
; /* Unix file descriptor */
30 enum side side
; /* which side of the pipe is this */
33 static void pipe_dump( struct object
*obj
, int verbose
);
34 static int pipe_add_queue( struct object
*obj
, struct wait_queue_entry
*entry
);
35 static void pipe_remove_queue( struct object
*obj
, struct wait_queue_entry
*entry
);
36 static int pipe_signaled( struct object
*obj
, struct thread
*thread
);
37 static int pipe_get_read_fd( struct object
*obj
);
38 static int pipe_get_write_fd( struct object
*obj
);
39 static int pipe_get_info( struct object
*obj
, struct get_file_info_reply
*reply
);
40 static void pipe_destroy( struct object
*obj
);
42 static const struct object_ops pipe_ops
=
56 static const struct select_ops select_ops
=
59 NULL
/* we never set a timeout on a pipe */
62 int create_pipe( struct object
*obj
[2] )
64 struct pipe
*newpipe
[2];
72 if (!(newpipe
[0] = mem_alloc( sizeof(struct pipe
) )))
78 if (!(newpipe
[1] = mem_alloc( sizeof(struct pipe
) )))
85 init_object( &newpipe
[0]->obj
, &pipe_ops
, NULL
);
86 init_object( &newpipe
[1]->obj
, &pipe_ops
, NULL
);
87 newpipe
[0]->fd
= fd
[0];
88 newpipe
[0]->other
= newpipe
[1];
89 newpipe
[0]->side
= READ_SIDE
;
90 newpipe
[1]->fd
= fd
[1];
91 newpipe
[1]->other
= newpipe
[0];
92 newpipe
[1]->side
= WRITE_SIDE
;
93 obj
[0] = &newpipe
[0]->obj
;
94 obj
[1] = &newpipe
[1]->obj
;
99 static void pipe_dump( struct object
*obj
, int verbose
)
101 struct pipe
*pipe
= (struct pipe
*)obj
;
102 assert( obj
->ops
== &pipe_ops
);
103 fprintf( stderr
, "Pipe %s-side fd=%d\n",
104 (pipe
->side
== READ_SIDE
) ? "read" : "write", pipe
->fd
);
107 static int pipe_add_queue( struct object
*obj
, struct wait_queue_entry
*entry
)
109 struct pipe
*pipe
= (struct pipe
*)obj
;
110 assert( obj
->ops
== &pipe_ops
);
111 if (!obj
->head
) /* first on the queue */
113 if (!add_select_user( pipe
->fd
,
114 (pipe
->side
== READ_SIDE
) ? READ_EVENT
: WRITE_EVENT
,
117 SET_ERROR( ERROR_OUTOFMEMORY
);
121 add_queue( obj
, entry
);
125 static void pipe_remove_queue( struct object
*obj
, struct wait_queue_entry
*entry
)
127 struct pipe
*pipe
= (struct pipe
*)grab_object(obj
);
128 assert( obj
->ops
== &pipe_ops
);
130 remove_queue( obj
, entry
);
131 if (!obj
->head
) /* last on the queue is gone */
132 remove_select_user( pipe
->fd
);
133 release_object( obj
);
136 static int pipe_signaled( struct object
*obj
, struct thread
*thread
)
138 struct pipe
*pipe
= (struct pipe
*)obj
;
139 struct timeval tv
= { 0, 0 };
142 assert( obj
->ops
== &pipe_ops
);
144 FD_SET( pipe
->fd
, &fds
);
145 if (pipe
->side
== READ_SIDE
)
146 return select( pipe
->fd
+ 1, &fds
, NULL
, NULL
, &tv
) > 0;
148 return select( pipe
->fd
+ 1, NULL
, &fds
, NULL
, &tv
) > 0;
151 static int pipe_get_read_fd( struct object
*obj
)
153 struct pipe
*pipe
= (struct pipe
*)obj
;
154 assert( obj
->ops
== &pipe_ops
);
158 SET_ERROR( ERROR_BROKEN_PIPE
);
161 if (pipe
->side
!= READ_SIDE
) /* FIXME: should not be necessary */
163 SET_ERROR( ERROR_ACCESS_DENIED
);
166 return dup( pipe
->fd
);
169 static int pipe_get_write_fd( struct object
*obj
)
171 struct pipe
*pipe
= (struct pipe
*)obj
;
172 assert( obj
->ops
== &pipe_ops
);
176 SET_ERROR( ERROR_BROKEN_PIPE
);
179 if (pipe
->side
!= WRITE_SIDE
) /* FIXME: should not be necessary */
181 SET_ERROR( ERROR_ACCESS_DENIED
);
184 return dup( pipe
->fd
);
187 static int pipe_get_info( struct object
*obj
, struct get_file_info_reply
*reply
)
189 memset( reply
, 0, sizeof(*reply
) );
190 reply
->type
= FILE_TYPE_PIPE
;
194 static void pipe_destroy( struct object
*obj
)
196 struct pipe
*pipe
= (struct pipe
*)obj
;
197 assert( obj
->ops
== &pipe_ops
);
199 if (pipe
->other
) pipe
->other
->other
= NULL
;