xref: /aosp_15_r20/external/cronet/third_party/apache-portable-runtime/src/test/testfile.c (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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_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 
test_open_noreadwrite(abts_case * tc,void * data)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_FOPEN_CREATE | APR_FOPEN_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 
test_open_excl(abts_case * tc,void * data)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_FOPEN_CREATE | APR_FOPEN_EXCL | APR_FOPEN_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 
test_open_read(abts_case * tc,void * data)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_FOPEN_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 
link_existing(abts_case * tc,void * data)74 static void link_existing(abts_case *tc, void *data)
75 {
76     apr_status_t rv;
77 
78     rv = apr_file_link("data/file_datafile.txt", "data/file_datafile2.txt");
79     apr_file_remove("data/file_datafile2.txt", p);
80     ABTS_ASSERT(tc, "Couldn't create hardlink to file", rv == APR_SUCCESS);
81 }
82 
link_nonexisting(abts_case * tc,void * data)83 static void link_nonexisting(abts_case *tc, void *data)
84 {
85     apr_status_t rv;
86 
87     rv = apr_file_link("data/does_not_exist.txt", "data/fake.txt");
88     ABTS_ASSERT(tc, "", rv != APR_SUCCESS);
89 }
90 
test_read(abts_case * tc,void * data)91 static void test_read(abts_case *tc, void *data)
92 {
93     apr_status_t rv;
94     apr_size_t nbytes = 256;
95     char *str = apr_pcalloc(p, nbytes + 1);
96     apr_file_t *filetest = NULL;
97 
98     rv = apr_file_open(&filetest, FILENAME,
99                        APR_FOPEN_READ,
100                        APR_UREAD | APR_UWRITE | APR_GREAD, p);
101 
102     APR_ASSERT_SUCCESS(tc, "Opening test file " FILENAME, rv);
103     rv = apr_file_read(filetest, str, &nbytes);
104     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
105     ABTS_SIZE_EQUAL(tc, strlen(TESTSTR), nbytes);
106     ABTS_STR_EQUAL(tc, TESTSTR, str);
107 
108     apr_file_close(filetest);
109 }
110 
test_readzero(abts_case * tc,void * data)111 static void test_readzero(abts_case *tc, void *data)
112 {
113     apr_status_t rv;
114     apr_size_t nbytes = 0;
115     char *str = NULL;
116     apr_file_t *filetest;
117 
118     rv = apr_file_open(&filetest, FILENAME, APR_FOPEN_READ, APR_OS_DEFAULT, p);
119     APR_ASSERT_SUCCESS(tc, "Opening test file " FILENAME, rv);
120 
121     rv = apr_file_read(filetest, str, &nbytes);
122     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
123     ABTS_SIZE_EQUAL(tc, 0, nbytes);
124 
125     apr_file_close(filetest);
126 }
127 
test_filename(abts_case * tc,void * data)128 static void test_filename(abts_case *tc, void *data)
129 {
130     const char *str;
131     apr_status_t rv;
132     apr_file_t *filetest = NULL;
133 
134     rv = apr_file_open(&filetest, FILENAME,
135                        APR_FOPEN_READ,
136                        APR_UREAD | APR_UWRITE | APR_GREAD, p);
137     APR_ASSERT_SUCCESS(tc, "Opening test file " FILENAME, rv);
138 
139     rv = apr_file_name_get(&str, filetest);
140     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
141     ABTS_STR_EQUAL(tc, FILENAME, str);
142 
143     apr_file_close(filetest);
144 }
145 
test_fileclose(abts_case * tc,void * data)146 static void test_fileclose(abts_case *tc, void *data)
147 {
148     char str;
149     apr_status_t rv;
150     apr_size_t one = 1;
151     apr_file_t *filetest = NULL;
152 
153     rv = apr_file_open(&filetest, FILENAME,
154                        APR_FOPEN_READ,
155                        APR_UREAD | APR_UWRITE | APR_GREAD, p);
156     APR_ASSERT_SUCCESS(tc, "Opening test file " FILENAME, rv);
157 
158     rv = apr_file_close(filetest);
159     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
160     /* We just closed the file, so this should fail */
161     rv = apr_file_read(filetest, &str, &one);
162     ABTS_INT_EQUAL(tc, 1, APR_STATUS_IS_EBADF(rv));
163 }
164 
test_file_remove(abts_case * tc,void * data)165 static void test_file_remove(abts_case *tc, void *data)
166 {
167     apr_status_t rv;
168     apr_file_t *filetest = NULL;
169 
170     rv = apr_file_remove(FILENAME, p);
171     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
172 
173     rv = apr_file_open(&filetest, FILENAME, APR_FOPEN_READ,
174                        APR_UREAD | APR_UWRITE | APR_GREAD, p);
175     ABTS_INT_EQUAL(tc, 1, APR_STATUS_IS_ENOENT(rv));
176 }
177 
test_open_write(abts_case * tc,void * data)178 static void test_open_write(abts_case *tc, void *data)
179 {
180     apr_status_t rv;
181     apr_file_t *filetest = NULL;
182 
183     filetest = NULL;
184     rv = apr_file_open(&filetest, FILENAME,
185                        APR_FOPEN_WRITE,
186                        APR_UREAD | APR_UWRITE | APR_GREAD, p);
187     ABTS_INT_EQUAL(tc, 1, APR_STATUS_IS_ENOENT(rv));
188     ABTS_PTR_EQUAL(tc, NULL, filetest);
189 }
190 
test_open_writecreate(abts_case * tc,void * data)191 static void test_open_writecreate(abts_case *tc, void *data)
192 {
193     apr_status_t rv;
194     apr_file_t *filetest = NULL;
195 
196     filetest = NULL;
197     rv = apr_file_open(&filetest, FILENAME,
198                        APR_FOPEN_WRITE | APR_FOPEN_CREATE,
199                        APR_UREAD | APR_UWRITE | APR_GREAD, p);
200     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
201 
202     apr_file_close(filetest);
203 }
204 
test_write(abts_case * tc,void * data)205 static void test_write(abts_case *tc, void *data)
206 {
207     apr_status_t rv;
208     apr_size_t bytes = strlen(TESTSTR);
209     apr_file_t *filetest = NULL;
210 
211     rv = apr_file_open(&filetest, FILENAME,
212                        APR_FOPEN_WRITE | APR_FOPEN_CREATE,
213                        APR_UREAD | APR_UWRITE | APR_GREAD, p);
214     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
215 
216     rv = apr_file_write(filetest, TESTSTR, &bytes);
217     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
218 
219     apr_file_close(filetest);
220 }
221 
test_open_readwrite(abts_case * tc,void * data)222 static void test_open_readwrite(abts_case *tc, void *data)
223 {
224     apr_status_t rv;
225     apr_file_t *filetest = NULL;
226 
227     filetest = NULL;
228     rv = apr_file_open(&filetest, FILENAME,
229                        APR_FOPEN_READ | APR_FOPEN_WRITE,
230                        APR_UREAD | APR_UWRITE | APR_GREAD, p);
231     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
232     ABTS_PTR_NOTNULL(tc, filetest);
233 
234     apr_file_close(filetest);
235 }
236 
test_seek(abts_case * tc,void * data)237 static void test_seek(abts_case *tc, void *data)
238 {
239     apr_status_t rv;
240     apr_off_t offset = 5;
241     apr_size_t nbytes = 256;
242     char *str = apr_pcalloc(p, nbytes + 1);
243     apr_file_t *filetest = NULL;
244 
245     rv = apr_file_open(&filetest, FILENAME,
246                        APR_FOPEN_READ,
247                        APR_UREAD | APR_UWRITE | APR_GREAD, p);
248     APR_ASSERT_SUCCESS(tc, "Open test file " FILENAME, rv);
249 
250     rv = apr_file_read(filetest, str, &nbytes);
251     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
252     ABTS_SIZE_EQUAL(tc, strlen(TESTSTR), nbytes);
253     ABTS_STR_EQUAL(tc, TESTSTR, str);
254 
255     memset(str, 0, nbytes + 1);
256 
257     rv = apr_file_seek(filetest, SEEK_SET, &offset);
258     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
259 
260     rv = apr_file_read(filetest, str, &nbytes);
261     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
262     ABTS_SIZE_EQUAL(tc, strlen(TESTSTR) - 5, nbytes);
263     ABTS_STR_EQUAL(tc, TESTSTR + 5, str);
264 
265     apr_file_close(filetest);
266 
267     /* Test for regression of sign error bug with SEEK_END and
268        buffered files. */
269     rv = apr_file_open(&filetest, FILENAME,
270                        APR_FOPEN_READ | APR_FOPEN_BUFFERED,
271                        APR_UREAD | APR_UWRITE | APR_GREAD, p);
272     APR_ASSERT_SUCCESS(tc, "Open test file " FILENAME, rv);
273 
274     offset = -5;
275     rv = apr_file_seek(filetest, SEEK_END, &offset);
276     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
277     ABTS_SIZE_EQUAL(tc, strlen(TESTSTR) - 5, nbytes);
278 
279     memset(str, 0, nbytes + 1);
280     nbytes = 256;
281     rv = apr_file_read(filetest, str, &nbytes);
282     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
283     ABTS_SIZE_EQUAL(tc, 5, nbytes);
284     ABTS_STR_EQUAL(tc, TESTSTR + strlen(TESTSTR) - 5, str);
285 
286     apr_file_close(filetest);
287 }
288 
test_userdata_set(abts_case * tc,void * data)289 static void test_userdata_set(abts_case *tc, void *data)
290 {
291     apr_status_t rv;
292     apr_file_t *filetest = NULL;
293 
294     rv = apr_file_open(&filetest, FILENAME,
295                        APR_FOPEN_WRITE,
296                        APR_UREAD | APR_UWRITE | APR_GREAD, p);
297     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
298 
299     rv = apr_file_data_set(filetest, "This is a test",
300                            "test", apr_pool_cleanup_null);
301     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
302     apr_file_close(filetest);
303 }
304 
test_userdata_get(abts_case * tc,void * data)305 static void test_userdata_get(abts_case *tc, void *data)
306 {
307     apr_status_t rv;
308     void *udata;
309     char *teststr;
310     apr_file_t *filetest = NULL;
311 
312     rv = apr_file_open(&filetest, FILENAME,
313                        APR_FOPEN_WRITE,
314                        APR_UREAD | APR_UWRITE | APR_GREAD, p);
315     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
316 
317     rv = apr_file_data_set(filetest, "This is a test",
318                            "test", apr_pool_cleanup_null);
319     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
320 
321     rv = apr_file_data_get(&udata, "test", filetest);
322     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
323     teststr = udata;
324     ABTS_STR_EQUAL(tc, "This is a test", teststr);
325 
326     apr_file_close(filetest);
327 }
328 
test_userdata_getnokey(abts_case * tc,void * data)329 static void test_userdata_getnokey(abts_case *tc, void *data)
330 {
331     apr_status_t rv;
332     void *teststr;
333     apr_file_t *filetest = NULL;
334 
335     rv = apr_file_open(&filetest, FILENAME,
336                        APR_FOPEN_WRITE,
337                        APR_UREAD | APR_UWRITE | APR_GREAD, p);
338     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
339 
340     rv = apr_file_data_get(&teststr, "nokey", filetest);
341     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
342     ABTS_PTR_EQUAL(tc, NULL, teststr);
343     apr_file_close(filetest);
344 }
345 
test_buffer_set_get(abts_case * tc,void * data)346 static void test_buffer_set_get(abts_case *tc, void *data)
347 {
348     apr_status_t rv;
349     apr_size_t bufsize;
350     apr_file_t *filetest = NULL;
351     char   * buffer;
352 
353     rv = apr_file_open(&filetest, FILENAME,
354                        APR_FOPEN_WRITE | APR_FOPEN_BUFFERED,
355                        APR_UREAD | APR_UWRITE | APR_GREAD, p);
356     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
357 
358     bufsize = apr_file_buffer_size_get(filetest);
359     ABTS_SIZE_EQUAL(tc, APR_BUFFERSIZE, bufsize);
360 
361     buffer = apr_pcalloc(p, 10240);
362     rv = apr_file_buffer_set(filetest, buffer, 10240);
363     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
364 
365     bufsize = apr_file_buffer_size_get(filetest);
366     ABTS_SIZE_EQUAL(tc, 10240, bufsize);
367 
368     rv = apr_file_buffer_set(filetest, buffer, 12);
369     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
370 
371     bufsize = apr_file_buffer_size_get(filetest);
372     ABTS_SIZE_EQUAL(tc, 12, bufsize);
373 
374     apr_file_close(filetest);
375 }
test_getc(abts_case * tc,void * data)376 static void test_getc(abts_case *tc, void *data)
377 {
378     apr_file_t *f = NULL;
379     apr_status_t rv;
380     char ch;
381 
382     rv = apr_file_open(&f, FILENAME, APR_FOPEN_READ, 0, p);
383     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
384 
385     apr_file_getc(&ch, f);
386     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
387     ABTS_INT_EQUAL(tc, (int)TESTSTR[0], (int)ch);
388     apr_file_close(f);
389 }
390 
test_ungetc(abts_case * tc,void * data)391 static void test_ungetc(abts_case *tc, void *data)
392 {
393     apr_file_t *f = NULL;
394     apr_status_t rv;
395     char ch;
396 
397     rv = apr_file_open(&f, FILENAME, APR_FOPEN_READ, 0, p);
398     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
399 
400     apr_file_getc(&ch, f);
401     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
402     ABTS_INT_EQUAL(tc, (int)TESTSTR[0], (int)ch);
403 
404     apr_file_ungetc('X', f);
405     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
406 
407     apr_file_getc(&ch, f);
408     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
409     ABTS_INT_EQUAL(tc, 'X', (int)ch);
410 
411     apr_file_close(f);
412 }
413 
test_gets(abts_case * tc,void * data)414 static void test_gets(abts_case *tc, void *data)
415 {
416     apr_file_t *f = NULL;
417     apr_status_t rv;
418     char *str = apr_palloc(p, 256);
419 
420     rv = apr_file_open(&f, FILENAME, APR_FOPEN_READ, 0, p);
421     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
422 
423     rv = apr_file_gets(str, 256, f);
424     /* Only one line in the test file, so APR will encounter EOF on the first
425      * call to gets, but we should get APR_SUCCESS on this call and
426      * APR_EOF on the next.
427      */
428     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
429     ABTS_STR_EQUAL(tc, TESTSTR, str);
430     rv = apr_file_gets(str, 256, f);
431     ABTS_INT_EQUAL(tc, APR_EOF, rv);
432     ABTS_STR_EQUAL(tc, "", str);
433     apr_file_close(f);
434 }
435 
test_gets_buffered(abts_case * tc,void * data)436 static void test_gets_buffered(abts_case *tc, void *data)
437 {
438     apr_file_t *f = NULL;
439     apr_status_t rv;
440     char *str = apr_palloc(p, 256);
441 
442     /* This will deadlock gets before the r524355 fix. */
443     rv = apr_file_open(&f, FILENAME, APR_FOPEN_READ|APR_FOPEN_BUFFERED|APR_FOPEN_XTHREAD, 0, p);
444     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
445 
446     rv = apr_file_gets(str, 256, f);
447     /* Only one line in the test file, so APR will encounter EOF on the first
448      * call to gets, but we should get APR_SUCCESS on this call and
449      * APR_EOF on the next.
450      */
451     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
452     ABTS_STR_EQUAL(tc, TESTSTR, str);
453     rv = apr_file_gets(str, 256, f);
454     ABTS_INT_EQUAL(tc, APR_EOF, rv);
455     ABTS_STR_EQUAL(tc, "", str);
456     apr_file_close(f);
457 }
458 
test_bigread(abts_case * tc,void * data)459 static void test_bigread(abts_case *tc, void *data)
460 {
461     apr_file_t *f = NULL;
462     apr_status_t rv;
463     char buf[APR_BUFFERSIZE * 2];
464     apr_size_t nbytes;
465 
466     /* Create a test file with known content.
467      */
468     rv = apr_file_open(&f, "data/created_file",
469                        APR_FOPEN_CREATE | APR_FOPEN_WRITE | APR_FOPEN_TRUNCATE,
470                        APR_UREAD | APR_UWRITE, p);
471     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
472 
473     nbytes = APR_BUFFERSIZE;
474     memset(buf, 0xFE, nbytes);
475 
476     rv = apr_file_write(f, buf, &nbytes);
477     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
478     ABTS_SIZE_EQUAL(tc, APR_BUFFERSIZE, nbytes);
479 
480     rv = apr_file_close(f);
481     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
482 
483     f = NULL;
484     rv = apr_file_open(&f, "data/created_file", APR_FOPEN_READ, 0, p);
485     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
486 
487     nbytes = sizeof buf;
488     rv = apr_file_read(f, buf, &nbytes);
489     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
490     ABTS_SIZE_EQUAL(tc, APR_BUFFERSIZE, nbytes);
491 
492     rv = apr_file_close(f);
493     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
494 
495     rv = apr_file_remove("data/created_file", p);
496     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
497 }
498 
499 /* This is a horrible name for this function.  We are testing APR, not how
500  * Apache uses APR.  And, this function tests _way_ too much stuff.
501  */
test_mod_neg(abts_case * tc,void * data)502 static void test_mod_neg(abts_case *tc, void *data)
503 {
504     apr_status_t rv;
505     apr_file_t *f;
506     const char *s;
507     int i;
508     apr_size_t nbytes;
509     char buf[8192];
510     apr_off_t cur;
511     const char *fname = "data/modneg.dat";
512 
513     rv = apr_file_open(&f, fname,
514                        APR_FOPEN_CREATE | APR_FOPEN_WRITE, APR_UREAD | APR_UWRITE, p);
515     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
516 
517     s = "body56789\n";
518     nbytes = strlen(s);
519     rv = apr_file_write(f, s, &nbytes);
520     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
521     ABTS_SIZE_EQUAL(tc, strlen(s), nbytes);
522 
523     for (i = 0; i < 7980; i++) {
524         s = "0";
525         nbytes = strlen(s);
526         rv = apr_file_write(f, s, &nbytes);
527         ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
528         ABTS_SIZE_EQUAL(tc, strlen(s), nbytes);
529     }
530 
531     s = "end456789\n";
532     nbytes = strlen(s);
533     rv = apr_file_write(f, s, &nbytes);
534     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
535     ABTS_SIZE_EQUAL(tc, strlen(s), nbytes);
536 
537     for (i = 0; i < 10000; i++) {
538         s = "1";
539         nbytes = strlen(s);
540         rv = apr_file_write(f, s, &nbytes);
541         ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
542         ABTS_SIZE_EQUAL(tc, strlen(s), nbytes);
543     }
544 
545     rv = apr_file_close(f);
546     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
547 
548     rv = apr_file_open(&f, fname, APR_FOPEN_READ, 0, p);
549     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
550 
551     rv = apr_file_gets(buf, 11, f);
552     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
553     ABTS_STR_EQUAL(tc, "body56789\n", buf);
554 
555     cur = 0;
556     rv = apr_file_seek(f, APR_CUR, &cur);
557     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
558     ABTS_ASSERT(tc, "File Pointer Mismatch, expected 10", cur == 10);
559 
560     nbytes = sizeof(buf);
561     rv = apr_file_read(f, buf, &nbytes);
562     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
563     ABTS_SIZE_EQUAL(tc, nbytes, sizeof(buf));
564 
565     cur = -((apr_off_t)nbytes - 7980);
566     rv = apr_file_seek(f, APR_CUR, &cur);
567     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
568     ABTS_ASSERT(tc, "File Pointer Mismatch, expected 7990", cur == 7990);
569 
570     rv = apr_file_gets(buf, 11, f);
571     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
572     ABTS_STR_EQUAL(tc, "end456789\n", buf);
573 
574     rv = apr_file_close(f);
575     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
576 
577     rv = apr_file_remove(fname, p);
578     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
579 }
580 
581 /* Test that the contents of file FNAME are equal to data EXPECT of
582  * length EXPECTLEN. */
file_contents_equal(abts_case * tc,const char * fname,const void * expect,apr_size_t expectlen)583 static void file_contents_equal(abts_case *tc,
584                                 const char *fname,
585                                 const void *expect,
586                                 apr_size_t expectlen)
587 {
588     void *actual = apr_palloc(p, expectlen);
589     apr_file_t *f;
590 
591     APR_ASSERT_SUCCESS(tc, "open file",
592                        apr_file_open(&f, fname, APR_FOPEN_READ|APR_FOPEN_BUFFERED,
593                                      0, p));
594     APR_ASSERT_SUCCESS(tc, "read from file",
595                        apr_file_read_full(f, actual, expectlen, NULL));
596 
597     ABTS_ASSERT(tc, "matched expected file contents",
598                 memcmp(expect, actual, expectlen) == 0);
599 
600     APR_ASSERT_SUCCESS(tc, "close file", apr_file_close(f));
601 }
602 
603 #define LINE1 "this is a line of text\n"
604 #define LINE2 "this is a second line of text\n"
605 
test_puts(abts_case * tc,void * data)606 static void test_puts(abts_case *tc, void *data)
607 {
608     apr_file_t *f;
609     const char *fname = "data/testputs.txt";
610 
611     APR_ASSERT_SUCCESS(tc, "open file for writing",
612                        apr_file_open(&f, fname,
613                                      APR_FOPEN_WRITE|APR_FOPEN_CREATE|APR_FOPEN_TRUNCATE,
614                                      APR_OS_DEFAULT, p));
615 
616     APR_ASSERT_SUCCESS(tc, "write line to file",
617                        apr_file_puts(LINE1, f));
618     APR_ASSERT_SUCCESS(tc, "write second line to file",
619                        apr_file_puts(LINE2, f));
620 
621     APR_ASSERT_SUCCESS(tc, "close for writing",
622                        apr_file_close(f));
623 
624     file_contents_equal(tc, fname, LINE1 LINE2, strlen(LINE1 LINE2));
625 }
626 
test_writev(abts_case * tc,void * data)627 static void test_writev(abts_case *tc, void *data)
628 {
629     apr_file_t *f;
630     apr_size_t nbytes;
631     struct iovec vec[5];
632     const char *fname = "data/testwritev.txt";
633 
634     APR_ASSERT_SUCCESS(tc, "open file for writing",
635                        apr_file_open(&f, fname,
636                                      APR_FOPEN_WRITE|APR_FOPEN_CREATE|APR_FOPEN_TRUNCATE,
637                                      APR_OS_DEFAULT, p));
638 
639     vec[0].iov_base = LINE1;
640     vec[0].iov_len = strlen(LINE1);
641 
642     APR_ASSERT_SUCCESS(tc, "writev of size 1 to file",
643                        apr_file_writev(f, vec, 1, &nbytes));
644 
645     file_contents_equal(tc, fname, LINE1, strlen(LINE1));
646 
647     vec[0].iov_base = LINE1;
648     vec[0].iov_len = strlen(LINE1);
649     vec[1].iov_base = LINE2;
650     vec[1].iov_len = strlen(LINE2);
651     vec[2].iov_base = LINE1;
652     vec[2].iov_len = strlen(LINE1);
653     vec[3].iov_base = LINE1;
654     vec[3].iov_len = strlen(LINE1);
655     vec[4].iov_base = LINE2;
656     vec[4].iov_len = strlen(LINE2);
657 
658     APR_ASSERT_SUCCESS(tc, "writev of size 5 to file",
659                        apr_file_writev(f, vec, 5, &nbytes));
660 
661     APR_ASSERT_SUCCESS(tc, "close for writing",
662                        apr_file_close(f));
663 
664     file_contents_equal(tc, fname, LINE1 LINE1 LINE2 LINE1 LINE1 LINE2,
665                         strlen(LINE1)*4 + strlen(LINE2)*2);
666 
667 }
668 
test_writev_full(abts_case * tc,void * data)669 static void test_writev_full(abts_case *tc, void *data)
670 {
671     apr_file_t *f;
672     apr_size_t nbytes;
673     struct iovec vec[5];
674     const char *fname = "data/testwritev_full.txt";
675 
676     APR_ASSERT_SUCCESS(tc, "open file for writing",
677                        apr_file_open(&f, fname,
678                                      APR_FOPEN_WRITE|APR_FOPEN_CREATE|APR_FOPEN_TRUNCATE,
679                                      APR_OS_DEFAULT, p));
680 
681     vec[0].iov_base = LINE1;
682     vec[0].iov_len = strlen(LINE1);
683     vec[1].iov_base = LINE2;
684     vec[1].iov_len = strlen(LINE2);
685     vec[2].iov_base = LINE1;
686     vec[2].iov_len = strlen(LINE1);
687     vec[3].iov_base = LINE1;
688     vec[3].iov_len = strlen(LINE1);
689     vec[4].iov_base = LINE2;
690     vec[4].iov_len = strlen(LINE2);
691 
692     APR_ASSERT_SUCCESS(tc, "writev_full of size 5 to file",
693                        apr_file_writev_full(f, vec, 5, &nbytes));
694 
695     ABTS_SIZE_EQUAL(tc, strlen(LINE1)*3 + strlen(LINE2)*2, nbytes);
696 
697     APR_ASSERT_SUCCESS(tc, "close for writing",
698                        apr_file_close(f));
699 
700     file_contents_equal(tc, fname, LINE1 LINE2 LINE1 LINE1 LINE2,
701                         strlen(LINE1)*3 + strlen(LINE2)*2);
702 
703 }
704 
test_writev_buffered(abts_case * tc,void * data)705 static void test_writev_buffered(abts_case *tc, void *data)
706 {
707     apr_file_t *f;
708     apr_size_t nbytes;
709     struct iovec vec[2];
710     const char *fname = "data/testwritev_buffered.dat";
711 
712     APR_ASSERT_SUCCESS(tc, "open file for writing",
713                        apr_file_open(&f, fname,
714                                      APR_FOPEN_WRITE | APR_FOPEN_CREATE | APR_FOPEN_TRUNCATE |
715                                      APR_FOPEN_BUFFERED, APR_OS_DEFAULT, p));
716 
717     nbytes = strlen(TESTSTR);
718     APR_ASSERT_SUCCESS(tc, "buffered write",
719                        apr_file_write(f, TESTSTR, &nbytes));
720 
721     vec[0].iov_base = LINE1;
722     vec[0].iov_len = strlen(LINE1);
723     vec[1].iov_base = LINE2;
724     vec[1].iov_len = strlen(LINE2);
725 
726     APR_ASSERT_SUCCESS(tc, "writev of size 2 to file",
727                        apr_file_writev(f, vec, 2, &nbytes));
728 
729     APR_ASSERT_SUCCESS(tc, "close for writing",
730                        apr_file_close(f));
731 
732     file_contents_equal(tc, fname, TESTSTR LINE1 LINE2,
733                         strlen(TESTSTR) + strlen(LINE1) + strlen(LINE2));
734 }
735 
test_writev_buffered_seek(abts_case * tc,void * data)736 static void test_writev_buffered_seek(abts_case *tc, void *data)
737 {
738     apr_file_t *f;
739     apr_status_t rv;
740     apr_off_t off = 0;
741     struct iovec vec[3];
742     apr_size_t nbytes = strlen(TESTSTR);
743     char *str = apr_pcalloc(p, nbytes+1);
744     const char *fname = "data/testwritev_buffered.dat";
745 
746     APR_ASSERT_SUCCESS(tc, "open file for writing",
747                        apr_file_open(&f, fname,
748                                      APR_FOPEN_WRITE | APR_FOPEN_READ | APR_FOPEN_BUFFERED,
749                                      APR_OS_DEFAULT, p));
750 
751     rv = apr_file_read(f, str, &nbytes);
752     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
753     ABTS_STR_EQUAL(tc, TESTSTR, str);
754     APR_ASSERT_SUCCESS(tc, "buffered seek", apr_file_seek(f, APR_SET, &off));
755 
756     vec[0].iov_base = LINE1;
757     vec[0].iov_len = strlen(LINE1);
758     vec[1].iov_base = LINE2;
759     vec[1].iov_len = strlen(LINE2);
760     vec[2].iov_base = TESTSTR;
761     vec[2].iov_len = strlen(TESTSTR);
762 
763     APR_ASSERT_SUCCESS(tc, "writev of size 2 to file",
764                        apr_file_writev(f, vec, 3, &nbytes));
765 
766     APR_ASSERT_SUCCESS(tc, "close for writing",
767                        apr_file_close(f));
768 
769     file_contents_equal(tc, fname, LINE1 LINE2 TESTSTR,
770                         strlen(LINE1) + strlen(LINE2) + strlen(TESTSTR));
771 
772     APR_ASSERT_SUCCESS(tc, "remove file", apr_file_remove(fname, p));
773 }
774 
test_truncate(abts_case * tc,void * data)775 static void test_truncate(abts_case *tc, void *data)
776 {
777     apr_status_t rv;
778     apr_file_t *f;
779     const char *fname = "data/testtruncate.dat";
780     const char *s;
781     apr_size_t nbytes;
782     apr_finfo_t finfo;
783 
784     apr_file_remove(fname, p);
785 
786     rv = apr_file_open(&f, fname,
787                        APR_FOPEN_CREATE | APR_FOPEN_WRITE, APR_UREAD | APR_UWRITE, p);
788     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
789 
790     s = "some data";
791     nbytes = strlen(s);
792     rv = apr_file_write(f, s, &nbytes);
793     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
794     ABTS_SIZE_EQUAL(tc, strlen(s), nbytes);
795 
796     rv = apr_file_close(f);
797     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
798 
799     rv = apr_file_open(&f, fname,
800                        APR_FOPEN_TRUNCATE | APR_FOPEN_WRITE, APR_UREAD | APR_UWRITE, p);
801     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
802 
803     rv = apr_file_close(f);
804     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
805 
806     rv = apr_stat(&finfo, fname, APR_FINFO_SIZE, p);
807     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
808     ABTS_ASSERT(tc, "File size mismatch, expected 0 (empty)", finfo.size == 0);
809 
810     rv = apr_file_remove(fname, p);
811     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
812 }
813 
test_bigfprintf(abts_case * tc,void * data)814 static void test_bigfprintf(abts_case *tc, void *data)
815 {
816     apr_file_t *f;
817     const char *fname = "data/testbigfprintf.dat";
818     char *to_write;
819     int i;
820 
821     apr_file_remove(fname, p);
822 
823     APR_ASSERT_SUCCESS(tc, "open test file",
824                        apr_file_open(&f, fname,
825                                      APR_FOPEN_CREATE|APR_FOPEN_WRITE,
826                                      APR_UREAD|APR_UWRITE, p));
827 
828 
829     to_write = malloc(HUGE_STRING_LEN + 3);
830 
831     for (i = 0; i < HUGE_STRING_LEN + 1; ++i)
832         to_write[i] = 'A' + i%26;
833 
834     strcpy(to_write + HUGE_STRING_LEN, "42");
835 
836     i = apr_file_printf(f, "%s", to_write);
837     ABTS_INT_EQUAL(tc, HUGE_STRING_LEN + 2, i);
838 
839     apr_file_close(f);
840 
841     file_contents_equal(tc, fname, to_write, HUGE_STRING_LEN + 2);
842 
843     free(to_write);
844 }
845 
test_fail_write_flush(abts_case * tc,void * data)846 static void test_fail_write_flush(abts_case *tc, void *data)
847 {
848     apr_file_t *f;
849     const char *fname = "data/testflush.dat";
850     apr_status_t rv;
851     char buf[APR_BUFFERSIZE];
852     int n;
853 
854     apr_file_remove(fname, p);
855 
856     APR_ASSERT_SUCCESS(tc, "open test file",
857                        apr_file_open(&f, fname,
858                                      APR_FOPEN_CREATE|APR_FOPEN_READ|APR_FOPEN_BUFFERED,
859                                      APR_UREAD|APR_UWRITE, p));
860 
861     memset(buf, 'A', sizeof buf);
862 
863     /* Try three writes.  One of these should fail when it exceeds the
864      * internal buffer and actually tries to write to the file, which
865      * was opened read-only and hence should be unwritable. */
866     for (n = 0, rv = APR_SUCCESS; n < 4 && rv == APR_SUCCESS; n++) {
867         apr_size_t bytes = sizeof buf;
868         rv = apr_file_write(f, buf, &bytes);
869     }
870 
871     ABTS_ASSERT(tc, "failed to write to read-only buffered fd",
872                 rv != APR_SUCCESS);
873 
874     apr_file_close(f);
875 }
876 
test_fail_read_flush(abts_case * tc,void * data)877 static void test_fail_read_flush(abts_case *tc, void *data)
878 {
879     apr_file_t *f;
880     const char *fname = "data/testflush.dat";
881     apr_status_t rv;
882     char buf[2];
883 
884     apr_file_remove(fname, p);
885 
886     APR_ASSERT_SUCCESS(tc, "open test file",
887                        apr_file_open(&f, fname,
888                                      APR_FOPEN_CREATE|APR_FOPEN_READ|APR_FOPEN_BUFFERED,
889                                      APR_UREAD|APR_UWRITE, p));
890 
891     /* this write should be buffered. */
892     APR_ASSERT_SUCCESS(tc, "buffered write should succeed",
893                        apr_file_puts("hello", f));
894 
895     /* Now, trying a read should fail since the write must be flushed,
896      * and should fail with something other than EOF since the file is
897      * opened read-only. */
898     rv = apr_file_read_full(f, buf, 2, NULL);
899 
900     ABTS_ASSERT(tc, "read should flush buffered write and fail",
901                 rv != APR_SUCCESS && rv != APR_EOF);
902 
903     /* Likewise for gets */
904     rv = apr_file_gets(buf, 2, f);
905 
906     ABTS_ASSERT(tc, "gets should flush buffered write and fail",
907                 rv != APR_SUCCESS && rv != APR_EOF);
908 
909     /* Likewise for seek. */
910     {
911         apr_off_t offset = 0;
912 
913         rv = apr_file_seek(f, APR_SET, &offset);
914     }
915 
916     ABTS_ASSERT(tc, "seek should flush buffered write and fail",
917                 rv != APR_SUCCESS && rv != APR_EOF);
918 
919     apr_file_close(f);
920 }
921 
test_xthread(abts_case * tc,void * data)922 static void test_xthread(abts_case *tc, void *data)
923 {
924     apr_file_t *f;
925     const char *fname = "data/testxthread.dat";
926     apr_status_t rv;
927     apr_int32_t flags = APR_FOPEN_CREATE|APR_FOPEN_READ|APR_FOPEN_WRITE|APR_FOPEN_APPEND|APR_FOPEN_XTHREAD;
928     char buf[128] = { 0 };
929 
930     /* Test for bug 38438, opening file with append + xthread and seeking to
931        the end of the file resulted in writes going to the beginning not the
932        end. */
933 
934     apr_file_remove(fname, p);
935 
936     APR_ASSERT_SUCCESS(tc, "open test file",
937                        apr_file_open(&f, fname, flags,
938                                      APR_UREAD|APR_UWRITE, p));
939 
940     APR_ASSERT_SUCCESS(tc, "write should succeed",
941                        apr_file_puts("hello", f));
942 
943     apr_file_close(f);
944 
945     APR_ASSERT_SUCCESS(tc, "open test file",
946                        apr_file_open(&f, fname, flags,
947                                      APR_UREAD|APR_UWRITE, p));
948 
949     /* Seek to the end. */
950     {
951         apr_off_t offset = 0;
952 
953         rv = apr_file_seek(f, APR_END, &offset);
954         ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
955     }
956 
957     APR_ASSERT_SUCCESS(tc, "more writes should succeed",
958                        apr_file_puts("world", f));
959 
960     /* Back to the beginning. */
961     {
962         apr_off_t offset = 0;
963 
964         rv = apr_file_seek(f, APR_SET, &offset);
965         ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
966     }
967 
968     apr_file_read_full(f, buf, sizeof(buf), NULL);
969 
970     ABTS_STR_EQUAL(tc, "helloworld", buf);
971 
972     apr_file_close(f);
973 }
974 
testfile(abts_suite * suite)975 abts_suite *testfile(abts_suite *suite)
976 {
977     suite = ADD_SUITE(suite)
978 
979     abts_run_test(suite, test_open_noreadwrite, NULL);
980     abts_run_test(suite, test_open_excl, NULL);
981     abts_run_test(suite, test_open_read, NULL);
982     abts_run_test(suite, test_open_readwrite, NULL);
983     abts_run_test(suite, link_existing, NULL);
984     abts_run_test(suite, link_nonexisting, NULL);
985     abts_run_test(suite, test_read, NULL);
986     abts_run_test(suite, test_readzero, NULL);
987     abts_run_test(suite, test_seek, NULL);
988     abts_run_test(suite, test_filename, NULL);
989     abts_run_test(suite, test_fileclose, NULL);
990     abts_run_test(suite, test_file_remove, NULL);
991     abts_run_test(suite, test_open_write, NULL);
992     abts_run_test(suite, test_open_writecreate, NULL);
993     abts_run_test(suite, test_write, NULL);
994     abts_run_test(suite, test_userdata_set, NULL);
995     abts_run_test(suite, test_userdata_get, NULL);
996     abts_run_test(suite, test_userdata_getnokey, NULL);
997     abts_run_test(suite, test_getc, NULL);
998     abts_run_test(suite, test_ungetc, NULL);
999     abts_run_test(suite, test_gets, NULL);
1000     abts_run_test(suite, test_gets_buffered, NULL);
1001     abts_run_test(suite, test_puts, NULL);
1002     abts_run_test(suite, test_writev, NULL);
1003     abts_run_test(suite, test_writev_full, NULL);
1004     abts_run_test(suite, test_writev_buffered, NULL);
1005     abts_run_test(suite, test_writev_buffered_seek, NULL);
1006     abts_run_test(suite, test_bigread, NULL);
1007     abts_run_test(suite, test_mod_neg, NULL);
1008     abts_run_test(suite, test_truncate, NULL);
1009     abts_run_test(suite, test_bigfprintf, NULL);
1010     abts_run_test(suite, test_fail_write_flush, NULL);
1011     abts_run_test(suite, test_fail_read_flush, NULL);
1012     abts_run_test(suite, test_buffer_set_get, NULL);
1013     abts_run_test(suite, test_xthread, NULL);
1014 
1015     return suite;
1016 }
1017 
1018