123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263 |
- /* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- #include "fspr_file_io.h"
- #include "fspr_file_info.h"
- #include "fspr_strings.h"
- #include "fspr_errno.h"
- #include "fspr_general.h"
- #include "fspr_poll.h"
- #include "fspr_lib.h"
- #include "testutil.h"
- #define FILENAME "data/file_datafile.txt"
- #define NEWFILENAME "data/new_datafile.txt"
- #define NEWFILEDATA "This is new text in a new file."
- static const struct view_fileinfo
- {
- fspr_int32_t bits;
- char *description;
- } vfi[] = {
- {APR_FINFO_MTIME, "MTIME"},
- {APR_FINFO_CTIME, "CTIME"},
- {APR_FINFO_ATIME, "ATIME"},
- {APR_FINFO_SIZE, "SIZE"},
- {APR_FINFO_DEV, "DEV"},
- {APR_FINFO_INODE, "INODE"},
- {APR_FINFO_NLINK, "NLINK"},
- {APR_FINFO_TYPE, "TYPE"},
- {APR_FINFO_USER, "USER"},
- {APR_FINFO_GROUP, "GROUP"},
- {APR_FINFO_UPROT, "UPROT"},
- {APR_FINFO_GPROT, "GPROT"},
- {APR_FINFO_WPROT, "WPROT"},
- {0, NULL}
- };
- static void finfo_equal(abts_case *tc, fspr_finfo_t *f1, fspr_finfo_t *f2)
- {
- /* Minimum supported flags across all platforms (APR_FINFO_MIN) */
- ABTS_ASSERT(tc, "fspr_stat and fspr_getfileinfo must return APR_FINFO_TYPE",
- (f1->valid & f2->valid & APR_FINFO_TYPE));
- ABTS_ASSERT(tc, "fspr_stat and fspr_getfileinfo differ in filetype",
- f1->filetype == f2->filetype);
- ABTS_ASSERT(tc, "fspr_stat and fspr_getfileinfo must return APR_FINFO_SIZE",
- (f1->valid & f2->valid & APR_FINFO_SIZE));
- ABTS_ASSERT(tc, "fspr_stat and fspr_getfileinfo differ in size",
- f1->size == f2->size);
- ABTS_ASSERT(tc, "fspr_stat and fspr_getfileinfo must return APR_FINFO_ATIME",
- (f1->valid & f2->valid & APR_FINFO_ATIME));
- ABTS_ASSERT(tc, "fspr_stat and fspr_getfileinfo differ in atime",
- f1->atime == f2->atime);
- ABTS_ASSERT(tc, "fspr_stat and fspr_getfileinfo must return APR_FINFO_MTIME",
- (f1->valid & f2->valid & APR_FINFO_MTIME));
- ABTS_ASSERT(tc, "fspr_stat and fspr_getfileinfo differ in mtime",
- f1->mtime == f2->mtime);
- ABTS_ASSERT(tc, "fspr_stat and fspr_getfileinfo must return APR_FINFO_CTIME",
- (f1->valid & f2->valid & APR_FINFO_CTIME));
- ABTS_ASSERT(tc, "fspr_stat and fspr_getfileinfo differ in ctime",
- f1->ctime == f2->ctime);
- if (f1->valid & f2->valid & APR_FINFO_NAME)
- ABTS_ASSERT(tc, "fspr_stat and fspr_getfileinfo differ in name",
- !strcmp(f1->name, f2->name));
- if (f1->fname && f2->fname)
- ABTS_ASSERT(tc, "fspr_stat and fspr_getfileinfo differ in fname",
- !strcmp(f1->fname, f2->fname));
- /* Additional supported flags not supported on all platforms */
- if (f1->valid & f2->valid & APR_FINFO_USER)
- ABTS_ASSERT(tc, "fspr_stat and fspr_getfileinfo differ in user",
- !fspr_uid_compare(f1->user, f2->user));
- if (f1->valid & f2->valid & APR_FINFO_GROUP)
- ABTS_ASSERT(tc, "fspr_stat and fspr_getfileinfo differ in group",
- !fspr_gid_compare(f1->group, f2->group));
- if (f1->valid & f2->valid & APR_FINFO_INODE)
- ABTS_ASSERT(tc, "fspr_stat and fspr_getfileinfo differ in inode",
- f1->inode == f2->inode);
- if (f1->valid & f2->valid & APR_FINFO_DEV)
- ABTS_ASSERT(tc, "fspr_stat and fspr_getfileinfo differ in device",
- f1->device == f2->device);
- if (f1->valid & f2->valid & APR_FINFO_NLINK)
- ABTS_ASSERT(tc, "fspr_stat and fspr_getfileinfo differ in nlink",
- f1->nlink == f2->nlink);
- if (f1->valid & f2->valid & APR_FINFO_CSIZE)
- ABTS_ASSERT(tc, "fspr_stat and fspr_getfileinfo differ in csize",
- f1->csize == f2->csize);
- if (f1->valid & f2->valid & APR_FINFO_PROT)
- ABTS_ASSERT(tc, "fspr_stat and fspr_getfileinfo differ in protection",
- f1->protection == f2->protection);
- }
- static void test_info_get(abts_case *tc, void *data)
- {
- fspr_file_t *thefile;
- fspr_finfo_t finfo;
- fspr_status_t rv;
- rv = fspr_file_open(&thefile, FILENAME, APR_READ, APR_OS_DEFAULT, p);
- ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
- rv = fspr_file_info_get(&finfo, APR_FINFO_NORM, thefile);
- if (rv == APR_INCOMPLETE) {
- char *str;
- int i;
- str = fspr_pstrdup(p, "APR_INCOMPLETE: Missing ");
- for (i = 0; vfi[i].bits; ++i) {
- if (vfi[i].bits & ~finfo.valid) {
- str = fspr_pstrcat(p, str, vfi[i].description, " ", NULL);
- }
- }
- ABTS_FAIL(tc, str);
- }
- ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
- fspr_file_close(thefile);
- }
- static void test_stat(abts_case *tc, void *data)
- {
- fspr_finfo_t finfo;
- fspr_status_t rv;
- rv = fspr_stat(&finfo, FILENAME, APR_FINFO_NORM, p);
- if (rv == APR_INCOMPLETE) {
- char *str;
- int i;
- str = fspr_pstrdup(p, "APR_INCOMPLETE: Missing ");
- for (i = 0; vfi[i].bits; ++i) {
- if (vfi[i].bits & ~finfo.valid) {
- str = fspr_pstrcat(p, str, vfi[i].description, " ", NULL);
- }
- }
- ABTS_FAIL(tc, str);
- }
- ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
- }
- static void test_stat_eq_finfo(abts_case *tc, void *data)
- {
- fspr_file_t *thefile;
- fspr_finfo_t finfo;
- fspr_finfo_t stat_finfo;
- fspr_status_t rv;
- rv = fspr_file_open(&thefile, FILENAME, APR_READ, APR_OS_DEFAULT, p);
- ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
- rv = fspr_file_info_get(&finfo, APR_FINFO_NORM, thefile);
- /* Opening the file may have toggled the atime member (time last
- * accessed), so fetch our fspr_stat() after getting the fileinfo
- * of the open file...
- */
- rv = fspr_stat(&stat_finfo, FILENAME, APR_FINFO_NORM, p);
- ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
- fspr_file_close(thefile);
- finfo_equal(tc, &stat_finfo, &finfo);
- }
- static void test_buffered_write_size(abts_case *tc, void *data)
- {
- const fspr_size_t data_len = strlen(NEWFILEDATA);
- fspr_file_t *thefile;
- fspr_finfo_t finfo;
- fspr_status_t rv;
- fspr_size_t bytes;
- rv = fspr_file_open(&thefile, NEWFILENAME,
- APR_READ | APR_WRITE | APR_CREATE | APR_TRUNCATE
- | APR_BUFFERED | APR_DELONCLOSE,
- APR_OS_DEFAULT, p);
- APR_ASSERT_SUCCESS(tc, "open file", rv);
- /* A funny thing happened to me the other day: I wrote something
- * into a buffered file, then asked for its size using
- * fspr_file_info_get; and guess what? The size was 0! That's not a
- * nice way to behave.
- */
- bytes = data_len;
- rv = fspr_file_write(thefile, NEWFILEDATA, &bytes);
- APR_ASSERT_SUCCESS(tc, "write file contents", rv);
- ABTS_TRUE(tc, data_len == bytes);
- rv = fspr_file_info_get(&finfo, APR_FINFO_SIZE, thefile);
- APR_ASSERT_SUCCESS(tc, "get file size", rv);
- ABTS_TRUE(tc, bytes == (fspr_size_t) finfo.size);
- fspr_file_close(thefile);
- }
- static void test_mtime_set(abts_case *tc, void *data)
- {
- fspr_file_t *thefile;
- fspr_finfo_t finfo;
- fspr_time_t epoch = 0;
- fspr_status_t rv;
- /* This test sort of depends on the system clock being at least
- * marginally ccorrect; We'll be setting the modification time to
- * the epoch.
- */
- rv = fspr_file_open(&thefile, NEWFILENAME,
- APR_READ | APR_WRITE | APR_CREATE | APR_TRUNCATE
- | APR_BUFFERED | APR_DELONCLOSE,
- APR_OS_DEFAULT, p);
- APR_ASSERT_SUCCESS(tc, "open file", rv);
- /* Check that the current mtime is not the epoch */
- rv = fspr_stat(&finfo, NEWFILENAME, APR_FINFO_MTIME, p);
- if (rv == APR_INCOMPLETE) {
- char *str;
- int i;
- str = fspr_pstrdup(p, "APR_INCOMPLETE: Missing ");
- for (i = 0; vfi[i].bits; ++i) {
- if (vfi[i].bits & ~finfo.valid) {
- str = fspr_pstrcat(p, str, vfi[i].description, " ", NULL);
- }
- }
- ABTS_FAIL(tc, str);
- }
- APR_ASSERT_SUCCESS(tc, "get initial mtime", rv);
- ABTS_TRUE(tc, finfo.mtime != epoch);
- /* Reset the mtime to the epoch and verify the result.
- * Note: we blindly assume that if the first fspr_stat succeeded,
- * the second one will, too.
- */
- rv = fspr_file_mtime_set(NEWFILENAME, epoch, p);
- APR_ASSERT_SUCCESS(tc, "set mtime", rv);
- rv = fspr_stat(&finfo, NEWFILENAME, APR_FINFO_MTIME, p);
- APR_ASSERT_SUCCESS(tc, "get modified mtime", rv);
- ABTS_TRUE(tc, finfo.mtime == epoch);
- fspr_file_close(thefile);
- }
- abts_suite *testfileinfo(abts_suite *suite)
- {
- suite = ADD_SUITE(suite)
- abts_run_test(suite, test_info_get, NULL);
- abts_run_test(suite, test_stat, NULL);
- abts_run_test(suite, test_stat_eq_finfo, NULL);
- abts_run_test(suite, test_buffered_write_size, NULL);
- abts_run_test(suite, test_mtime_set, NULL);
- return suite;
- }
|