View | Details | Raw Unified | Return to bug 49085
Collapse All | Expand All

(-)file_io/unix/readwrite.c (-38 / +140 lines)
Lines 50-84 Link Here
50
        --size;
50
        --size;
51
        thefile->ungetchar = -1;
51
        thefile->ungetchar = -1;
52
    }
52
    }
53
    while (rv == 0 && size > 0) {
53
54
        if (thefile->bufpos >= thefile->dataRead) {
54
	if (size > thefile->bufsize) {
55
            int bytesread = read(thefile->filedes, thefile->buffer, 
55
        int bytesread;
56
                                 thefile->bufsize);
56
57
            if (bytesread == 0) {
57
        blocksize = thefile->dataRead - thefile->bufpos;
58
                thefile->eof_hit = TRUE;
58
        if (blocksize > 0) {
59
                rv = APR_EOF;
59
            memcpy(pos, thefile->buffer + thefile->bufpos, blocksize);
60
                break;
60
            thefile->bufpos += blocksize;
61
            }
61
            pos += blocksize;
62
            else if (bytesread == -1) {
62
            size -= blocksize;
63
                rv = errno;
64
                break;
65
            }
66
            thefile->dataRead = bytesread;
67
            thefile->filePtr += thefile->dataRead;
68
            thefile->bufpos = 0;
69
        }
63
        }
70
64
71
        blocksize = size > thefile->dataRead - thefile->bufpos ? thefile->dataRead - thefile->bufpos : size;
65
        bytesread = read(thefile->filedes, pos, size);
72
        memcpy(pos, thefile->buffer + thefile->bufpos, blocksize);
66
        if (bytesread == 0) {
73
        thefile->bufpos += blocksize;
67
            thefile->eof_hit = TRUE;
74
        pos += blocksize;
68
            rv = APR_EOF;
75
        size -= blocksize;
69
        }
70
        else if (bytesread == -1) {
71
            rv = errno;
72
            bytesread = 0;
73
        }
74
75
        thefile->filePtr += bytesread;
76
        pos += bytesread;
76
    }
77
    }
78
    else {
79
        while (rv == 0 && size > 0) {
80
            if (thefile->bufpos >= thefile->dataRead) {
81
                int bytesread = read(thefile->filedes, thefile->buffer, 
82
                                     thefile->bufsize);
83
                if (bytesread == 0) {
84
                    thefile->eof_hit = TRUE;
85
                    rv = APR_EOF;
86
                    break;
87
                }
88
                else if (bytesread == -1) {
89
                    rv = errno;
90
                    break;
91
                }
92
                thefile->dataRead = bytesread;
93
                thefile->filePtr += thefile->dataRead;
94
                thefile->bufpos = 0;
95
            }
77
96
97
            blocksize = size > thefile->dataRead - thefile->bufpos 
98
                      ? thefile->dataRead - thefile->bufpos 
99
                      : size;
100
            memcpy(pos, thefile->buffer + thefile->bufpos, blocksize);
101
            thefile->bufpos += blocksize;
102
            pos += blocksize;
103
            size -= blocksize;
104
        }
105
    }
106
78
    *nbytes = pos - (char *)buf;
107
    *nbytes = pos - (char *)buf;
79
    if (*nbytes) {
108
    if (*nbytes)
80
        rv = 0;
109
        rv = APR_SUCCESS;
81
    }
110
82
    return rv;
111
    return rv;
83
}
112
}
84
113
Lines 149-158 Link Here
149
    apr_size_t rv;
178
    apr_size_t rv;
150
179
151
    if (thefile->buffered) {
180
    if (thefile->buffered) {
152
        char *pos = (char *)buf;
181
        const char *pos = (const char *)buf;
153
        int blocksize;
182
        int blocksize;
154
        int size = *nbytes;
183
        int size = *nbytes;
155
184
185
        if (size < 16 &&
186
            !(thefile->flags & APR_XTHREAD) && 
187
            thefile->direction == 1 &&
188
            thefile->bufpos + size <= thefile->bufsize) {
189
190
            char *dest = thefile->buffer + thefile->bufpos;
191
            const char *end = (const char *)buf + size;
192
            thefile->bufpos += size;
193
194
            for (; pos != end; ++pos, ++dest)
195
                *dest = *pos;
196
197
            return APR_SUCCESS;
198
        }
199
156
        file_lock(thefile);
200
        file_lock(thefile);
157
201
158
        if ( thefile->direction == 0 ) {
202
        if ( thefile->direction == 0 ) {
Lines 167-184 Link Here
167
        }
211
        }
168
212
169
        rv = 0;
213
        rv = 0;
170
        while (rv == 0 && size > 0) {
171
            if (thefile->bufpos == thefile->bufsize)   /* write buffer is full*/
172
                rv = apr_file_flush_locked(thefile);
173
214
174
            blocksize = size > thefile->bufsize - thefile->bufpos ? 
215
        /* Large chunks shall not be buffered. They would cause at least one
175
                        thefile->bufsize - thefile->bufpos : size;
216
         * cache flush just "for themselves". So, we can pass them directly 
176
            memcpy(thefile->buffer + thefile->bufpos, pos, blocksize);                      
217
         * to the OS instead of copying them around and poking the OS for
177
            thefile->bufpos += blocksize;
218
         * every 4k of data in the buffer. */
178
            pos += blocksize;
219
        if (size > thefile->bufsize) {
179
            size -= blocksize;
220
            rv = apr_file_flush_locked(thefile);
221
            if (rv == APR_SUCCESS) {
222
                apr_ssize_t written;
223
224
                do {
225
                    written = write(thefile->filedes, buf, size);
226
                } while (written == -1 && errno == EINTR);
227
                if (written == -1)
228
                    rv = errno;
229
                else
230
                    thefile->filePtr += written;
231
            }
180
        }
232
        }
233
        else {
234
            while (rv == 0 && size > 0) {
235
                if (thefile->bufpos == thefile->bufsize)   /* write buffer is full */
236
                    rv = apr_file_flush_locked(thefile);
181
237
238
                blocksize = size > thefile->bufsize - thefile->bufpos 
239
                          ? thefile->bufsize - thefile->bufpos 
240
                          : size;
241
                memcpy(thefile->buffer + thefile->bufpos, pos, blocksize);
242
                thefile->bufpos += blocksize;
243
                pos += blocksize;
244
                size -= blocksize;
245
            }
246
        }
247
182
        file_unlock(thefile);
248
        file_unlock(thefile);
183
249
184
        return rv;
250
        return rv;
Lines 283-291 Link Here
283
349
284
APR_DECLARE(apr_status_t) apr_file_putc(char ch, apr_file_t *thefile)
350
APR_DECLARE(apr_status_t) apr_file_putc(char ch, apr_file_t *thefile)
285
{
351
{
286
    apr_size_t nbytes = 1;
352
    if (!(thefile->flags & APR_XTHREAD) && 
353
        thefile->buffered &&
354
        thefile->direction == 1 &&
355
        thefile->bufpos < thefile->bufsize) {
287
356
288
    return apr_file_write(thefile, &ch, &nbytes);
357
        thefile->buffer [thefile->bufpos++] = ch;
358
359
        return APR_SUCCESS;
360
    }
361
    else {
362
        apr_size_t nbytes = 1;
363
        return apr_file_write(thefile, &ch, &nbytes);
364
    }
289
}
365
}
290
366
291
APR_DECLARE(apr_status_t) apr_file_ungetc(char ch, apr_file_t *thefile)
367
APR_DECLARE(apr_status_t) apr_file_ungetc(char ch, apr_file_t *thefile)
Lines 296-304 Link Here
296
372
297
APR_DECLARE(apr_status_t) apr_file_getc(char *ch, apr_file_t *thefile)
373
APR_DECLARE(apr_status_t) apr_file_getc(char *ch, apr_file_t *thefile)
298
{
374
{
299
    apr_size_t nbytes = 1;
375
    apr_status_t rc;
376
    apr_size_t bread;
300
377
301
    return apr_file_read(thefile, ch, &nbytes);
378
    if (thefile->ungetchar != -1) {
379
        *ch = (char)thefile->ungetchar;
380
        thefile->ungetchar = -1;
381
        return APR_SUCCESS;
382
    }
383
384
    if (!(thefile->flags & APR_XTHREAD) && 
385
        thefile->buffered &&
386
        thefile->direction == 0 &&
387
        thefile->bufpos < thefile->dataRead) {
388
        *ch = thefile->buffer[thefile->bufpos++];
389
        return APR_SUCCESS;
390
    }
391
392
    bread = 1;
393
    rc = apr_file_read(thefile, ch, &bread);
394
395
    if (rc) {
396
        return rc;
397
    }
398
    
399
    if (bread == 0) {
400
        thefile->eof_hit = TRUE;
401
        return APR_EOF;
402
    }
403
    return APR_SUCCESS; 
302
}
404
}
303
405
304
APR_DECLARE(apr_status_t) apr_file_puts(const char *str, apr_file_t *thefile)
406
APR_DECLARE(apr_status_t) apr_file_puts(const char *str, apr_file_t *thefile)
(-)file_io/win32/readwrite.c (-163 / +248 lines)
Lines 181-192 Link Here
181
        apr_size_t blocksize;
181
        apr_size_t blocksize;
182
        apr_size_t size = *len;
182
        apr_size_t size = *len;
183
183
184
        apr_thread_mutex_lock(thefile->mutex);
184
        if (thefile->flags & APR_XTHREAD)
185
            apr_thread_mutex_lock(thefile->mutex);
185
186
186
        if (thefile->direction == 1) {
187
        if (thefile->direction == 1) {
187
            rv = apr_file_flush(thefile);
188
            rv = apr_file_flush(thefile);
188
            if (rv != APR_SUCCESS) {
189
            if (rv != APR_SUCCESS) {
189
                apr_thread_mutex_unlock(thefile->mutex);
190
                if (thefile->flags & APR_XTHREAD)
191
                    apr_thread_mutex_unlock(thefile->mutex);
190
                return rv;
192
                return rv;
191
            }
193
            }
192
            thefile->bufpos = 0;
194
            thefile->bufpos = 0;
Lines 195-229 Link Here
195
        }
197
        }
196
198
197
        rv = 0;
199
        rv = 0;
198
        while (rv == 0 && size > 0) {
200
        if (size > thefile->bufsize) {
199
            if (thefile->bufpos >= thefile->dataRead) {
201
            apr_size_t read;
200
                apr_size_t read;
202
201
                rv = read_with_timeout(thefile, thefile->buffer, 
203
            blocksize = thefile->dataRead - thefile->bufpos;
202
                                       thefile->bufsize, &read);
204
            if (blocksize > 0) {
203
                if (read == 0) {
205
                memcpy(pos, thefile->buffer + thefile->bufpos, blocksize);
204
                    if (rv == APR_EOF)
206
                thefile->bufpos += blocksize;
205
                        thefile->eof_hit = TRUE;
207
                pos += blocksize;
206
                    break;
208
                size -= blocksize;
207
                }
208
                else {
209
                    thefile->dataRead = read;
210
                    thefile->filePtr += thefile->dataRead;
211
                    thefile->bufpos = 0;
212
                }
213
            }
209
            }
214
210
215
            blocksize = size > thefile->dataRead - thefile->bufpos ? thefile->dataRead - thefile->bufpos : size;
211
            rv = read_with_timeout(thefile, pos, size, &read);
216
            memcpy(pos, thefile->buffer + thefile->bufpos, blocksize);
212
            if (read == 0 && rv == APR_EOF)
217
            thefile->bufpos += blocksize;
213
                thefile->eof_hit = TRUE;
218
            pos += blocksize;
214
219
            size -= blocksize;
215
            thefile->filePtr += read;
216
            pos += read;
220
        }
217
        }
218
        else {
219
            while (rv == 0 && size > 0) {
220
                if (thefile->bufpos >= thefile->dataRead) {
221
                    apr_size_t read;
222
                    rv = read_with_timeout(thefile, thefile->buffer, 
223
                                           thefile->bufsize, &read);
224
                    if (read == 0) {
225
                        if (rv == APR_EOF)
226
                            thefile->eof_hit = TRUE;
227
                        break;
228
                    }
229
                    else {
230
                        thefile->dataRead = read;
231
                        thefile->filePtr += thefile->dataRead;
232
                        thefile->bufpos = 0;
233
                    }
234
                }
221
235
236
                blocksize = size > thefile->dataRead - thefile->bufpos 
237
                          ? thefile->dataRead - thefile->bufpos 
238
                          : size;
239
                memcpy(pos, thefile->buffer + thefile->bufpos, blocksize);
240
                thefile->bufpos += blocksize;
241
                pos += blocksize;
242
                size -= blocksize;
243
            }
244
        }
245
222
        *len = pos - (char *)buf;
246
        *len = pos - (char *)buf;
223
        if (*len) {
247
        if (*len) {
224
            rv = APR_SUCCESS;
248
            rv = APR_SUCCESS;
225
        }
249
        }
226
        apr_thread_mutex_unlock(thefile->mutex);
250
        if (thefile->flags & APR_XTHREAD)
251
            apr_thread_mutex_unlock(thefile->mutex);
227
    } else {  
252
    } else {  
228
        /* Unbuffered i/o */
253
        /* Unbuffered i/o */
229
        apr_size_t nbytes;
254
        apr_size_t nbytes;
Lines 236-267 Link Here
236
    return rv;
261
    return rv;
237
}
262
}
238
263
264
static apr_status_t apr_file_write_locked(apr_file_t *thefile, const void *buf, apr_size_t nbytes)
265
{
266
    DWORD numbytes, written = 0;
267
    apr_status_t rc = APR_SUCCESS;
268
    const char *buffer = buf;
269
270
    do {
271
        if (nbytes > APR_DWORD_MAX) {
272
            numbytes = APR_DWORD_MAX;
273
        }
274
        else {
275
            numbytes = (DWORD)nbytes;
276
        }
277
278
        if (!WriteFile(thefile->filehand, buffer, numbytes, &written, NULL)) {
279
            rc = apr_get_os_error();
280
            thefile->filePtr += written;
281
            break;
282
        }
283
284
        thefile->filePtr += written;
285
        nbytes -= written;
286
        buffer += written;
287
288
    } while (nbytes > 0);
289
290
    return rc;
291
}
292
293
239
APR_DECLARE(apr_status_t) apr_file_write(apr_file_t *thefile, const void *buf, apr_size_t *nbytes)
294
APR_DECLARE(apr_status_t) apr_file_write(apr_file_t *thefile, const void *buf, apr_size_t *nbytes)
240
{
295
{
241
    apr_status_t rv;
296
    apr_status_t rv;
242
    DWORD bwrote;
297
    DWORD bwrote;
298
    apr_size_t size = *nbytes;
243
299
244
    /* If the file is open for xthread support, allocate and
300
    /* Our buffered I/O implementation does not use overlapped I/O.
245
     * initialize the overlapped and io completion event (hEvent). 
246
     * Threads should NOT share an apr_file_t or its hEvent.
247
     */
301
     */
248
    if ((thefile->flags & APR_XTHREAD) && !thefile->pOverlapped ) {
249
        thefile->pOverlapped = (OVERLAPPED*) apr_pcalloc(thefile->pool, 
250
                                                         sizeof(OVERLAPPED));
251
        thefile->pOverlapped->hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
252
        if (!thefile->pOverlapped->hEvent) {
253
            rv = apr_get_os_error();
254
            return rv;
255
        }
256
    }
257
258
    if (thefile->buffered) {
302
    if (thefile->buffered) {
259
        char *pos = (char *)buf;
303
        char *pos = (char *)buf;
260
        apr_size_t blocksize;
304
        apr_size_t blocksize;
261
        apr_size_t size = *nbytes;
262
305
263
        apr_thread_mutex_lock(thefile->mutex);
306
        if (size < 16 &&
307
            !(thefile->flags & APR_XTHREAD) && 
308
            thefile->direction == 1 &&
309
            thefile->bufpos + size <= thefile->bufsize) {
264
310
311
            char *dest = thefile->buffer + thefile->bufpos;
312
            const char *end = pos + size;
313
314
            thefile->bufpos += size;
315
            for (; pos != end; ++pos, ++dest)
316
                *dest = *pos;
317
318
            return APR_SUCCESS;
319
        }
320
321
        if (thefile->flags & APR_XTHREAD)
322
            apr_thread_mutex_lock(thefile->mutex);
323
265
        if (thefile->direction == 0) {
324
        if (thefile->direction == 0) {
266
            // Position file pointer for writing at the offset we are logically reading from
325
            // Position file pointer for writing at the offset we are logically reading from
267
            apr_off_t offset = thefile->filePtr - thefile->dataRead + thefile->bufpos;
326
            apr_off_t offset = thefile->filePtr - thefile->dataRead + thefile->bufpos;
Lines 274-380 Link Here
274
        }
333
        }
275
334
276
        rv = 0;
335
        rv = 0;
277
        while (rv == 0 && size > 0) {
278
            if (thefile->bufpos == thefile->bufsize)   // write buffer is full
279
                rv = apr_file_flush(thefile);
280
336
281
            blocksize = size > thefile->bufsize - thefile->bufpos ? 
337
        /* Large chunks shall not be buffered. They would cause at least one
282
                                     thefile->bufsize - thefile->bufpos : size;
338
         * cache flush just "for themselves". So, we can pass them directly 
283
            memcpy(thefile->buffer + thefile->bufpos, pos, blocksize);
339
         * to the OS instead of copying them around and poking the OS for
284
            thefile->bufpos += blocksize;
340
         * every 4k of data in the buffer. */
285
            pos += blocksize;
341
        if (size > thefile->bufsize) {
286
            size -= blocksize;
342
            rv = apr_file_flush(thefile);
343
            if (rv == APR_SUCCESS)
344
                apr_file_write_locked(thefile, buf, size);
287
        }
345
        }
346
        else {
347
            while (rv == 0 && size > 0) {
348
                if (thefile->bufpos == thefile->bufsize)   // write buffer is full
349
                    rv = apr_file_flush(thefile);
288
350
289
        apr_thread_mutex_unlock(thefile->mutex);
351
                blocksize = size > thefile->bufsize - thefile->bufpos ? 
352
                                         thefile->bufsize - thefile->bufpos : size;
353
                memcpy(thefile->buffer + thefile->bufpos, pos, blocksize);
354
                thefile->bufpos += blocksize;
355
                pos += blocksize;
356
                size -= blocksize;
357
            }
358
        }
359
360
        if (thefile->flags & APR_XTHREAD)
361
            apr_thread_mutex_unlock(thefile->mutex);
362
290
        return rv;
363
        return rv;
291
    } else {
364
    }
292
        if (!thefile->pipe) {
365
293
            apr_off_t offset = 0;
366
    /* If the file is open for xthread support, allocate and
294
            apr_status_t rc;
367
     * initialize the overlapped and io completion event (hEvent). 
295
            if (thefile->append) {
368
     * Threads should NOT share an apr_file_t or its hEvent.
296
                /* apr_file_lock will mutex the file across processes.
369
     */
297
                 * The call to apr_thread_mutex_lock is added to avoid
370
    if ((thefile->flags & APR_XTHREAD) && !thefile->pOverlapped ) {
298
                 * a race condition between LockFile and WriteFile 
371
        thefile->pOverlapped = (OVERLAPPED*) apr_pcalloc(thefile->pool, 
299
                 * that occasionally leads to deadlocked threads.
372
                                                         sizeof(OVERLAPPED));
300
                 */
373
        thefile->pOverlapped->hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
374
        if (!thefile->pOverlapped->hEvent) {
375
            rv = apr_get_os_error();
376
            return rv;
377
        }
378
    }
379
380
    if (!thefile->pipe) {
381
        apr_off_t offset = 0;
382
        apr_status_t rc;
383
        if (thefile->append) {
384
            /* apr_file_lock will mutex the file across processes.
385
             * The call to apr_thread_mutex_lock is added to avoid
386
             * a race condition between LockFile and WriteFile 
387
             * that occasionally leads to deadlocked threads.
388
             */
389
            if (thefile->flags & APR_XTHREAD)
301
                apr_thread_mutex_lock(thefile->mutex);
390
                apr_thread_mutex_lock(thefile->mutex);
302
                rc = apr_file_lock(thefile, APR_FLOCK_EXCLUSIVE);
391
303
                if (rc != APR_SUCCESS) {
392
            rc = apr_file_lock(thefile, APR_FLOCK_EXCLUSIVE);
393
            if (rc != APR_SUCCESS) {
394
                if (thefile->flags & APR_XTHREAD)
304
                    apr_thread_mutex_unlock(thefile->mutex);
395
                    apr_thread_mutex_unlock(thefile->mutex);
305
                    return rc;
396
                return rc;
306
                }
397
            }
307
                rc = apr_file_seek(thefile, APR_END, &offset);
398
            rc = apr_file_seek(thefile, APR_END, &offset);
308
                if (rc != APR_SUCCESS) {
399
            if (rc != APR_SUCCESS) {
400
                if (thefile->flags & APR_XTHREAD)
309
                    apr_thread_mutex_unlock(thefile->mutex);
401
                    apr_thread_mutex_unlock(thefile->mutex);
310
                    return rc;
402
                return rc;
311
                }
312
            }
403
            }
313
            if (thefile->pOverlapped) {
314
                thefile->pOverlapped->Offset     = (DWORD)thefile->filePtr;
315
                thefile->pOverlapped->OffsetHigh = (DWORD)(thefile->filePtr >> 32);
316
            }
317
            rv = WriteFile(thefile->filehand, buf, (DWORD)*nbytes, &bwrote,
318
                           thefile->pOverlapped);
319
            if (thefile->append) {
320
                apr_file_unlock(thefile);
321
                apr_thread_mutex_unlock(thefile->mutex);
322
            }
323
        }
404
        }
324
        else {
405
        if (thefile->pOverlapped) {
325
            rv = WriteFile(thefile->filehand, buf, (DWORD)*nbytes, &bwrote,
406
            thefile->pOverlapped->Offset     = (DWORD)thefile->filePtr;
326
                           thefile->pOverlapped);
407
            thefile->pOverlapped->OffsetHigh = (DWORD)(thefile->filePtr >> 32);
327
        }
408
        }
328
        if (rv) {
409
        rv = WriteFile(thefile->filehand, buf, (DWORD)*nbytes, &bwrote,
329
            *nbytes = bwrote;
410
                       thefile->pOverlapped);
330
            rv = APR_SUCCESS;
411
        if (thefile->append) {
412
            apr_file_unlock(thefile);
413
            if (thefile->flags & APR_XTHREAD)
414
                apr_thread_mutex_unlock(thefile->mutex);
331
        }
415
        }
332
        else {
416
    }
333
            (*nbytes) = 0;
417
    else {
334
            rv = apr_get_os_error();
418
        rv = WriteFile(thefile->filehand, buf, (DWORD)*nbytes, &bwrote,
419
                       thefile->pOverlapped);
420
    }
421
    if (rv) {
422
        *nbytes = bwrote;
423
        rv = APR_SUCCESS;
424
    }
425
    else {
426
        (*nbytes) = 0;
427
        rv = apr_get_os_error();
335
428
336
            /* XXX: This must be corrected, per the apr_file_read logic!!! */
429
        /* XXX: This must be corrected, per the apr_file_read logic!!! */
337
            if (rv == APR_FROM_OS_ERROR(ERROR_IO_PENDING)) {
430
        if (rv == APR_FROM_OS_ERROR(ERROR_IO_PENDING)) {
338
 
339
                DWORD timeout_ms;
340
431
341
                if (thefile->timeout == 0) {
432
            DWORD timeout_ms;
342
                    timeout_ms = 0;
433
343
                }
434
            if (thefile->timeout == 0) {
344
                else if (thefile->timeout < 0) {
435
                timeout_ms = 0;
345
                    timeout_ms = INFINITE;
346
                }
347
                else {
348
                    timeout_ms = (DWORD)(thefile->timeout / 1000);
349
                }
350
	       
351
                rv = WaitForSingleObject(thefile->pOverlapped->hEvent, timeout_ms);
352
                switch (rv) {
353
                    case WAIT_OBJECT_0:
354
                        GetOverlappedResult(thefile->filehand, thefile->pOverlapped, 
355
                                            &bwrote, TRUE);
356
                        *nbytes = bwrote;
357
                        rv = APR_SUCCESS;
358
                        break;
359
                    case WAIT_TIMEOUT:
360
                        rv = (timeout_ms == 0) ? APR_EAGAIN : APR_TIMEUP;
361
                        break;
362
                    case WAIT_FAILED:
363
                        rv = apr_get_os_error();
364
                        break;
365
                    default:
366
                        break;
367
                }
368
                if (rv != APR_SUCCESS) {
369
                    if (apr_os_level >= APR_WIN_98)
370
                        CancelIo(thefile->filehand);
371
                }
372
            }
436
            }
437
            else if (thefile->timeout < 0) {
438
                timeout_ms = INFINITE;
439
            }
440
            else {
441
                timeout_ms = (DWORD)(thefile->timeout / 1000);
442
            }
443
       
444
            rv = WaitForSingleObject(thefile->pOverlapped->hEvent, timeout_ms);
445
            switch (rv) {
446
                case WAIT_OBJECT_0:
447
                    GetOverlappedResult(thefile->filehand, thefile->pOverlapped, 
448
                                        &bwrote, TRUE);
449
                    *nbytes = bwrote;
450
                    rv = APR_SUCCESS;
451
                    break;
452
                case WAIT_TIMEOUT:
453
                    rv = (timeout_ms == 0) ? APR_EAGAIN : APR_TIMEUP;
454
                    break;
455
                case WAIT_FAILED:
456
                    rv = apr_get_os_error();
457
                    break;
458
                default:
459
                    break;
460
            }
461
            if (rv != APR_SUCCESS) {
462
                if (apr_os_level >= APR_WIN_98)
463
                    CancelIo(thefile->filehand);
464
            }
373
        }
465
        }
374
        if (rv == APR_SUCCESS && thefile->pOverlapped && !thefile->pipe) {
375
            thefile->filePtr += *nbytes;
376
        }
377
    }
466
    }
467
    if (rv == APR_SUCCESS && thefile->pOverlapped && !thefile->pipe) {
468
        thefile->filePtr += *nbytes;
469
    }
470
378
    return rv;
471
    return rv;
379
}
472
}
380
/* ToDo: Write for it anyway and test the oslevel!
473
/* ToDo: Write for it anyway and test the oslevel!
Lines 405-413 Link Here
405
498
406
APR_DECLARE(apr_status_t) apr_file_putc(char ch, apr_file_t *thefile)
499
APR_DECLARE(apr_status_t) apr_file_putc(char ch, apr_file_t *thefile)
407
{
500
{
408
    apr_size_t len = 1;
501
    if (!(thefile->flags & APR_XTHREAD) && 
502
        thefile->buffered &&
503
        thefile->direction == 1 &&
504
        thefile->bufpos < thefile->bufsize) {
409
505
410
    return apr_file_write(thefile, &ch, &len);
506
        thefile->buffer [thefile->bufpos++] = ch;
507
508
        return APR_SUCCESS;
509
    }
510
    else {
511
        apr_size_t len = 1;
512
        return apr_file_write(thefile, &ch, &len);
513
    }
411
}
514
}
412
515
413
APR_DECLARE(apr_status_t) apr_file_ungetc(char ch, apr_file_t *thefile)
516
APR_DECLARE(apr_status_t) apr_file_ungetc(char ch, apr_file_t *thefile)
Lines 421-426 Link Here
421
    apr_status_t rc;
524
    apr_status_t rc;
422
    apr_size_t bread;
525
    apr_size_t bread;
423
526
527
    if (thefile->ungetchar != -1) {
528
        *ch = (char)thefile->ungetchar;
529
        thefile->ungetchar = -1;
530
        return APR_SUCCESS;
531
    }
532
533
    if (!(thefile->flags & APR_XTHREAD) && 
534
        thefile->buffered &&
535
        thefile->direction == 0 &&
536
        thefile->bufpos < thefile->dataRead) {
537
        *ch = thefile->buffer[thefile->bufpos++];
538
        return APR_SUCCESS;
539
    }
540
424
    bread = 1;
541
    bread = 1;
425
    rc = apr_file_read(thefile, ch, &bread);
542
    rc = apr_file_read(thefile, ch, &bread);
426
543
Lines 473-519 Link Here
473
590
474
APR_DECLARE(apr_status_t) apr_file_flush(apr_file_t *thefile)
591
APR_DECLARE(apr_status_t) apr_file_flush(apr_file_t *thefile)
475
{
592
{
476
    if (thefile->buffered) {
593
    apr_status_t rc = 0;
477
        DWORD numbytes, written = 0;
478
        apr_status_t rc = 0;
479
        char *buffer;
480
        apr_size_t bytesleft;
481
594
482
        if (thefile->direction == 1 && thefile->bufpos) {
595
    if (thefile->buffered && thefile->direction == 1 && thefile->bufpos) {
483
            buffer = thefile->buffer;
596
        rc = apr_file_write_locked(thefile, thefile->buffer, thefile->bufpos);
484
            bytesleft = thefile->bufpos;           
597
        if (rc == 0)
485
598
            thefile->bufpos = 0;
486
            do {
487
                if (bytesleft > APR_DWORD_MAX) {
488
                    numbytes = APR_DWORD_MAX;
489
                }
490
                else {
491
                    numbytes = (DWORD)bytesleft;
492
                }
493
494
                if (!WriteFile(thefile->filehand, buffer, numbytes, &written, NULL)) {
495
                    rc = apr_get_os_error();
496
                    thefile->filePtr += written;
497
                    break;
498
                }
499
500
                thefile->filePtr += written;
501
                bytesleft -= written;
502
                buffer += written;
503
504
            } while (bytesleft > 0);
505
506
            if (rc == 0)
507
                thefile->bufpos = 0;
508
        }
509
510
        return rc;
511
    }
599
    }
512
600
513
    /* There isn't anything to do if we aren't buffering the output
601
    return rc;
514
     * so just return success.
515
     */
516
    return APR_SUCCESS; 
517
}
602
}
518
603
519
struct apr_file_printf_data {
604
struct apr_file_printf_data {

Return to bug 49085