~ubuntu-branches/ubuntu/feisty/apache2/feisty

« back to all changes in this revision

Viewing changes to srclib/apr/test/testfile.c

  • Committer: Bazaar Package Importer
  • Author(s): Andreas Barth
  • Date: 2006-12-09 21:05:45 UTC
  • mfrom: (0.6.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20061209210545-h70s0xaqc2v8vqr2
Tags: 2.2.3-3.2
* Non-maintainer upload.
* 043_ajp_connection_reuse: Patch from upstream Bugzilla, fixing a critical
  issue with regard to connection reuse in mod_proxy_ajp.
  Closes: #396265

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as
 
2
 * applicable.
 
3
 *
 
4
 * Licensed under the Apache License, Version 2.0 (the "License");
 
5
 * you may not use this file except in compliance with the License.
 
6
 * 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_file_io.h"
 
18
#include "apr_file_info.h"
 
19
#include "apr_network_io.h"
 
20
#include "apr_errno.h"
 
21
#include "apr_general.h"
 
22
#include "apr_poll.h"
 
23
#include "apr_lib.h"
 
24
#include "testutil.h"
 
25
 
 
26
#define DIRNAME "data"
 
27
#define FILENAME DIRNAME "/file_datafile.txt"
 
28
#define TESTSTR  "This is the file data file."
 
29
 
 
30
#define TESTREAD_BLKSIZE 1024
 
31
#define APR_BUFFERSIZE   4096 /* This should match APR's buffer size. */
 
32
 
 
33
 
 
34
 
 
35
static void test_open_noreadwrite(abts_case *tc, void *data)
 
36
{
 
37
    apr_status_t rv;
 
38
    apr_file_t *thefile = NULL;
 
39
 
 
40
    rv = apr_file_open(&thefile, FILENAME,
 
41
                       APR_CREATE | APR_EXCL, 
 
42
                       APR_UREAD | APR_UWRITE | APR_GREAD, p);
 
43
    ABTS_TRUE(tc, rv != APR_SUCCESS);
 
44
    ABTS_INT_EQUAL(tc, 1, APR_STATUS_IS_EACCES(rv));
 
45
    ABTS_PTR_EQUAL(tc, NULL, thefile); 
 
46
}
 
47
 
 
48
static void test_open_excl(abts_case *tc, void *data)
 
49
{
 
50
    apr_status_t rv;
 
51
    apr_file_t *thefile = NULL;
 
52
 
 
53
    rv = apr_file_open(&thefile, FILENAME,
 
54
                       APR_CREATE | APR_EXCL | APR_WRITE, 
 
55
                       APR_UREAD | APR_UWRITE | APR_GREAD, p);
 
56
    ABTS_TRUE(tc, rv != APR_SUCCESS);
 
57
    ABTS_INT_EQUAL(tc, 1, APR_STATUS_IS_EEXIST(rv));
 
58
    ABTS_PTR_EQUAL(tc, NULL, thefile); 
 
59
}
 
60
 
 
61
static void test_open_read(abts_case *tc, void *data)
 
62
{
 
63
    apr_status_t rv;
 
64
    apr_file_t *filetest = NULL;
 
65
 
 
66
    rv = apr_file_open(&filetest, FILENAME, 
 
67
                       APR_READ, 
 
68
                       APR_UREAD | APR_UWRITE | APR_GREAD, p);
 
69
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
70
    ABTS_PTR_NOTNULL(tc, filetest);
 
71
    apr_file_close(filetest);
 
72
}
 
73
 
 
74
static void test_read(abts_case *tc, void *data)
 
75
{
 
76
    apr_status_t rv;
 
77
    apr_size_t nbytes = 256;
 
78
    char *str = apr_pcalloc(p, nbytes + 1);
 
79
    apr_file_t *filetest = NULL;
 
80
    
 
81
    rv = apr_file_open(&filetest, FILENAME, 
 
82
                       APR_READ, 
 
83
                       APR_UREAD | APR_UWRITE | APR_GREAD, p);
 
84
 
 
85
    APR_ASSERT_SUCCESS(tc, "Opening test file " FILENAME, rv);
 
86
    rv = apr_file_read(filetest, str, &nbytes);
 
87
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
88
    ABTS_INT_EQUAL(tc, strlen(TESTSTR), nbytes);
 
89
    ABTS_STR_EQUAL(tc, TESTSTR, str);
 
90
 
 
91
    apr_file_close(filetest);
 
92
}
 
93
 
 
94
static void test_readzero(abts_case *tc, void *data)
 
95
{
 
96
    apr_status_t rv;
 
97
    apr_size_t nbytes = 0;
 
98
    char *str = NULL;
 
99
    apr_file_t *filetest;
 
100
    
 
101
    rv = apr_file_open(&filetest, FILENAME, APR_READ, APR_OS_DEFAULT, p);
 
102
    APR_ASSERT_SUCCESS(tc, "Opening test file " FILENAME, rv);
 
103
 
 
104
    rv = apr_file_read(filetest, str, &nbytes);
 
105
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
106
    ABTS_INT_EQUAL(tc, 0, nbytes);
 
107
 
 
108
    apr_file_close(filetest);
 
109
}
 
110
 
 
111
static void test_filename(abts_case *tc, void *data)
 
112
{
 
113
    const char *str;
 
114
    apr_status_t rv;
 
115
    apr_file_t *filetest = NULL;
 
116
    
 
117
    rv = apr_file_open(&filetest, FILENAME, 
 
118
                       APR_READ, 
 
119
                       APR_UREAD | APR_UWRITE | APR_GREAD, p);
 
120
    APR_ASSERT_SUCCESS(tc, "Opening test file " FILENAME, rv);
 
121
 
 
122
    rv = apr_file_name_get(&str, filetest);
 
123
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
124
    ABTS_STR_EQUAL(tc, FILENAME, str);
 
125
 
 
126
    apr_file_close(filetest);
 
127
}
 
128
    
 
129
static void test_fileclose(abts_case *tc, void *data)
 
130
{
 
131
    char str;
 
132
    apr_status_t rv;
 
133
    apr_size_t one = 1;
 
134
    apr_file_t *filetest = NULL;
 
135
    
 
136
    rv = apr_file_open(&filetest, FILENAME, 
 
137
                       APR_READ, 
 
138
                       APR_UREAD | APR_UWRITE | APR_GREAD, p);
 
139
    APR_ASSERT_SUCCESS(tc, "Opening test file " FILENAME, rv);
 
140
 
 
141
    rv = apr_file_close(filetest);
 
142
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
143
    /* We just closed the file, so this should fail */
 
144
    rv = apr_file_read(filetest, &str, &one);
 
145
    ABTS_INT_EQUAL(tc, 1, APR_STATUS_IS_EBADF(rv));
 
146
}
 
147
 
 
148
static void test_file_remove(abts_case *tc, void *data)
 
149
{
 
150
    apr_status_t rv;
 
151
    apr_file_t *filetest = NULL;
 
152
 
 
153
    rv = apr_file_remove(FILENAME, p);
 
154
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
155
 
 
156
    rv = apr_file_open(&filetest, FILENAME, APR_READ, 
 
157
                       APR_UREAD | APR_UWRITE | APR_GREAD, p);
 
158
    ABTS_INT_EQUAL(tc, 1, APR_STATUS_IS_ENOENT(rv));
 
159
}
 
160
 
 
161
static void test_open_write(abts_case *tc, void *data)
 
162
{
 
163
    apr_status_t rv;
 
164
    apr_file_t *filetest = NULL;
 
165
 
 
166
    filetest = NULL;
 
167
    rv = apr_file_open(&filetest, FILENAME, 
 
168
                       APR_WRITE, 
 
169
                       APR_UREAD | APR_UWRITE | APR_GREAD, p);
 
170
    ABTS_INT_EQUAL(tc, 1, APR_STATUS_IS_ENOENT(rv));
 
171
    ABTS_PTR_EQUAL(tc, NULL, filetest);
 
172
}
 
173
 
 
174
static void test_open_writecreate(abts_case *tc, void *data)
 
175
{
 
176
    apr_status_t rv;
 
177
    apr_file_t *filetest = NULL;
 
178
 
 
179
    filetest = NULL;
 
180
    rv = apr_file_open(&filetest, FILENAME, 
 
181
                       APR_WRITE | APR_CREATE, 
 
182
                       APR_UREAD | APR_UWRITE | APR_GREAD, p);
 
183
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
184
 
 
185
    apr_file_close(filetest);
 
186
}
 
187
 
 
188
static void test_write(abts_case *tc, void *data)
 
189
{
 
190
    apr_status_t rv;
 
191
    apr_size_t bytes = strlen(TESTSTR);
 
192
    apr_file_t *filetest = NULL;
 
193
 
 
194
    rv = apr_file_open(&filetest, FILENAME, 
 
195
                       APR_WRITE | APR_CREATE, 
 
196
                       APR_UREAD | APR_UWRITE | APR_GREAD, p);
 
197
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
198
 
 
199
    rv = apr_file_write(filetest, TESTSTR, &bytes);
 
200
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
201
 
 
202
    apr_file_close(filetest);
 
203
}
 
204
 
 
205
static void test_open_readwrite(abts_case *tc, void *data)
 
206
{
 
207
    apr_status_t rv;
 
208
    apr_file_t *filetest = NULL;
 
209
 
 
210
    filetest = NULL;
 
211
    rv = apr_file_open(&filetest, FILENAME, 
 
212
                       APR_READ | APR_WRITE, 
 
213
                       APR_UREAD | APR_UWRITE | APR_GREAD, p);
 
214
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
215
    ABTS_PTR_NOTNULL(tc, filetest);
 
216
 
 
217
    apr_file_close(filetest);
 
218
}
 
219
 
 
220
static void test_seek(abts_case *tc, void *data)
 
221
{
 
222
    apr_status_t rv;
 
223
    apr_off_t offset = 5;
 
224
    apr_size_t nbytes = 256;
 
225
    char *str = apr_pcalloc(p, nbytes + 1);
 
226
    apr_file_t *filetest = NULL;
 
227
 
 
228
    rv = apr_file_open(&filetest, FILENAME, 
 
229
                       APR_READ, 
 
230
                       APR_UREAD | APR_UWRITE | APR_GREAD, p);
 
231
    APR_ASSERT_SUCCESS(tc, "Open test file " FILENAME, rv);
 
232
 
 
233
    rv = apr_file_read(filetest, str, &nbytes);
 
234
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
235
    ABTS_INT_EQUAL(tc, strlen(TESTSTR), nbytes);
 
236
    ABTS_STR_EQUAL(tc, TESTSTR, str);
 
237
 
 
238
    memset(str, 0, nbytes + 1);
 
239
 
 
240
    rv = apr_file_seek(filetest, SEEK_SET, &offset);
 
241
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
242
    
 
243
    rv = apr_file_read(filetest, str, &nbytes);
 
244
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
245
    ABTS_INT_EQUAL(tc, strlen(TESTSTR) - 5, nbytes);
 
246
    ABTS_STR_EQUAL(tc, TESTSTR + 5, str);
 
247
 
 
248
    apr_file_close(filetest);
 
249
 
 
250
    /* Test for regression of sign error bug with SEEK_END and
 
251
       buffered files. */
 
252
    rv = apr_file_open(&filetest, FILENAME,
 
253
                       APR_READ | APR_BUFFERED,
 
254
                       APR_UREAD | APR_UWRITE | APR_GREAD, p);
 
255
    APR_ASSERT_SUCCESS(tc, "Open test file " FILENAME, rv);
 
256
 
 
257
    offset = -5;
 
258
    rv = apr_file_seek(filetest, SEEK_END, &offset);
 
259
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
260
    ABTS_INT_EQUAL(tc, strlen(TESTSTR) - 5, nbytes);
 
261
 
 
262
    memset(str, 0, nbytes + 1);
 
263
    nbytes = 256;
 
264
    rv = apr_file_read(filetest, str, &nbytes);
 
265
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
266
    ABTS_INT_EQUAL(tc, 5, nbytes);
 
267
    ABTS_STR_EQUAL(tc, TESTSTR + strlen(TESTSTR) - 5, str);
 
268
 
 
269
    apr_file_close(filetest);
 
270
}                
 
271
 
 
272
static void test_userdata_set(abts_case *tc, void *data)
 
273
{
 
274
    apr_status_t rv;
 
275
    apr_file_t *filetest = NULL;
 
276
 
 
277
    rv = apr_file_open(&filetest, FILENAME, 
 
278
                       APR_WRITE, 
 
279
                       APR_UREAD | APR_UWRITE | APR_GREAD, p);
 
280
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
281
 
 
282
    rv = apr_file_data_set(filetest, "This is a test",
 
283
                           "test", apr_pool_cleanup_null);
 
284
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
285
    apr_file_close(filetest);
 
286
}
 
287
 
 
288
static void test_userdata_get(abts_case *tc, void *data)
 
289
{
 
290
    apr_status_t rv;
 
291
    void *udata;
 
292
    char *teststr;
 
293
    apr_file_t *filetest = NULL;
 
294
 
 
295
    rv = apr_file_open(&filetest, FILENAME, 
 
296
                       APR_WRITE, 
 
297
                       APR_UREAD | APR_UWRITE | APR_GREAD, p);
 
298
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
299
 
 
300
    rv = apr_file_data_set(filetest, "This is a test",
 
301
                           "test", apr_pool_cleanup_null);
 
302
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
303
 
 
304
    rv = apr_file_data_get(&udata, "test", filetest);
 
305
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
306
    teststr = udata;
 
307
    ABTS_STR_EQUAL(tc, "This is a test", teststr);
 
308
 
 
309
    apr_file_close(filetest);
 
310
}
 
311
 
 
312
static void test_userdata_getnokey(abts_case *tc, void *data)
 
313
{
 
314
    apr_status_t rv;
 
315
    void *teststr;
 
316
    apr_file_t *filetest = NULL;
 
317
 
 
318
    rv = apr_file_open(&filetest, FILENAME, 
 
319
                       APR_WRITE, 
 
320
                       APR_UREAD | APR_UWRITE | APR_GREAD, p);
 
321
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
322
 
 
323
    rv = apr_file_data_get(&teststr, "nokey", filetest);
 
324
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
325
    ABTS_PTR_EQUAL(tc, NULL, teststr);
 
326
    apr_file_close(filetest);
 
327
}
 
328
 
 
329
static void test_getc(abts_case *tc, void *data)
 
330
{
 
331
    apr_file_t *f = NULL;
 
332
    apr_status_t rv;
 
333
    char ch;
 
334
 
 
335
    rv = apr_file_open(&f, FILENAME, APR_READ, 0, p);
 
336
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
337
 
 
338
    apr_file_getc(&ch, f);
 
339
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
340
    ABTS_INT_EQUAL(tc, (int)TESTSTR[0], (int)ch);
 
341
    apr_file_close(f);
 
342
}
 
343
 
 
344
static void test_ungetc(abts_case *tc, void *data)
 
345
{
 
346
    apr_file_t *f = NULL;
 
347
    apr_status_t rv;
 
348
    char ch;
 
349
 
 
350
    rv = apr_file_open(&f, FILENAME, APR_READ, 0, p);
 
351
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
352
 
 
353
    apr_file_getc(&ch, f);
 
354
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
355
    ABTS_INT_EQUAL(tc, (int)TESTSTR[0], (int)ch);
 
356
 
 
357
    apr_file_ungetc('X', f);
 
358
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
359
 
 
360
    apr_file_getc(&ch, f);
 
361
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
362
    ABTS_INT_EQUAL(tc, 'X', (int)ch);
 
363
 
 
364
    apr_file_close(f);
 
365
}
 
366
 
 
367
static void test_gets(abts_case *tc, void *data)
 
368
{
 
369
    apr_file_t *f = NULL;
 
370
    apr_status_t rv;
 
371
    char *str = apr_palloc(p, 256);
 
372
 
 
373
    rv = apr_file_open(&f, FILENAME, APR_READ, 0, p);
 
374
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
375
 
 
376
    rv = apr_file_gets(str, 256, f);
 
377
    /* Only one line in the test file, so APR will encounter EOF on the first
 
378
     * call to gets, but we should get APR_SUCCESS on this call and
 
379
     * APR_EOF on the next.
 
380
     */
 
381
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
382
    ABTS_STR_EQUAL(tc, TESTSTR, str);
 
383
    rv = apr_file_gets(str, 256, f);
 
384
    ABTS_INT_EQUAL(tc, APR_EOF, rv);
 
385
    ABTS_STR_EQUAL(tc, "", str);
 
386
    apr_file_close(f);
 
387
}
 
388
 
 
389
static void test_bigread(abts_case *tc, void *data)
 
390
{
 
391
    apr_file_t *f = NULL;
 
392
    apr_status_t rv;
 
393
    char buf[APR_BUFFERSIZE * 2];
 
394
    apr_size_t nbytes;
 
395
 
 
396
    /* Create a test file with known content.
 
397
     */
 
398
    rv = apr_file_open(&f, "data/created_file", 
 
399
                       APR_CREATE | APR_WRITE | APR_TRUNCATE, 
 
400
                       APR_UREAD | APR_UWRITE, p);
 
401
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
402
 
 
403
    nbytes = APR_BUFFERSIZE;
 
404
    memset(buf, 0xFE, nbytes);
 
405
 
 
406
    rv = apr_file_write(f, buf, &nbytes);
 
407
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
408
    ABTS_INT_EQUAL(tc, APR_BUFFERSIZE, nbytes);
 
409
 
 
410
    rv = apr_file_close(f);
 
411
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
412
 
 
413
    f = NULL;
 
414
    rv = apr_file_open(&f, "data/created_file", APR_READ, 0, p);
 
415
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
416
 
 
417
    nbytes = sizeof buf;
 
418
    rv = apr_file_read(f, buf, &nbytes);
 
419
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
420
    ABTS_INT_EQUAL(tc, APR_BUFFERSIZE, nbytes);
 
421
 
 
422
    rv = apr_file_close(f);
 
423
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
424
 
 
425
    rv = apr_file_remove("data/created_file", p);
 
426
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
427
}
 
428
 
 
429
/* This is a horrible name for this function.  We are testing APR, not how
 
430
 * Apache uses APR.  And, this function tests _way_ too much stuff.
 
431
 */
 
432
static void test_mod_neg(abts_case *tc, void *data)
 
433
{
 
434
    apr_status_t rv;
 
435
    apr_file_t *f;
 
436
    const char *s;
 
437
    int i;
 
438
    apr_size_t nbytes;
 
439
    char buf[8192];
 
440
    apr_off_t cur;
 
441
    const char *fname = "data/modneg.dat";
 
442
 
 
443
    rv = apr_file_open(&f, fname, 
 
444
                       APR_CREATE | APR_WRITE, APR_UREAD | APR_UWRITE, p);
 
445
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
446
 
 
447
    s = "body56789\n";
 
448
    nbytes = strlen(s);
 
449
    rv = apr_file_write(f, s, &nbytes);
 
450
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
451
    ABTS_INT_EQUAL(tc, strlen(s), nbytes);
 
452
    
 
453
    for (i = 0; i < 7980; i++) {
 
454
        s = "0";
 
455
        nbytes = strlen(s);
 
456
        rv = apr_file_write(f, s, &nbytes);
 
457
        ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
458
        ABTS_INT_EQUAL(tc, strlen(s), nbytes);
 
459
    }
 
460
    
 
461
    s = "end456789\n";
 
462
    nbytes = strlen(s);
 
463
    rv = apr_file_write(f, s, &nbytes);
 
464
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
465
    ABTS_INT_EQUAL(tc, strlen(s), nbytes);
 
466
 
 
467
    for (i = 0; i < 10000; i++) {
 
468
        s = "1";
 
469
        nbytes = strlen(s);
 
470
        rv = apr_file_write(f, s, &nbytes);
 
471
        ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
472
        ABTS_INT_EQUAL(tc, strlen(s), nbytes);
 
473
    }
 
474
    
 
475
    rv = apr_file_close(f);
 
476
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
477
 
 
478
    rv = apr_file_open(&f, fname, APR_READ, 0, p);
 
479
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
480
 
 
481
    rv = apr_file_gets(buf, 11, f);
 
482
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
483
    ABTS_STR_EQUAL(tc, "body56789\n", buf);
 
484
 
 
485
    cur = 0;
 
486
    rv = apr_file_seek(f, APR_CUR, &cur);
 
487
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
488
    ABTS_ASSERT(tc, "File Pointer Mismatch, expected 10", cur == 10);
 
489
 
 
490
    nbytes = sizeof(buf);
 
491
    rv = apr_file_read(f, buf, &nbytes);
 
492
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
493
    ABTS_INT_EQUAL(tc, nbytes, sizeof(buf));
 
494
 
 
495
    cur = -((apr_off_t)nbytes - 7980);
 
496
    rv = apr_file_seek(f, APR_CUR, &cur);
 
497
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
498
    ABTS_ASSERT(tc, "File Pointer Mismatch, expected 7990", cur == 7990);
 
499
 
 
500
    rv = apr_file_gets(buf, 11, f);
 
501
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
502
    ABTS_STR_EQUAL(tc, "end456789\n", buf);
 
503
 
 
504
    rv = apr_file_close(f);
 
505
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
506
 
 
507
    rv = apr_file_remove(fname, p);
 
508
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
509
}
 
510
 
 
511
/* Test that the contents of file FNAME are equal to data EXPECT of
 
512
 * length EXPECTLEN. */
 
513
static void file_contents_equal(abts_case *tc,
 
514
                                const char *fname,
 
515
                                const void *expect,
 
516
                                apr_size_t expectlen)
 
517
{
 
518
    void *actual = apr_palloc(p, expectlen);
 
519
    apr_file_t *f;
 
520
 
 
521
    APR_ASSERT_SUCCESS(tc, "open file",
 
522
                       apr_file_open(&f, fname, APR_READ|APR_BUFFERED,
 
523
                                     0, p));
 
524
    APR_ASSERT_SUCCESS(tc, "read from file",
 
525
                       apr_file_read_full(f, actual, expectlen, NULL));
 
526
    
 
527
    ABTS_ASSERT(tc, "matched expected file contents",
 
528
                memcmp(expect, actual, expectlen) == 0);
 
529
 
 
530
    APR_ASSERT_SUCCESS(tc, "close file", apr_file_close(f));
 
531
}
 
532
 
 
533
#define LINE1 "this is a line of text\n"
 
534
#define LINE2 "this is a second line of text\n"
 
535
 
 
536
static void test_puts(abts_case *tc, void *data)
 
537
{
 
538
    apr_file_t *f;
 
539
    const char *fname = "data/testputs.txt";
 
540
 
 
541
    APR_ASSERT_SUCCESS(tc, "open file for writing",
 
542
                       apr_file_open(&f, fname, 
 
543
                                     APR_WRITE|APR_CREATE|APR_TRUNCATE, 
 
544
                                     APR_OS_DEFAULT, p));
 
545
    
 
546
    APR_ASSERT_SUCCESS(tc, "write line to file", 
 
547
                       apr_file_puts(LINE1, f));
 
548
    APR_ASSERT_SUCCESS(tc, "write second line to file", 
 
549
                       apr_file_puts(LINE2, f));
 
550
    
 
551
    APR_ASSERT_SUCCESS(tc, "close for writing",
 
552
                       apr_file_close(f));
 
553
 
 
554
    file_contents_equal(tc, fname, LINE1 LINE2, strlen(LINE1 LINE2));
 
555
}
 
556
 
 
557
static void test_writev(abts_case *tc, void *data)
 
558
{
 
559
    apr_file_t *f;
 
560
    apr_size_t nbytes;
 
561
    struct iovec vec[5];
 
562
    const char *fname = "data/testwritev.txt";
 
563
 
 
564
    APR_ASSERT_SUCCESS(tc, "open file for writing",
 
565
                       apr_file_open(&f, fname, 
 
566
                                     APR_WRITE|APR_CREATE|APR_TRUNCATE, 
 
567
                                     APR_OS_DEFAULT, p));
 
568
    
 
569
    vec[0].iov_base = LINE1;
 
570
    vec[0].iov_len = strlen(LINE1);
 
571
 
 
572
    APR_ASSERT_SUCCESS(tc, "writev of size 1 to file",
 
573
                       apr_file_writev(f, vec, 1, &nbytes));
 
574
 
 
575
    file_contents_equal(tc, fname, LINE1, strlen(LINE1));
 
576
    
 
577
    vec[0].iov_base = LINE1;
 
578
    vec[0].iov_len = strlen(LINE1);
 
579
    vec[1].iov_base = LINE2;
 
580
    vec[1].iov_len = strlen(LINE2);
 
581
    vec[2].iov_base = LINE1;
 
582
    vec[2].iov_len = strlen(LINE1);
 
583
    vec[3].iov_base = LINE1;
 
584
    vec[3].iov_len = strlen(LINE1);
 
585
    vec[4].iov_base = LINE2;
 
586
    vec[4].iov_len = strlen(LINE2);
 
587
 
 
588
    APR_ASSERT_SUCCESS(tc, "writev of size 5 to file",
 
589
                       apr_file_writev(f, vec, 5, &nbytes));
 
590
 
 
591
    APR_ASSERT_SUCCESS(tc, "close for writing",
 
592
                       apr_file_close(f));
 
593
 
 
594
    file_contents_equal(tc, fname, LINE1 LINE1 LINE2 LINE1 LINE1 LINE2, 
 
595
                        strlen(LINE1)*4 + strlen(LINE2)*2);
 
596
 
 
597
}
 
598
 
 
599
static void test_writev_full(abts_case *tc, void *data)
 
600
{
 
601
    apr_file_t *f;
 
602
    apr_size_t nbytes;
 
603
    struct iovec vec[5];
 
604
    const char *fname = "data/testwritev_full.txt";
 
605
 
 
606
    APR_ASSERT_SUCCESS(tc, "open file for writing",
 
607
                       apr_file_open(&f, fname, 
 
608
                                     APR_WRITE|APR_CREATE|APR_TRUNCATE, 
 
609
                                     APR_OS_DEFAULT, p));
 
610
    
 
611
    vec[0].iov_base = LINE1;
 
612
    vec[0].iov_len = strlen(LINE1);
 
613
    vec[1].iov_base = LINE2;
 
614
    vec[1].iov_len = strlen(LINE2);
 
615
    vec[2].iov_base = LINE1;
 
616
    vec[2].iov_len = strlen(LINE1);
 
617
    vec[3].iov_base = LINE1;
 
618
    vec[3].iov_len = strlen(LINE1);
 
619
    vec[4].iov_base = LINE2;
 
620
    vec[4].iov_len = strlen(LINE2);
 
621
 
 
622
    APR_ASSERT_SUCCESS(tc, "writev_full of size 5 to file",
 
623
                       apr_file_writev_full(f, vec, 5, &nbytes));
 
624
 
 
625
    ABTS_INT_EQUAL(tc, strlen(LINE1)*3 + strlen(LINE2)*2, nbytes);
 
626
 
 
627
    APR_ASSERT_SUCCESS(tc, "close for writing",
 
628
                       apr_file_close(f));
 
629
 
 
630
    file_contents_equal(tc, fname, LINE1 LINE2 LINE1 LINE1 LINE2, 
 
631
                        strlen(LINE1)*3 + strlen(LINE2)*2);
 
632
 
 
633
}
 
634
 
 
635
static void test_truncate(abts_case *tc, void *data)
 
636
{
 
637
    apr_status_t rv;
 
638
    apr_file_t *f;
 
639
    const char *fname = "data/testtruncate.dat";
 
640
    const char *s;
 
641
    apr_size_t nbytes;
 
642
    apr_finfo_t finfo;
 
643
 
 
644
    apr_file_remove(fname, p);
 
645
 
 
646
    rv = apr_file_open(&f, fname,
 
647
                       APR_CREATE | APR_WRITE, APR_UREAD | APR_UWRITE, p);
 
648
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
649
    
 
650
    s = "some data";
 
651
    nbytes = strlen(s);
 
652
    rv = apr_file_write(f, s, &nbytes);
 
653
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
654
    ABTS_INT_EQUAL(tc, strlen(s), nbytes);
 
655
 
 
656
    rv = apr_file_close(f);
 
657
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
658
 
 
659
    rv = apr_file_open(&f, fname,
 
660
                       APR_TRUNCATE | APR_WRITE, APR_UREAD | APR_UWRITE, p);
 
661
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
662
 
 
663
    rv = apr_file_close(f);
 
664
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
665
 
 
666
    rv = apr_stat(&finfo, fname, APR_FINFO_SIZE, p);
 
667
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
668
    ABTS_ASSERT(tc, "File size mismatch, expected 0 (empty)", finfo.size == 0);
 
669
 
 
670
    rv = apr_file_remove(fname, p);
 
671
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
672
}
 
673
 
 
674
static void test_bigfprintf(abts_case *tc, void *data)
 
675
{
 
676
    apr_file_t *f;
 
677
    const char *fname = "data/testbigfprintf.dat";
 
678
    char *to_write;
 
679
    int i;
 
680
 
 
681
    apr_file_remove(fname, p);
 
682
 
 
683
    APR_ASSERT_SUCCESS(tc, "open test file",
 
684
                       apr_file_open(&f, fname,
 
685
                                     APR_CREATE|APR_WRITE,
 
686
                                     APR_UREAD|APR_UWRITE, p));
 
687
    
 
688
 
 
689
    to_write = malloc(HUGE_STRING_LEN + 3);
 
690
 
 
691
    for (i = 0; i < HUGE_STRING_LEN + 1; ++i)
 
692
        to_write[i] = 'A' + i%26;
 
693
 
 
694
    strcpy(to_write + HUGE_STRING_LEN, "42");
 
695
 
 
696
    i = apr_file_printf(f, "%s", to_write);
 
697
    ABTS_INT_EQUAL(tc, HUGE_STRING_LEN + 2, i);
 
698
 
 
699
    apr_file_close(f);
 
700
 
 
701
    file_contents_equal(tc, fname, to_write, HUGE_STRING_LEN + 2);
 
702
 
 
703
    free(to_write);
 
704
}
 
705
 
 
706
static void test_fail_write_flush(abts_case *tc, void *data)
 
707
{
 
708
    apr_file_t *f;
 
709
    const char *fname = "data/testflush.dat";
 
710
    apr_status_t rv;
 
711
    char buf[APR_BUFFERSIZE];
 
712
    int n;
 
713
 
 
714
    apr_file_remove(fname, p);
 
715
 
 
716
    APR_ASSERT_SUCCESS(tc, "open test file",
 
717
                       apr_file_open(&f, fname,
 
718
                                     APR_CREATE|APR_READ|APR_BUFFERED,
 
719
                                     APR_UREAD|APR_UWRITE, p));
 
720
 
 
721
    memset(buf, 'A', sizeof buf);
 
722
 
 
723
    /* Try three writes.  One of these should fail when it exceeds the
 
724
     * internal buffer and actually tries to write to the file, which
 
725
     * was opened read-only and hence should be unwritable. */
 
726
    for (n = 0, rv = APR_SUCCESS; n < 4 && rv == APR_SUCCESS; n++) {
 
727
        apr_size_t bytes = sizeof buf;
 
728
        rv = apr_file_write(f, buf, &bytes);
 
729
    }
 
730
 
 
731
    ABTS_ASSERT(tc, "failed to write to read-only buffered fd",
 
732
                rv != APR_SUCCESS);
 
733
 
 
734
    apr_file_close(f);
 
735
}
 
736
 
 
737
static void test_fail_read_flush(abts_case *tc, void *data)
 
738
{
 
739
    apr_file_t *f;
 
740
    const char *fname = "data/testflush.dat";
 
741
    apr_status_t rv;
 
742
    char buf[2];
 
743
 
 
744
    apr_file_remove(fname, p);
 
745
 
 
746
    APR_ASSERT_SUCCESS(tc, "open test file",
 
747
                       apr_file_open(&f, fname,
 
748
                                     APR_CREATE|APR_READ|APR_BUFFERED,
 
749
                                     APR_UREAD|APR_UWRITE, p));
 
750
 
 
751
    /* this write should be buffered. */
 
752
    APR_ASSERT_SUCCESS(tc, "buffered write should succeed",
 
753
                       apr_file_puts("hello", f));
 
754
 
 
755
    /* Now, trying a read should fail since the write must be flushed,
 
756
     * and should fail with something other than EOF since the file is
 
757
     * opened read-only. */
 
758
    rv = apr_file_read_full(f, buf, 2, NULL);
 
759
 
 
760
    ABTS_ASSERT(tc, "read should flush buffered write and fail",
 
761
                rv != APR_SUCCESS && rv != APR_EOF);
 
762
 
 
763
    /* Likewise for gets */
 
764
    rv = apr_file_gets(buf, 2, f);
 
765
 
 
766
    ABTS_ASSERT(tc, "gets should flush buffered write and fail",
 
767
                rv != APR_SUCCESS && rv != APR_EOF);
 
768
 
 
769
    /* Likewise for seek. */
 
770
    {
 
771
        apr_off_t offset = 0;
 
772
 
 
773
        rv = apr_file_seek(f, APR_SET, &offset);
 
774
    }
 
775
 
 
776
    ABTS_ASSERT(tc, "seek should flush buffered write and fail",
 
777
                rv != APR_SUCCESS && rv != APR_EOF);
 
778
 
 
779
    apr_file_close(f);
 
780
}
 
781
 
 
782
static void test_xthread(abts_case *tc, void *data)
 
783
{
 
784
    apr_file_t *f;
 
785
    const char *fname = "data/testxthread.dat";
 
786
    apr_status_t rv;
 
787
    apr_int32_t flags = APR_CREATE|APR_READ|APR_WRITE|APR_APPEND|APR_XTHREAD;
 
788
    char buf[128] = { 0 };
 
789
 
 
790
    /* Test for bug 38438, opening file with append + xthread and seeking to 
 
791
       the end of the file resulted in writes going to the beginning not the
 
792
       end. */
 
793
 
 
794
    apr_file_remove(fname, p);
 
795
 
 
796
    APR_ASSERT_SUCCESS(tc, "open test file",
 
797
                       apr_file_open(&f, fname, flags,
 
798
                                     APR_UREAD|APR_UWRITE, p));
 
799
 
 
800
    APR_ASSERT_SUCCESS(tc, "write should succeed",
 
801
                       apr_file_puts("hello", f));
 
802
 
 
803
    apr_file_close(f);
 
804
    
 
805
    APR_ASSERT_SUCCESS(tc, "open test file",
 
806
                       apr_file_open(&f, fname, flags,
 
807
                                     APR_UREAD|APR_UWRITE, p));
 
808
 
 
809
    /* Seek to the end. */
 
810
    {
 
811
        apr_off_t offset = 0;
 
812
 
 
813
        rv = apr_file_seek(f, APR_END, &offset);
 
814
    }
 
815
 
 
816
    APR_ASSERT_SUCCESS(tc, "more writes should succeed",
 
817
                       apr_file_puts("world", f));
 
818
 
 
819
    /* Back to the beginning. */
 
820
    {
 
821
        apr_off_t offset = 0;
 
822
        
 
823
        rv = apr_file_seek(f, APR_SET, &offset);
 
824
    }
 
825
    
 
826
    apr_file_read_full(f, buf, sizeof(buf), NULL);
 
827
 
 
828
    ABTS_STR_EQUAL(tc, "helloworld", buf);
 
829
 
 
830
    apr_file_close(f);
 
831
}
 
832
 
 
833
abts_suite *testfile(abts_suite *suite)
 
834
{
 
835
    suite = ADD_SUITE(suite)
 
836
 
 
837
    abts_run_test(suite, test_open_noreadwrite, NULL);
 
838
    abts_run_test(suite, test_open_excl, NULL);
 
839
    abts_run_test(suite, test_open_read, NULL);
 
840
    abts_run_test(suite, test_open_readwrite, NULL);
 
841
    abts_run_test(suite, test_read, NULL); 
 
842
    abts_run_test(suite, test_readzero, NULL); 
 
843
    abts_run_test(suite, test_seek, NULL);
 
844
    abts_run_test(suite, test_filename, NULL);
 
845
    abts_run_test(suite, test_fileclose, NULL);
 
846
    abts_run_test(suite, test_file_remove, NULL);
 
847
    abts_run_test(suite, test_open_write, NULL);
 
848
    abts_run_test(suite, test_open_writecreate, NULL);
 
849
    abts_run_test(suite, test_write, NULL);
 
850
    abts_run_test(suite, test_userdata_set, NULL);
 
851
    abts_run_test(suite, test_userdata_get, NULL);
 
852
    abts_run_test(suite, test_userdata_getnokey, NULL);
 
853
    abts_run_test(suite, test_getc, NULL);
 
854
    abts_run_test(suite, test_ungetc, NULL);
 
855
    abts_run_test(suite, test_gets, NULL);
 
856
    abts_run_test(suite, test_puts, NULL);
 
857
    abts_run_test(suite, test_writev, NULL);
 
858
    abts_run_test(suite, test_writev_full, NULL);
 
859
    abts_run_test(suite, test_bigread, NULL);
 
860
    abts_run_test(suite, test_mod_neg, NULL);
 
861
    abts_run_test(suite, test_truncate, NULL);
 
862
    abts_run_test(suite, test_bigfprintf, NULL);
 
863
    abts_run_test(suite, test_fail_write_flush, NULL);
 
864
    abts_run_test(suite, test_fail_read_flush, NULL);
 
865
    abts_run_test(suite, test_xthread, NULL);
 
866
 
 
867
    return suite;
 
868
}
 
869