2 * Server-side pipe management
4 * Copyright (C) 1998 Alexandre Julliard
11 #include <sys/errno.h>
14 #include <sys/types.h>
20 #include "server/thread.h"
22 enum side
{ READ_SIDE
, WRITE_SIDE
};
26 struct object obj
; /* object header */
27 struct pipe
*other
; /* the pipe other end */
28 int fd
; /* Unix file descriptor */
29 enum side side
; /* which side of the pipe is this */
32 static void pipe_dump( struct object
*obj
, int verbose
);
33 static int pipe_add_queue( struct object
*obj
, struct wait_queue_entry
*entry
);
34 static void pipe_remove_queue( struct object
*obj
, struct wait_queue_entry
*entry
);
35 static int pipe_signaled( struct object
*obj
, struct thread
*thread
);
36 static int pipe_get_read_fd( struct object
*obj
);
37 static int pipe_get_write_fd( struct object
*obj
);
38 static void pipe_destroy( struct object
*obj
);
40 static const struct object_ops pipe_ops
=
53 static const struct select_ops select_ops
=
56 NULL
/* we never set a timeout on a pipe */
59 int create_pipe( struct object
*obj
[2] )
61 struct pipe
*newpipe
[2];
69 if (!(newpipe
[0] = mem_alloc( sizeof(struct pipe
) )))
75 if (!(newpipe
[1] = mem_alloc( sizeof(struct pipe
) )))
82 init_object( &newpipe
[0]->obj
, &pipe_ops
, NULL
);
83 init_object( &newpipe
[1]->obj
, &pipe_ops
, NULL
);
84 newpipe
[0]->fd
= fd
[0];
85 newpipe
[0]->other
= newpipe
[1];
86 newpipe
[0]->side
= READ_SIDE
;
87 newpipe
[1]->fd
= fd
[1];
88 newpipe
[1]->other
= newpipe
[0];
89 newpipe
[1]->side
= WRITE_SIDE
;
90 obj
[0] = &newpipe
[0]->obj
;
91 obj
[1] = &newpipe
[1]->obj
;
96 static void pipe_dump( struct object
*obj
, int verbose
)
98 struct pipe
*pipe
= (struct pipe
*)obj
;
99 assert( obj
->ops
== &pipe_ops
);
100 printf( "Pipe %s-side fd=%d\n",
101 (pipe
->side
== READ_SIDE
) ? "read" : "write", pipe
->fd
);
104 static int pipe_add_queue( struct object
*obj
, struct wait_queue_entry
*entry
)
106 struct pipe
*pipe
= (struct pipe
*)obj
;
107 assert( obj
->ops
== &pipe_ops
);
108 if (!obj
->head
) /* first on the queue */
110 if (!add_select_user( pipe
->fd
,
111 (pipe
->side
== READ_SIDE
) ? READ_EVENT
: WRITE_EVENT
,
114 SET_ERROR( ERROR_OUTOFMEMORY
);
118 add_queue( obj
, entry
);
122 static void pipe_remove_queue( struct object
*obj
, struct wait_queue_entry
*entry
)
124 struct pipe
*pipe
= (struct pipe
*)grab_object(obj
);
125 assert( obj
->ops
== &pipe_ops
);
127 remove_queue( obj
, entry
);
128 if (!obj
->head
) /* last on the queue is gone */
129 remove_select_user( pipe
->fd
);
130 release_object( obj
);
133 static int pipe_signaled( struct object
*obj
, struct thread
*thread
)
135 struct pipe
*pipe
= (struct pipe
*)obj
;
136 struct timeval tv
= { 0, 0 };
139 assert( obj
->ops
== &pipe_ops
);
141 FD_SET( pipe
->fd
, &fds
);
142 if (pipe
->side
== READ_SIDE
)
143 return select( pipe
->fd
+ 1, &fds
, NULL
, NULL
, &tv
) > 0;
145 return select( pipe
->fd
+ 1, NULL
, &fds
, NULL
, &tv
) > 0;
148 static int pipe_get_read_fd( struct object
*obj
)
150 struct pipe
*pipe
= (struct pipe
*)obj
;
151 assert( obj
->ops
== &pipe_ops
);
155 SET_ERROR( ERROR_BROKEN_PIPE
);
158 if (pipe
->side
!= READ_SIDE
) /* FIXME: should not be necessary */
160 SET_ERROR( ERROR_ACCESS_DENIED
);
163 return dup( pipe
->fd
);
166 static int pipe_get_write_fd( struct object
*obj
)
168 struct pipe
*pipe
= (struct pipe
*)obj
;
169 assert( obj
->ops
== &pipe_ops
);
173 SET_ERROR( ERROR_BROKEN_PIPE
);
176 if (pipe
->side
!= WRITE_SIDE
) /* FIXME: should not be necessary */
178 SET_ERROR( ERROR_ACCESS_DENIED
);
181 return dup( pipe
->fd
);
184 static void pipe_destroy( struct object
*obj
)
186 struct pipe
*pipe
= (struct pipe
*)obj
;
187 assert( obj
->ops
== &pipe_ops
);
189 if (pipe
->other
) pipe
->other
->other
= NULL
;