upload http
[bottlenecks.git] / rubbos / app / httpd-2.0.64 / srclib / apr / file_io / unix / pipe.c
1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2  * contributor license agreements.  See the NOTICE file distributed with
3  * this work for additional information regarding copyright ownership.
4  * The ASF licenses this file to You under the Apache License, Version 2.0
5  * (the "License"); you may not use this file except in compliance with
6  * the License.  You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "apr_arch_file_io.h"
18 #include "apr_strings.h"
19 #include "apr_portable.h"
20
21 #include "apr_arch_inherit.h"
22
23 /* Figure out how to get pipe block/nonblock on BeOS...
24  * Basically, BONE7 changed things again so that ioctl didn't work,
25  * but now fcntl does, hence we need to do this extra checking.
26  * The joys of beta programs. :-)
27  */
28 #if BEOS
29 #if !BONE7
30 # define BEOS_BLOCKING 1
31 #else
32 # define BEOS_BLOCKING 0
33 #endif
34 #endif
35
36 static apr_status_t pipeblock(apr_file_t *thepipe)
37 {
38 #if !BEOS_BLOCKING
39       int fd_flags;
40
41       fd_flags = fcntl(thepipe->filedes, F_GETFL, 0);
42 #  if defined(O_NONBLOCK)
43       fd_flags &= ~O_NONBLOCK;
44 #  elif defined(O_NDELAY)
45       fd_flags &= ~O_NDELAY;
46 #  elif defined(FNDELAY)
47       fd_flags &= ~O_FNDELAY;
48 #  else 
49       /* XXXX: this breaks things, but an alternative isn't obvious...*/
50       return APR_ENOTIMPL;
51 #  endif
52       if (fcntl(thepipe->filedes, F_SETFL, fd_flags) == -1) {
53           return errno;
54       }
55 #else /* BEOS_BLOCKING */
56
57 #  if BEOS_BONE /* This only works on BONE 0-6 */
58       int on = 0;
59       if (ioctl(thepipe->filedes, FIONBIO, &on, sizeof(on)) < 0) {
60           return errno;
61       }
62 #  else /* "classic" BeOS doesn't support this at all */
63       return APR_ENOTIMPL;
64 #  endif 
65  
66 #endif /* !BEOS_BLOCKING */
67
68     thepipe->blocking = BLK_ON;
69     return APR_SUCCESS;
70 }
71
72 static apr_status_t pipenonblock(apr_file_t *thepipe)
73 {
74 #if !BEOS_BLOCKING
75       int fd_flags = fcntl(thepipe->filedes, F_GETFL, 0);
76
77 #  if defined(O_NONBLOCK)
78       fd_flags |= O_NONBLOCK;
79 #  elif defined(O_NDELAY)
80       fd_flags |= O_NDELAY;
81 #  elif defined(FNDELAY)
82       fd_flags |= O_FNDELAY;
83 #  else
84       /* XXXX: this breaks things, but an alternative isn't obvious...*/
85       return APR_ENOTIMPL;
86 #  endif
87       if (fcntl(thepipe->filedes, F_SETFL, fd_flags) == -1) {
88           return errno;
89       }
90     
91 #else /* BEOS_BLOCKING */
92
93 #  if BEOS_BONE /* This only works on BONE 0-6 */
94       int on = 1;
95       if (ioctl(thepipe->filedes, FIONBIO, &on, sizeof(on)) < 0) {
96           return errno;
97       }
98 #  else /* "classic" BeOS doesn't support this at all */
99       return APR_ENOTIMPL;
100 #  endif
101
102 #endif /* !BEOS_BLOCKING */
103
104     thepipe->blocking = BLK_OFF;
105     return APR_SUCCESS;
106 }
107
108 APR_DECLARE(apr_status_t) apr_file_pipe_timeout_set(apr_file_t *thepipe, apr_interval_time_t timeout)
109 {
110     if (thepipe->is_pipe == 1) {
111         thepipe->timeout = timeout;
112         if (timeout >= 0) {
113             if (thepipe->blocking != BLK_OFF) { /* blocking or unknown state */
114                 return pipenonblock(thepipe);
115             }
116         }
117         else {
118             if (thepipe->blocking != BLK_ON) { /* non-blocking or unknown state */
119                 return pipeblock(thepipe);
120             }
121         }
122         return APR_SUCCESS;
123     }
124     return APR_EINVAL;
125 }
126
127 APR_DECLARE(apr_status_t) apr_file_pipe_timeout_get(apr_file_t *thepipe, apr_interval_time_t *timeout)
128 {
129     if (thepipe->is_pipe == 1) {
130         *timeout = thepipe->timeout;
131         return APR_SUCCESS;
132     }
133     return APR_EINVAL;
134 }
135
136 APR_DECLARE(apr_status_t) apr_os_pipe_put_ex(apr_file_t **file,
137                                              apr_os_file_t *thefile,
138                                              int register_cleanup,
139                                              apr_pool_t *pool)
140 {
141     int *dafile = thefile;
142     
143     (*file) = apr_pcalloc(pool, sizeof(apr_file_t));
144     (*file)->pool = pool;
145     (*file)->eof_hit = 0;
146     (*file)->is_pipe = 1;
147     (*file)->blocking = BLK_UNKNOWN; /* app needs to make a timeout call */
148     (*file)->timeout = -1;
149     (*file)->ungetchar = -1; /* no char avail */
150     (*file)->filedes = *dafile;
151     if (!register_cleanup) {
152         (*file)->flags = APR_FILE_NOCLEANUP;
153     }
154     (*file)->buffered = 0;
155 #if APR_HAS_THREADS
156     (*file)->thlock = NULL;
157 #endif
158     if (register_cleanup) {
159         apr_pool_cleanup_register((*file)->pool, (void *)(*file),
160                                   apr_unix_file_cleanup,
161                                   apr_pool_cleanup_null);
162     }
163     return APR_SUCCESS;
164 }
165
166 APR_DECLARE(apr_status_t) apr_os_pipe_put(apr_file_t **file,
167                                           apr_os_file_t *thefile,
168                                           apr_pool_t *pool)
169 {
170     return apr_os_pipe_put_ex(file, thefile, 0, pool);
171 }
172
173 APR_DECLARE(apr_status_t) apr_file_pipe_create(apr_file_t **in, apr_file_t **out, apr_pool_t *pool)
174 {
175     int filedes[2];
176
177     if (pipe(filedes) == -1) {
178         return errno;
179     }
180     
181     (*in) = (apr_file_t *)apr_pcalloc(pool, sizeof(apr_file_t));
182     (*in)->pool = pool;
183     (*in)->filedes = filedes[0];
184     (*in)->is_pipe = 1;
185     (*in)->fname = NULL;
186     (*in)->buffered = 0;
187     (*in)->blocking = BLK_ON;
188     (*in)->timeout = -1;
189     (*in)->ungetchar = -1;
190     (*in)->flags = APR_INHERIT;
191 #if APR_HAS_THREADS
192     (*in)->thlock = NULL;
193 #endif
194
195     (*out) = (apr_file_t *)apr_pcalloc(pool, sizeof(apr_file_t));
196     (*out)->pool = pool;
197     (*out)->filedes = filedes[1];
198     (*out)->is_pipe = 1;
199     (*out)->fname = NULL;
200     (*out)->buffered = 0;
201     (*out)->blocking = BLK_ON;
202     (*out)->flags = APR_INHERIT;
203     (*out)->timeout = -1;
204 #if APR_HAS_THREADS
205     (*out)->thlock = NULL;
206 #endif
207
208     apr_pool_cleanup_register((*in)->pool, (void *)(*in), apr_unix_file_cleanup,
209                          apr_pool_cleanup_null);
210     apr_pool_cleanup_register((*out)->pool, (void *)(*out), apr_unix_file_cleanup,
211                          apr_pool_cleanup_null);
212     return APR_SUCCESS;
213 }
214
215 APR_DECLARE(apr_status_t) apr_file_namedpipe_create(const char *filename, 
216                                                     apr_fileperms_t perm, apr_pool_t *pool)
217 {
218     mode_t mode = apr_unix_perms2mode(perm);
219
220     if (mkfifo(filename, mode) == -1) {
221         return errno;
222     }
223     return APR_SUCCESS;
224
225
226     
227