Only include 'sys/user.h' for Linux. Fixes a compilation error on
[wine] / server / pipe.c
1 /*
2  * Server-side pipe management
3  *
4  * Copyright (C) 1998 Alexandre Julliard
5  */
6
7 #include "config.h"
8
9 #include <assert.h>
10 #include <fcntl.h>
11 #include <string.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #ifdef HAVE_SYS_ERRNO_H
15 #include <sys/errno.h>
16 #endif
17 #include <sys/time.h>
18 #include <sys/types.h>
19 #include <time.h>
20 #include <unistd.h>
21
22 #include "winbase.h"
23
24 #include "handle.h"
25 #include "thread.h"
26 #include "request.h"
27
28 enum side { READ_SIDE, WRITE_SIDE };
29
30 struct pipe
31 {
32     struct object       obj;         /* object header */
33     struct pipe        *other;       /* the pipe other end */
34     enum side           side;        /* which side of the pipe is this */
35 };
36
37 static void pipe_dump( struct object *obj, int verbose );
38 static int pipe_get_poll_events( struct object *obj );
39 static int pipe_get_fd( struct object *obj );
40 static int pipe_get_info( struct object *obj, struct get_file_info_request *req );
41 static void pipe_destroy( struct object *obj );
42
43 static const struct object_ops pipe_ops =
44 {
45     sizeof(struct pipe),          /* size */
46     pipe_dump,                    /* dump */
47     default_poll_add_queue,       /* add_queue */
48     default_poll_remove_queue,    /* remove_queue */
49     default_poll_signaled,        /* signaled */
50     no_satisfied,                 /* satisfied */
51     pipe_get_poll_events,         /* get_poll_events */
52     default_poll_event,           /* poll_event */
53     pipe_get_fd,                  /* get_fd */
54     no_flush,                     /* flush */
55     pipe_get_info,                /* get_file_info */
56     pipe_destroy                  /* destroy */
57 };
58
59
60 static struct pipe *create_pipe_side( int fd, int side )
61 {
62     struct pipe *pipe;
63
64     if ((pipe = alloc_object( &pipe_ops, fd )))
65     {
66         pipe->other  = NULL;
67         pipe->side   = side;
68     }
69     return pipe;
70 }
71
72 static int create_pipe( struct object *obj[2] )
73 {
74     struct pipe *read_pipe;
75     struct pipe *write_pipe;
76     int fd[2];
77
78     if (pipe( fd ) == -1)
79     {
80         file_set_error();
81         return 0;
82     }
83     if ((read_pipe = create_pipe_side( fd[0], READ_SIDE )))
84     {
85         if ((write_pipe = create_pipe_side( fd[1], WRITE_SIDE )))
86         {
87             write_pipe->other = read_pipe;
88             read_pipe->other  = write_pipe;
89             obj[0] = &read_pipe->obj;
90             obj[1] = &write_pipe->obj;
91             return 1;
92         }
93         release_object( read_pipe );
94     }
95     else close( fd[1] );
96     return 0;
97 }
98
99 static void pipe_dump( struct object *obj, int verbose )
100 {
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->obj.fd );
105 }
106
107 static int pipe_get_poll_events( struct object *obj )
108 {
109     struct pipe *pipe = (struct pipe *)obj;
110     assert( obj->ops == &pipe_ops );
111     return (pipe->side == READ_SIDE) ? POLLIN : POLLOUT;
112 }
113
114 static int pipe_get_fd( struct object *obj )
115 {
116     struct pipe *pipe = (struct pipe *)obj;
117     assert( obj->ops == &pipe_ops );
118
119     if (!pipe->other)
120     {
121         set_error( STATUS_PIPE_BROKEN );
122         return -1;
123     }
124     return pipe->obj.fd;
125 }
126
127 static int pipe_get_info( struct object *obj, struct get_file_info_request *req )
128 {
129     if (req)
130     {
131         req->type        = FILE_TYPE_PIPE;
132         req->attr        = 0;
133         req->access_time = 0;
134         req->write_time  = 0;
135         req->size_high   = 0;
136         req->size_low    = 0;
137         req->links       = 0;
138         req->index_high  = 0;
139         req->index_low   = 0;
140         req->serial      = 0;
141     }
142     return FD_TYPE_DEFAULT;
143 }
144
145 static void pipe_destroy( struct object *obj )
146 {
147     struct pipe *pipe = (struct pipe *)obj;
148     assert( obj->ops == &pipe_ops );
149
150     if (pipe->other) pipe->other->other = NULL;
151 }
152
153 /* create an anonymous pipe */
154 DECL_HANDLER(create_pipe)
155 {
156     struct object *obj[2];
157     handle_t hread = 0, hwrite = 0;
158
159     if (create_pipe( obj ))
160     {
161         hread = alloc_handle( current->process, obj[0],
162                               STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|GENERIC_READ,
163                               req->inherit );
164         if (hread)
165         {
166             hwrite = alloc_handle( current->process, obj[1],
167                                    STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|GENERIC_WRITE,
168                                    req->inherit );
169             if (!hwrite) close_handle( current->process, hread, NULL );
170         }
171         release_object( obj[0] );
172         release_object( obj[1] );
173     }
174     req->handle_read  = hread;
175     req->handle_write = hwrite;
176 }