Apache HTTPD
pipe.c
Go to the documentation of this file.
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 defined(BEOS)
29#if !defined(BONE7)
30# define BEOS_BLOCKING 1
31#else
32# define BEOS_BLOCKING 0
33#endif
34#endif
35
37{
38#if !defined(BEOS) || !BEOS_BLOCKING
39 int fd_flags;
40
41 fd_flags = fcntl(thepipe->filedes, F_GETFL, 0);
42# if defined(O_NONBLOCK)
44# elif defined(O_NDELAY)
46# elif defined(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
73{
74#if !defined(BEOS) || !BEOS_BLOCKING
75 int fd_flags = fcntl(thepipe->filedes, F_GETFL, 0);
76
77# if defined(O_NONBLOCK)
79# elif defined(O_NDELAY)
81# elif defined(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
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
128{
129 if (thepipe->is_pipe == 1) {
130 *timeout = thepipe->timeout;
131 return APR_SUCCESS;
132 }
133 return APR_EINVAL;
134}
135
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_FOPEN_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),
162 }
163#ifndef WAITIO_USES_POLL
164 /* Start out with no pollset. apr_wait_for_io_or_timeout() will
165 * initialize the pollset if needed.
166 */
167 (*file)->pollset = NULL;
168#endif
169 return APR_SUCCESS;
170}
171
175{
176 return apr_os_pipe_put_ex(file, thefile, 0, pool);
177}
178
181{
182 int filedes[2];
183
184 if (pipe(filedes) == -1) {
185 return errno;
186 }
187
188 (*in) = (apr_file_t *)apr_pcalloc(pool_in, sizeof(apr_file_t));
189 (*in)->pool = pool_in;
190 (*in)->filedes = filedes[0];
191 (*in)->is_pipe = 1;
192 (*in)->fname = NULL;
193 (*in)->buffered = 0;
194 (*in)->blocking = BLK_ON;
195 (*in)->timeout = -1;
196 (*in)->ungetchar = -1;
197 (*in)->flags = APR_INHERIT;
198#if APR_HAS_THREADS
199 (*in)->thlock = NULL;
200#endif
201#ifndef WAITIO_USES_POLL
202 (*in)->pollset = NULL;
203#endif
204 (*out) = (apr_file_t *)apr_pcalloc(pool_out, sizeof(apr_file_t));
205 (*out)->pool = pool_out;
206 (*out)->filedes = filedes[1];
207 (*out)->is_pipe = 1;
208 (*out)->fname = NULL;
209 (*out)->buffered = 0;
210 (*out)->blocking = BLK_ON;
211 (*out)->flags = APR_INHERIT;
212 (*out)->timeout = -1;
213#if APR_HAS_THREADS
214 (*out)->thlock = NULL;
215#endif
216#ifndef WAITIO_USES_POLL
217 (*out)->pollset = NULL;
218#endif
219 apr_pool_cleanup_register((*in)->pool, (void *)(*in), apr_unix_file_cleanup,
221 apr_pool_cleanup_register((*out)->pool, (void *)(*out), apr_unix_file_cleanup,
223 return APR_SUCCESS;
224}
225
227{
228 switch (blocking) {
229 case APR_FULL_BLOCK:
230 break;
231 case APR_READ_BLOCK:
233 break;
234 case APR_WRITE_BLOCK:
236 break;
237 default:
240 break;
241 }
242}
243
246{
247 return file_pipe_create(in, out, pool, pool);
248}
249
251 apr_file_t **out,
254{
256
258 return status;
259 }
260
262
263 return APR_SUCCESS;
264}
265
268{
270
272 return status;
273 }
274
276
277 return APR_SUCCESS;
278}
279
282{
284
285 if (mkfifo(filename, mode) == -1) {
286 return errno;
287 }
288 return APR_SUCCESS;
289}
290
291
292
mode_t
Definition aplibtool.c:31
#define ioctl
APR Portability Routines.
APR Strings library.
#define APR_ENOTIMPL
Definition apr_errno.h:476
#define APR_EINVAL
Definition apr_errno.h:711
apr_dbd_transaction_t int mode
Definition apr_dbd.h:261
const void apr_status_t(*) apr_status_t(* APR_DECLARE)(void) apr_pool_pre_cleanup_register(apr_pool_t *p
Definition apr_pools.h:646
apr_size_t size
const char int apr_pool_t * pool
Definition apr_cstr.h:84
#define APR_SUCCESS
Definition apr_errno.h:225
int apr_status_t
Definition apr_errno.h:44
apr_int32_t apr_fileperms_t
apr_file_t * thefile
apr_file_t apr_int32_t apr_pool_t apr_pool_t * pool_out
const char apr_file_t * file
apr_file_t apr_int32_t blocking
const char apr_int32_t apr_fileperms_t perm
apr_file_t apr_int32_t apr_pool_t * pool_in
#define APR_FOPEN_NOCLEANUP
Definition apr_file_io.h:74
apr_int32_t apr_int32_t on
#define apr_pcalloc(p, size)
Definition apr_pools.h:465
int apr_os_file_t
apr_os_file_t int register_cleanup
apr_size_t const char * filename
Definition apr_shm.h:72
apr_int32_t in
#define APR_WRITE_BLOCK
#define APR_FULL_BLOCK
int int status
#define APR_READ_BLOCK
apr_int64_t apr_interval_time_t
Definition apr_time.h:55
static apr_file_t * out
Definition mod_info.c:85
return NULL
Definition mod_so.c:359
static apr_status_t pipenonblock(apr_file_t *thepipe)
Definition pipe.c:48
static apr_status_t file_pipe_create(apr_file_t **in, apr_file_t **out, apr_pool_t *pool_in, apr_pool_t *pool_out)
Definition pipe.c:136
static apr_status_t pipeblock(apr_file_t *thepipe)
Definition pipe.c:26
static void file_pipe_block(apr_file_t **in, apr_file_t **out, apr_int32_t blocking)
Definition pipe.c:178
#define APR_INHERIT
mode_t apr_unix_perms2mode(apr_fileperms_t perms)
Definition fileacc.c:35
apr_status_t apr_unix_file_cleanup(void *thefile)
Definition open.c:71
#define filedes
IN ULONG IN INT timeout