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 void 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 void 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 */
109 add_select_user( pipe
->fd
,
110 (pipe
->side
== READ_SIDE
) ? READ_EVENT
: WRITE_EVENT
,
112 add_queue( obj
, entry
);
115 static void pipe_remove_queue( struct object
*obj
, struct wait_queue_entry
*entry
)
117 struct pipe
*pipe
= (struct pipe
*)grab_object(obj
);
118 assert( obj
->ops
== &pipe_ops
);
120 remove_queue( obj
, entry
);
121 if (!obj
->head
) /* last on the queue is gone */
122 remove_select_user( pipe
->fd
);
123 release_object( obj
);
126 static int pipe_signaled( struct object
*obj
, struct thread
*thread
)
128 struct pipe
*pipe
= (struct pipe
*)obj
;
129 struct timeval tv
= { 0, 0 };
132 assert( obj
->ops
== &pipe_ops
);
134 FD_SET( pipe
->fd
, &fds
);
135 if (pipe
->side
== READ_SIDE
)
136 return select( pipe
->fd
+ 1, &fds
, NULL
, NULL
, &tv
) > 0;
138 return select( pipe
->fd
+ 1, NULL
, &fds
, NULL
, &tv
) > 0;
141 static int pipe_get_read_fd( struct object
*obj
)
143 struct pipe
*pipe
= (struct pipe
*)obj
;
144 assert( obj
->ops
== &pipe_ops
);
148 SET_ERROR( ERROR_BROKEN_PIPE
);
151 if (pipe
->side
!= READ_SIDE
) /* FIXME: should not be necessary */
153 SET_ERROR( ERROR_ACCESS_DENIED
);
156 return dup( pipe
->fd
);
159 static int pipe_get_write_fd( struct object
*obj
)
161 struct pipe
*pipe
= (struct pipe
*)obj
;
162 assert( obj
->ops
== &pipe_ops
);
166 SET_ERROR( ERROR_BROKEN_PIPE
);
169 if (pipe
->side
!= WRITE_SIDE
) /* FIXME: should not be necessary */
171 SET_ERROR( ERROR_ACCESS_DENIED
);
174 return dup( pipe
->fd
);
177 static void pipe_destroy( struct object
*obj
)
179 struct pipe
*pipe
= (struct pipe
*)obj
;
180 assert( obj
->ops
== &pipe_ops
);
182 if (pipe
->other
) pipe
->other
->other
= NULL
;