apr  1.7.0
About: APR (Apache Portable Runtime) project offers software libraries that provide a predictable and consistent interface to underlying platform-specific implementations (APR core library).
  Fossies Dox: apr-1.7.0.tar.bz2  ("inofficial" and yet experimental doxygen-generated source code documentation)  

readwrite.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_file_io.h"
19 #include "apr_general.h"
20 #include "apr_strings.h"
21 #include "apr_lib.h"
22 #include "apr_errno.h"
23 #include <malloc.h>
24 #include "apr_arch_atime.h"
25 #include "apr_arch_misc.h"
26 
27 /*
28  * read_with_timeout()
29  * Uses async i/o to emulate unix non-blocking i/o with timeouts.
30  */
31 static apr_status_t read_with_timeout(apr_file_t *file, void *buf, apr_size_t len_in, apr_size_t *nbytes)
32 {
33  apr_status_t rv;
34  DWORD res;
35  DWORD len = (DWORD)len_in;
36  DWORD bytesread = 0;
37 
38  /* Handle the zero timeout non-blocking case */
39  if (file->timeout == 0) {
40  /* Peek at the pipe. If there is no data available, return APR_EAGAIN.
41  * If data is available, go ahead and read it.
42  */
43  if (file->pipe) {
44  DWORD bytes;
45  if (!PeekNamedPipe(file->filehand, NULL, 0, NULL, &bytes, NULL)) {
46  rv = apr_get_os_error();
47  if (rv == APR_FROM_OS_ERROR(ERROR_BROKEN_PIPE)) {
48  rv = APR_EOF;
49  }
50  *nbytes = 0;
51  return rv;
52  }
53  else {
54  if (bytes == 0) {
55  *nbytes = 0;
56  return APR_EAGAIN;
57  }
58  if (len > bytes) {
59  len = bytes;
60  }
61  }
62  }
63  else {
64  /* ToDo: Handle zero timeout non-blocking file i/o
65  * This is not needed until an APR application needs to
66  * timeout file i/o (which means setting file i/o non-blocking)
67  */
68  }
69  }
70 
71  if (file->pOverlapped && !file->pipe) {
72  file->pOverlapped->Offset = (DWORD)file->filePtr;
73  file->pOverlapped->OffsetHigh = (DWORD)(file->filePtr >> 32);
74  }
75 
76  if (ReadFile(file->filehand, buf, len,
77  &bytesread, file->pOverlapped)) {
78  rv = APR_SUCCESS;
79  }
80  else {
81  rv = apr_get_os_error();
82  if (rv == APR_FROM_OS_ERROR(ERROR_IO_PENDING)) {
83  /* Wait for the pending i/o, timeout converted from us to ms
84  * Note that we loop if someone gives up the event, since
85  * folks suggest that WAIT_ABANDONED isn't actually a result
86  * but an alert that ownership of the event has passed from
87  * one owner to a new proc/thread.
88  */
89  do {
90  res = WaitForSingleObject(file->pOverlapped->hEvent,
91  (file->timeout > 0)
92  ? (DWORD)(file->timeout/1000)
93  : ((file->timeout == -1)
94  ? INFINITE : 0));
95  } while (res == WAIT_ABANDONED);
96 
97  /* There is one case that represents entirely
98  * successful operations, otherwise we will cancel
99  * the operation in progress.
100  */
101  if (res != WAIT_OBJECT_0) {
103  }
104 
105  /* Ignore any failures above. Attempt to complete
106  * the overlapped operation and use only _its_ result.
107  * For example, CancelIo or WaitForSingleObject can
108  * fail if the handle is closed, yet the read may have
109  * completed before we attempted to CancelIo...
110  */
111  if (GetOverlappedResult(file->filehand, file->pOverlapped,
112  &bytesread, TRUE)) {
113  rv = APR_SUCCESS;
114  }
115  else {
116  rv = apr_get_os_error();
117  if (((rv == APR_FROM_OS_ERROR(ERROR_IO_INCOMPLETE))
118  || (rv == APR_FROM_OS_ERROR(ERROR_OPERATION_ABORTED)))
119  && (res == WAIT_TIMEOUT))
120  rv = APR_TIMEUP;
121  }
122  }
123  if (rv == APR_FROM_OS_ERROR(ERROR_BROKEN_PIPE)) {
124  /* Assume ERROR_BROKEN_PIPE signals an EOF reading from a pipe */
125  rv = APR_EOF;
126  } else if (rv == APR_FROM_OS_ERROR(ERROR_HANDLE_EOF)) {
127  /* Did we hit EOF reading from the handle? */
128  rv = APR_EOF;
129  }
130  }
131 
132  /* OK and 0 bytes read ==> end of file */
133  if (rv == APR_SUCCESS && bytesread == 0)
134  rv = APR_EOF;
135 
136  if (rv == APR_SUCCESS && file->pOverlapped && !file->pipe) {
137  file->filePtr += bytesread;
138  }
139  *nbytes = bytesread;
140  return rv;
141 }
142 
143 APR_DECLARE(apr_status_t) apr_file_read(apr_file_t *thefile, void *buf, apr_size_t *len)
144 {
145  apr_status_t rv;
146  DWORD bytes_read = 0;
147 
148  if (*len <= 0) {
149  *len = 0;
150  return APR_SUCCESS;
151  }
152 
153  /* If the file is open for xthread support, allocate and
154  * initialize the overlapped and io completion event (hEvent).
155  * Threads should NOT share an apr_file_t or its hEvent.
156  */
158  thefile->pOverlapped = (OVERLAPPED*) apr_pcalloc(thefile->pool,
159  sizeof(OVERLAPPED));
160  thefile->pOverlapped->hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
161  if (!thefile->pOverlapped->hEvent) {
162  rv = apr_get_os_error();
163  return rv;
164  }
165  }
166 
167  /* Handle the ungetchar if there is one */
168  if (thefile->ungetchar != -1) {
169  bytes_read = 1;
170  *(char *)buf = (char)thefile->ungetchar;
171  buf = (char *)buf + 1;
172  (*len)--;
173  thefile->ungetchar = -1;
174  if (*len == 0) {
175  *len = bytes_read;
176  return APR_SUCCESS;
177  }
178  }
179  if (thefile->buffered) {
180  char *pos = (char *)buf;
181  apr_size_t blocksize;
182  apr_size_t size = *len;
183 
185  apr_thread_mutex_lock(thefile->mutex);
186  }
187 
188  if (thefile->direction == 1) {
189  rv = apr_file_flush(thefile);
190  if (rv != APR_SUCCESS) {
192  apr_thread_mutex_unlock(thefile->mutex);
193  }
194  return rv;
195  }
196  thefile->bufpos = 0;
197  thefile->direction = 0;
198  thefile->dataRead = 0;
199  }
200 
201  rv = 0;
202  while (rv == 0 && size > 0) {
203  if (thefile->bufpos >= thefile->dataRead) {
204  apr_size_t read;
206  thefile->bufsize, &read);
207  if (read == 0) {
208  if (rv == APR_EOF)
209  thefile->eof_hit = TRUE;
210  break;
211  }
212  else {
213  thefile->dataRead = read;
215  thefile->bufpos = 0;
216  }
217  }
218 
219  blocksize = size > thefile->dataRead - thefile->bufpos ? thefile->dataRead - thefile->bufpos : size;
220  memcpy(pos, thefile->buffer + thefile->bufpos, blocksize);
221  thefile->bufpos += blocksize;
222  pos += blocksize;
223  size -= blocksize;
224  }
225 
226  *len = pos - (char *)buf;
227  if (*len) {
228  rv = APR_SUCCESS;
229  }
230 
232  apr_thread_mutex_unlock(thefile->mutex);
233  }
234  } else {
235  /* Unbuffered i/o */
236  apr_size_t nbytes;
238  if (rv == APR_EOF)
239  thefile->eof_hit = TRUE;
240  *len = nbytes;
241  }
242 
243  return rv;
244 }
245 
246 APR_DECLARE(apr_status_t) apr_file_write(apr_file_t *thefile, const void *buf, apr_size_t *nbytes)
247 {
248  apr_status_t rv;
249  DWORD bwrote;
250 
251  /* If the file is open for xthread support, allocate and
252  * initialize the overlapped and io completion event (hEvent).
253  * Threads should NOT share an apr_file_t or its hEvent.
254  */
256  thefile->pOverlapped = (OVERLAPPED*) apr_pcalloc(thefile->pool,
257  sizeof(OVERLAPPED));
258  thefile->pOverlapped->hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
259  if (!thefile->pOverlapped->hEvent) {
260  rv = apr_get_os_error();
261  return rv;
262  }
263  }
264 
265  if (thefile->buffered) {
266  char *pos = (char *)buf;
267  apr_size_t blocksize;
268  apr_size_t size = *nbytes;
269 
271  apr_thread_mutex_lock(thefile->mutex);
272  }
273 
274  if (thefile->direction == 0) {
275  /* Position file pointer for writing at the offset we are logically reading from */
276  apr_off_t offset = thefile->filePtr - thefile->dataRead + thefile->bufpos;
277  DWORD offlo = (DWORD)offset;
278  LONG offhi = (LONG)(offset >> 32);
279  if (offset != thefile->filePtr)
280  SetFilePointer(thefile->filehand, offlo, &offhi, FILE_BEGIN);
281  thefile->bufpos = thefile->dataRead = 0;
282  thefile->direction = 1;
283  }
284 
285  rv = 0;
286  while (rv == 0 && size > 0) {
287  if (thefile->bufpos == thefile->bufsize) /* write buffer is full */
288  rv = apr_file_flush(thefile);
289 
290  blocksize = size > thefile->bufsize - thefile->bufpos ?
292  memcpy(thefile->buffer + thefile->bufpos, pos, blocksize);
293  thefile->bufpos += blocksize;
294  pos += blocksize;
295  size -= blocksize;
296  }
297 
299  apr_thread_mutex_unlock(thefile->mutex);
300  }
301  return rv;
302  } else {
303  if (!thefile->pipe) {
304  apr_off_t offset = 0;
305  apr_status_t rc;
306  if (thefile->append) {
307  /* apr_file_lock will mutex the file across processes.
308  * The call to apr_thread_mutex_lock is added to avoid
309  * a race condition between LockFile and WriteFile
310  * that occasionally leads to deadlocked threads.
311  */
312  apr_thread_mutex_lock(thefile->mutex);
314  if (rc != APR_SUCCESS) {
315  apr_thread_mutex_unlock(thefile->mutex);
316  return rc;
317  }
318  rc = apr_file_seek(thefile, APR_END, &offset);
319  if (rc != APR_SUCCESS) {
320  apr_thread_mutex_unlock(thefile->mutex);
321  return rc;
322  }
323  }
324  if (thefile->pOverlapped) {
325  thefile->pOverlapped->Offset = (DWORD)thefile->filePtr;
326  thefile->pOverlapped->OffsetHigh = (DWORD)(thefile->filePtr >> 32);
327  }
328  rv = WriteFile(thefile->filehand, buf, (DWORD)*nbytes, &bwrote,
330  if (thefile->append) {
332  apr_thread_mutex_unlock(thefile->mutex);
333  }
334  }
335  else {
336  rv = WriteFile(thefile->filehand, buf, (DWORD)*nbytes, &bwrote,
338  }
339  if (rv) {
340  *nbytes = bwrote;
341  rv = APR_SUCCESS;
342  }
343  else {
344  (*nbytes) = 0;
345  rv = apr_get_os_error();
346 
347  /* XXX: This must be corrected, per the apr_file_read logic!!! */
348  if (rv == APR_FROM_OS_ERROR(ERROR_IO_PENDING)) {
349 
350  DWORD timeout_ms;
351 
352  if (thefile->timeout == 0) {
353  timeout_ms = 0;
354  }
355  else if (thefile->timeout < 0) {
356  timeout_ms = INFINITE;
357  }
358  else {
359  timeout_ms = (DWORD)(thefile->timeout / 1000);
360  }
361 
362  rv = WaitForSingleObject(thefile->pOverlapped->hEvent, timeout_ms);
363  switch (rv) {
364  case WAIT_OBJECT_0:
365  GetOverlappedResult(thefile->filehand, thefile->pOverlapped,
366  &bwrote, TRUE);
367  *nbytes = bwrote;
368  rv = APR_SUCCESS;
369  break;
370  case WAIT_TIMEOUT:
371  rv = (timeout_ms == 0) ? APR_EAGAIN : APR_TIMEUP;
372  break;
373  case WAIT_FAILED:
374  rv = apr_get_os_error();
375  break;
376  default:
377  break;
378  }
379  if (rv != APR_SUCCESS) {
380  if (apr_os_level >= APR_WIN_98)
382  }
383  }
384  }
385  if (rv == APR_SUCCESS && thefile->pOverlapped && !thefile->pipe) {
386  thefile->filePtr += *nbytes;
387  }
388  }
389  return rv;
390 }
391 /* ToDo: Write for it anyway and test the oslevel!
392  * Too bad WriteFileGather() is not supported on 95&98 (or NT prior to SP2)
393  */
394 APR_DECLARE(apr_status_t) apr_file_writev(apr_file_t *thefile,
395  const struct iovec *vec,
396  apr_size_t nvec,
397  apr_size_t *nbytes)
398 {
400  apr_size_t i;
401  apr_size_t bwrote = 0;
402  char *buf;
403 
404  *nbytes = 0;
405  for (i = 0; i < nvec; i++) {
406  buf = vec[i].iov_base;
407  bwrote = vec[i].iov_len;
408  rv = apr_file_write(thefile, buf, &bwrote);
409  *nbytes += bwrote;
410  if (rv != APR_SUCCESS) {
411  break;
412  }
413  }
414  return rv;
415 }
416 
417 APR_DECLARE(apr_status_t) apr_file_putc(char ch, apr_file_t *thefile)
418 {
419  apr_size_t len = 1;
420 
421  return apr_file_write(thefile, &ch, &len);
422 }
423 
424 APR_DECLARE(apr_status_t) apr_file_ungetc(char ch, apr_file_t *thefile)
425 {
426  thefile->ungetchar = (unsigned char) ch;
427  return APR_SUCCESS;
428 }
429 
430 APR_DECLARE(apr_status_t) apr_file_getc(char *ch, apr_file_t *thefile)
431 {
432  apr_status_t rc;
433  apr_size_t bread;
434 
435  bread = 1;
436  rc = apr_file_read(thefile, ch, &bread);
437 
438  if (rc) {
439  return rc;
440  }
441 
442  if (bread == 0) {
443  thefile->eof_hit = TRUE;
444  return APR_EOF;
445  }
446  return APR_SUCCESS;
447 }
448 
449 APR_DECLARE(apr_status_t) apr_file_puts(const char *str, apr_file_t *thefile)
450 {
451  apr_size_t len = strlen(str);
452 
453  return apr_file_write(thefile, str, &len);
454 }
455 
456 APR_DECLARE(apr_status_t) apr_file_gets(char *str, int len, apr_file_t *thefile)
457 {
458  apr_size_t readlen;
460  int i;
461 
462  for (i = 0; i < len-1; i++) {
463  readlen = 1;
464  rv = apr_file_read(thefile, str+i, &readlen);
465 
466  if (rv != APR_SUCCESS && rv != APR_EOF)
467  return rv;
468 
469  if (readlen == 0) {
470  /* If we have bytes, defer APR_EOF to the next call */
471  if (i > 0)
472  rv = APR_SUCCESS;
473  break;
474  }
475 
476  if (str[i] == '\n') {
477  i++; /* don't clobber this char below */
478  break;
479  }
480  }
481  str[i] = 0;
482  return rv;
483 }
484 
485 APR_DECLARE(apr_status_t) apr_file_flush(apr_file_t *thefile)
486 {
487  if (thefile->buffered) {
488  DWORD numbytes, written = 0;
489  apr_status_t rc = 0;
490  char *buffer;
491  apr_size_t bytesleft;
492 
493  if (thefile->direction == 1 && thefile->bufpos) {
494  buffer = thefile->buffer;
495  bytesleft = thefile->bufpos;
496 
497  do {
498  if (bytesleft > APR_DWORD_MAX) {
499  numbytes = APR_DWORD_MAX;
500  }
501  else {
502  numbytes = (DWORD)bytesleft;
503  }
504 
505  if (!WriteFile(thefile->filehand, buffer, numbytes, &written, NULL)) {
506  rc = apr_get_os_error();
507  thefile->filePtr += written;
508  break;
509  }
510 
511  thefile->filePtr += written;
512  bytesleft -= written;
513  buffer += written;
514 
515  } while (bytesleft > 0);
516 
517  if (rc == 0)
518  thefile->bufpos = 0;
519  }
520 
521  return rc;
522  }
523 
524  /* There isn't anything to do if we aren't buffering the output
525  * so just return success.
526  */
527  return APR_SUCCESS;
528 }
529 
530 APR_DECLARE(apr_status_t) apr_file_sync(apr_file_t *thefile){
531  apr_status_t rv;
532 
533  rv = apr_file_flush(thefile);
534  if (rv != APR_SUCCESS) {
535  return rv;
536  }
537 
538  if (!FlushFileBuffers(thefile->filehand)) {
539  rv = apr_get_os_error();
540  }
541 
542  return rv;
543 }
544 
545 APR_DECLARE(apr_status_t) apr_file_datasync(apr_file_t *thefile){
546  return apr_file_sync(thefile);
547 }
548 
549 struct apr_file_printf_data {
551  apr_file_t *fptr;
552  char *buf;
553 };
554 
556 {
557  struct apr_file_printf_data *data = (struct apr_file_printf_data *)buff;
558 
559  if (apr_file_write_full(data->fptr, data->buf,
560  data->vbuff.curpos - data->buf, NULL)) {
561  return -1;
562  }
563 
564  data->vbuff.curpos = data->buf;
565  return 0;
566 }
567 
568 APR_DECLARE_NONSTD(int) apr_file_printf(apr_file_t *fptr,
569  const char *format, ...)
570 {
571  struct apr_file_printf_data data;
572  va_list ap;
573  int count;
574 
575  data.buf = malloc(HUGE_STRING_LEN);
576  if (data.buf == NULL) {
577  return 0;
578  }
579  data.vbuff.curpos = data.buf;
580  data.vbuff.endpos = data.buf + HUGE_STRING_LEN;
581  data.fptr = fptr;
582  va_start(ap, format);
583  count = apr_vformatter(file_printf_flush,
585  /* apr_vformatter does not call flush for the last bits */
586  if (count >= 0) file_printf_flush((apr_vformatter_buff_t *)&data);
587 
588  va_end(ap);
589 
590  free(data.buf);
591  return count;
592 }
apr_pcalloc
#define apr_pcalloc(p, size)
Definition: apr_pools.h:465
apr_file_t::buffer
char * buffer
Definition: apr_arch_file_io.h:113
apr_file_lock
apr_status_t apr_file_lock(apr_file_t *thefile, int type)
Definition: flock.c:21
apr_errno.h
APR Error Codes.
data
void * data
Definition: apr_file_io.h:861
apr_file_t::bufpos
apr_size_t bufpos
Definition: apr_arch_file_io.h:114
str
char ** str
Definition: apr_cstr.h:125
apr_file_t::eof_hit
int eof_hit
Definition: apr_arch_file_io.h:102
apr_os_level
APR_DECLARE_DATA apr_oslevel_e apr_os_level
Definition: misc.c:24
DWORD
typedef DWORD(WINAPI *apr_winapi_fpt_GetCompressedFileSizeA)(IN LPCSTR lpFileName
APR_END
#define APR_END
Definition: apr_file_io.h:169
apr_strings.h
APR Strings library.
apr_file_printf_data::buf
char * buf
Definition: readwrite.c:486
nvec
const struct iovec apr_size_t nvec
Definition: apr_file_io.h:519
LONG
typedef LONG(WINAPI *apr_winapi_fpt_NtQueryTimerResolution)(ULONG *pMaxRes
apr_file_t::buffered
int buffered
Definition: apr_arch_file_io.h:105
apr_arch_atime.h
apr_file_unlock
apr_status_t apr_file_unlock(apr_file_t *thefile)
Definition: flock.c:33
file_printf_flush
static int file_printf_flush(apr_vformatter_buff_t *buff)
Definition: readwrite.c:555
offset
apr_seek_where_t apr_off_t * offset
Definition: apr_file_io.h:717
APR_DECLARE
APR_DECLARE(apr_status_t)
Definition: readwrite.c:27
apr_vformatter_buff_t
Definition: apr_lib.h:64
apr_file_t::flags
apr_int32_t flags
Definition: apr_arch_file_io.h:101
ap
apr_vformatter_buff_t const char va_list ap
Definition: apr_lib.h:175
thefile
apr_file_t * thefile
Definition: apr_file_io.h:594
apr_file_t::pool
apr_pool_t * pool
Definition: apr_arch_file_io.h:98
len
const char apr_ssize_t int apr_size_t * len
Definition: apr_encode.h:162
apr_file_t::bufsize
apr_size_t bufsize
Definition: apr_arch_file_io.h:115
buffer
char * buffer
Definition: apr_file_io.h:696
format
const char * format
Definition: apr_file_io.h:873
read_with_timeout
static apr_status_t read_with_timeout(apr_file_t *file, void *buf, apr_size_t len_in, apr_size_t *nbytes)
Definition: readwrite.c:31
apr_file_t::dataRead
apr_off_t dataRead
Definition: apr_arch_file_io.h:116
buf
char * buf
Definition: apr_errno.h:52
APR_TIMEUP
#define APR_TIMEUP
Definition: apr_errno.h:450
size
apr_size_t size
Definition: apr_allocator.h:115
vec
const struct iovec * vec
Definition: apr_file_io.h:519
apr_lib.h
APR general purpose library routines.
APR_WIN_98
Definition: apr_arch_misc.h:86
CancelIo
#define CancelIo
Definition: apr_arch_misc.h:260
APR_EAGAIN
#define APR_EAGAIN
Definition: apr_errno.h:730
apr_file_t::append
int append
Definition: apr_arch_file_io.h:177
apr_file_printf_data::vbuff
apr_vformatter_buff_t vbuff
Definition: readwrite.c:484
TRUE
#define TRUE
Definition: apr_snprintf.c:53
apr_get_os_error
#define apr_get_os_error()
Definition: apr_errno.h:1217
apr_file_t
Definition: apr_arch_file_io.h:97
bytes
const void apr_size_t bytes
Definition: apr_random.h:90
apr_file_io.h
APR File I/O Handling.
apr_general.h
APR Miscellaneous library routines.
APR_DECLARE_NONSTD
APR_DECLARE_NONSTD(int)
Definition: readwrite.c:353
APR_FLOCK_EXCLUSIVE
#define APR_FLOCK_EXCLUSIVE
Definition: apr_file_io.h:227
apr_status_t
int apr_status_t
Definition: apr_errno.h:44
bytes_read
void apr_size_t apr_size_t * bytes_read
Definition: apr_file_io.h:542
APR_SUCCESS
#define APR_SUCCESS
Definition: apr_errno.h:225
nbytes
void apr_size_t * nbytes
Definition: apr_file_io.h:482
apr_file_t::timeout
apr_interval_time_t timeout
Definition: apr_arch_file_io.h:104
file
const char apr_file_t * file
Definition: apr_file_io.h:851
APR_FOPEN_XTHREAD
#define APR_FOPEN_XTHREAD
Definition: apr_file_io.h:71
HUGE_STRING_LEN
#define HUGE_STRING_LEN
Definition: apr_lib.h:52
apr_file_t::direction
int direction
Definition: apr_arch_file_io.h:117
apr_file_t::ungetchar
int ungetchar
Definition: apr_arch_file_io.h:107
apr_file_printf_data::fptr
apr_file_t * fptr
Definition: readwrite.c:485
apr_file_printf_data
Definition: readwrite.c:483
apr_file_t::mutex
apr_thread_mutex_t * mutex
Definition: apr_arch_file_io.h:57
apr_file_t::pOverlapped
OVERLAPPED * pOverlapped
Definition: apr_arch_file_io.h:166
apr_file_t::pipe
int pipe
Definition: apr_arch_file_io.h:46
apr_file_t::filePtr
apr_off_t filePtr
Definition: apr_arch_file_io.h:118
FALSE
#define FALSE
Definition: apr_snprintf.c:50
apr_file_t::filehand
HANDLE filehand
Definition: apr_arch_file_io.h:164
APR_EOF
#define APR_EOF
Definition: apr_errno.h:461
APR_FROM_OS_ERROR
#define APR_FROM_OS_ERROR(e)
Definition: apr_errno.h:1214
WaitForSingleObject
#define WaitForSingleObject(h, d)
Definition: apr_dbg_win32_handles.h:168