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 #define INCL_DOS
18 #define INCL_DOSERRORS
19 
20 #include "apr_arch_file_io.h"
21 #include "apr_file_io.h"
22 #include "apr_lib.h"
23 #include "apr_strings.h"
24 
25 #include <malloc.h>
26 
27 APR_DECLARE(apr_status_t) apr_file_read(apr_file_t *thefile, void *buf, apr_size_t *nbytes)
28 {
29  ULONG rc = 0;
30  ULONG bytesread;
31 
32  if (!thefile->isopen) {
33  *nbytes = 0;
34  return APR_EBADF;
35  }
36 
37  if (thefile->buffered) {
38  char *pos = (char *)buf;
39  ULONG blocksize;
40  ULONG size = *nbytes;
41 
42  apr_thread_mutex_lock(thefile->mutex);
43 
44  if (thefile->direction == 1) {
45  int rv = apr_file_flush(thefile);
46 
47  if (rv != APR_SUCCESS) {
48  apr_thread_mutex_unlock(thefile->mutex);
49  return rv;
50  }
51 
52  thefile->bufpos = 0;
53  thefile->direction = 0;
54  thefile->dataRead = 0;
55  }
56 
57  while (rc == 0 && size > 0) {
58  if (thefile->bufpos >= thefile->dataRead) {
59  ULONG bytesread;
60  rc = DosRead(thefile->filedes, thefile->buffer,
61  thefile->bufsize, &bytesread);
62 
63  if (bytesread == 0) {
64  if (rc == 0)
65  thefile->eof_hit = TRUE;
66  break;
67  }
68 
69  thefile->dataRead = bytesread;
71  thefile->bufpos = 0;
72  }
73 
75  memcpy(pos, thefile->buffer + thefile->bufpos, blocksize);
76  thefile->bufpos += blocksize;
77  pos += blocksize;
78  size -= blocksize;
79  }
80 
81  *nbytes = rc == 0 ? pos - (char *)buf : 0;
82  apr_thread_mutex_unlock(thefile->mutex);
83 
84  if (*nbytes == 0 && rc == 0 && thefile->eof_hit) {
85  return APR_EOF;
86  }
87 
88  return APR_FROM_OS_ERROR(rc);
89  } else {
90  if (thefile->pipe)
91  DosResetEventSem(thefile->pipeSem, &rc);
92 
93  rc = DosRead(thefile->filedes, buf, *nbytes, &bytesread);
94 
95  if (rc == ERROR_NO_DATA && thefile->timeout != 0) {
96  int rcwait = DosWaitEventSem(thefile->pipeSem, thefile->timeout >= 0 ? thefile->timeout / 1000 : SEM_INDEFINITE_WAIT);
97 
98  if (rcwait == 0) {
99  rc = DosRead(thefile->filedes, buf, *nbytes, &bytesread);
100  }
101  else if (rcwait == ERROR_TIMEOUT) {
102  *nbytes = 0;
103  return APR_TIMEUP;
104  }
105  }
106 
107  if (rc) {
108  *nbytes = 0;
109  return APR_FROM_OS_ERROR(rc);
110  }
111 
112  *nbytes = bytesread;
113 
114  if (bytesread == 0) {
115  thefile->eof_hit = TRUE;
116  return APR_EOF;
117  }
118 
119  return APR_SUCCESS;
120  }
121 }
122 
123 
124 
125 APR_DECLARE(apr_status_t) apr_file_write(apr_file_t *thefile, const void *buf, apr_size_t *nbytes)
126 {
127  ULONG rc = 0;
128  ULONG byteswritten;
129 
130  if (!thefile->isopen) {
131  *nbytes = 0;
132  return APR_EBADF;
133  }
134 
135  if (thefile->buffered) {
136  char *pos = (char *)buf;
137  int blocksize;
138  int size = *nbytes;
139 
140  apr_thread_mutex_lock(thefile->mutex);
141 
142  if ( thefile->direction == 0 ) {
143  /* Position file pointer for writing at the offset we are logically reading from */
145  if (offset != thefile->filePtr)
146  DosSetFilePtr(thefile->filedes, offset, FILE_BEGIN, &thefile->filePtr );
147  thefile->bufpos = thefile->dataRead = 0;
148  thefile->direction = 1;
149  }
150 
151  while (rc == 0 && size > 0) {
152  if (thefile->bufpos == thefile->bufsize) /* write buffer is full */
153  /* XXX bug; - rc is double-transformed os->apr below */
154  rc = apr_file_flush(thefile);
155 
156  blocksize = size > thefile->bufsize - thefile->bufpos ? thefile->bufsize - thefile->bufpos : size;
157  memcpy(thefile->buffer + thefile->bufpos, pos, blocksize);
158  thefile->bufpos += blocksize;
159  pos += blocksize;
160  size -= blocksize;
161  }
162 
163  apr_thread_mutex_unlock(thefile->mutex);
164  return APR_FROM_OS_ERROR(rc);
165  } else {
166  if (thefile->flags & APR_FOPEN_APPEND) {
167  FILELOCK all = { 0, 0x7fffffff };
168  ULONG newpos;
169  rc = DosSetFileLocks(thefile->filedes, NULL, &all, -1, 0);
170 
171  if (rc == 0) {
172  rc = DosSetFilePtr(thefile->filedes, 0, FILE_END, &newpos);
173 
174  if (rc == 0) {
175  rc = DosWrite(thefile->filedes, buf, *nbytes, &byteswritten);
176  }
177 
178  DosSetFileLocks(thefile->filedes, &all, NULL, -1, 0);
179  }
180  } else {
181  rc = DosWrite(thefile->filedes, buf, *nbytes, &byteswritten);
182  }
183 
184  if (rc) {
185  *nbytes = 0;
186  return APR_FROM_OS_ERROR(rc);
187  }
188 
189  *nbytes = byteswritten;
190  return APR_SUCCESS;
191  }
192 }
193 
194 
195 
196 #ifdef HAVE_WRITEV
197 
198 APR_DECLARE(apr_status_t) apr_file_writev(apr_file_t *thefile, const struct iovec *vec, apr_size_t nvec, apr_size_t *nbytes)
199 {
200  int bytes;
201 
202  if (thefile->buffered) {
203  apr_status_t rv = apr_file_flush(thefile);
204  if (rv != APR_SUCCESS) {
205  return rv;
206  }
207  }
208 
209  if ((bytes = writev(thefile->filedes, vec, nvec)) < 0) {
210  *nbytes = 0;
211  return errno;
212  }
213  else {
214  *nbytes = bytes;
215  return APR_SUCCESS;
216  }
217 }
218 #endif
219 
220 
221 
222 APR_DECLARE(apr_status_t) apr_file_putc(char ch, apr_file_t *thefile)
223 {
224  ULONG rc;
225  ULONG byteswritten;
226 
227  if (!thefile->isopen) {
228  return APR_EBADF;
229  }
230 
231  rc = DosWrite(thefile->filedes, &ch, 1, &byteswritten);
232 
233  if (rc) {
234  return APR_FROM_OS_ERROR(rc);
235  }
236 
237  return APR_SUCCESS;
238 }
239 
240 
241 
242 APR_DECLARE(apr_status_t) apr_file_ungetc(char ch, apr_file_t *thefile)
243 {
244  apr_off_t offset = -1;
245  return apr_file_seek(thefile, APR_CUR, &offset);
246 }
247 
248 
249 APR_DECLARE(apr_status_t) apr_file_getc(char *ch, apr_file_t *thefile)
250 {
251  ULONG rc;
252  apr_size_t bytesread;
253 
254  if (!thefile->isopen) {
255  return APR_EBADF;
256  }
257 
258  bytesread = 1;
259  rc = apr_file_read(thefile, ch, &bytesread);
260 
261  if (rc) {
262  return rc;
263  }
264 
265  if (bytesread == 0) {
266  thefile->eof_hit = TRUE;
267  return APR_EOF;
268  }
269 
270  return APR_SUCCESS;
271 }
272 
273 
274 
275 APR_DECLARE(apr_status_t) apr_file_puts(const char *str, apr_file_t *thefile)
276 {
277  apr_size_t len;
278 
279  len = strlen(str);
280  return apr_file_write(thefile, str, &len);
281 }
282 
283 
284 APR_DECLARE(apr_status_t) apr_file_flush(apr_file_t *thefile)
285 {
286  if (thefile->buffered) {
287  ULONG written = 0;
288  int rc = 0;
289 
290  if (thefile->direction == 1 && thefile->bufpos) {
291  rc = DosWrite(thefile->filedes, thefile->buffer, thefile->bufpos, &written);
292  thefile->filePtr += written;
293 
294  if (rc == 0)
295  thefile->bufpos = 0;
296  }
297 
298  return APR_FROM_OS_ERROR(rc);
299  } else {
300  /* There isn't anything to do if we aren't buffering the output
301  * so just return success.
302  */
303  return APR_SUCCESS;
304  }
305 }
306 
308 {
309  return APR_ENOTIMPL;
310 }
311 
312 APR_DECLARE(apr_status_t) apr_file_datasync(apr_file_t *thefile)
313 {
314  return APR_ENOTIMPL;
315 }
316 
317 APR_DECLARE(apr_status_t) apr_file_gets(char *str, int len, apr_file_t *thefile)
318 {
319  apr_size_t readlen;
321  int i;
322 
323  for (i = 0; i < len-1; i++) {
324  readlen = 1;
325  rv = apr_file_read(thefile, str+i, &readlen);
326 
327  if (rv != APR_SUCCESS) {
328  break;
329  }
330 
331  if (readlen != 1) {
332  rv = APR_EOF;
333  break;
334  }
335 
336  if (str[i] == '\n') {
337  i++;
338  break;
339  }
340  }
341  str[i] = 0;
342  if (i > 0) {
343  /* we stored chars; don't report EOF or any other errors;
344  * the app will find out about that on the next call
345  */
346  return APR_SUCCESS;
347  }
348  return rv;
349 }
350 
351 
352 
353 APR_DECLARE_NONSTD(int) apr_file_printf(apr_file_t *fptr,
354  const char *format, ...)
355 {
356  int cc;
357  va_list ap;
358  char *buf;
359  int len;
360 
361  buf = malloc(HUGE_STRING_LEN);
362  if (buf == NULL) {
363  return 0;
364  }
365  va_start(ap, format);
366  len = apr_vsnprintf(buf, HUGE_STRING_LEN, format, ap);
367  cc = apr_file_puts(buf, fptr);
368  va_end(ap);
369  free(buf);
370  return (cc == APR_SUCCESS) ? len : -1;
371 }
372 
373 
374 
376 {
377  int rc;
378 
379  if (!fd->pipe)
380  return APR_SUCCESS; /* Not a pipe, assume no waiting */
381 
382  rc = DosWaitEventSem(fd->pipeSem, SEM_IMMEDIATE_RETURN);
383 
384  if (rc == ERROR_TIMEOUT)
385  return APR_TIMEUP;
386 
387  return APR_FROM_OS_ERROR(rc);
388 }
apr_file_t::pipeSem
HEV pipeSem
Definition: apr_arch_file_io.h:47
apr_file_t::buffer
char * buffer
Definition: apr_arch_file_io.h:113
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_ENOTIMPL
#define APR_ENOTIMPL
Definition: apr_errno.h:476
apr_strings.h
APR Strings library.
nvec
const struct iovec apr_size_t nvec
Definition: apr_file_io.h:519
apr_file_t::buffered
int buffered
Definition: apr_arch_file_io.h:105
apr_file_t::isopen
int isopen
Definition: apr_arch_file_io.h:41
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_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
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
format
const char * format
Definition: apr_file_io.h:873
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
APR_FOPEN_APPEND
#define APR_FOPEN_APPEND
Definition: apr_file_io.h:57
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_EBADF
#define APR_EBADF
Definition: apr_errno.h:704
TRUE
#define TRUE
Definition: apr_snprintf.c:53
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_DECLARE_NONSTD
APR_DECLARE_NONSTD(int)
Definition: readwrite.c:353
APR_CUR
#define APR_CUR
Definition: apr_file_io.h:167
apr_status_t
int apr_status_t
Definition: apr_errno.h:44
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
HUGE_STRING_LEN
#define HUGE_STRING_LEN
Definition: apr_lib.h:52
apr_file_t::filedes
int filedes
Definition: apr_arch_file_io.h:99
apr_file_t::direction
int direction
Definition: apr_arch_file_io.h:117
apr_file_t::mutex
apr_thread_mutex_t * mutex
Definition: apr_arch_file_io.h:57
writev
#define writev
Definition: apr_arch_os2calls.h:57
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
apr_file_check_read
apr_status_t apr_file_check_read(apr_file_t *fd)
Definition: readwrite.c:375
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