diff options
author | sussman <sussman@13f79535-47bb-0310-9956-ffa450edef68> | 2003-07-07 22:44:11 +0000 |
---|---|---|
committer | sussman <sussman@13f79535-47bb-0310-9956-ffa450edef68> | 2003-07-07 22:44:11 +0000 |
commit | df9731f421df4af8b8d92c77099f07aa5d23e36f (patch) | |
tree | 0d3235b1a02a9f4302a6dadb0295b2fbad504658 | |
parent | 8a3a3508e97ae81cb07a9d8b943ca7aafedb5a85 (diff) | |
download | libapr-df9731f421df4af8b8d92c77099f07aa5d23e36f.tar.gz |
New apr_file_mtime_set() API, implemented in unix and win32.
Patches from Branko Cibej (brane) and Matt Kraai <kraai@alumni.cmu.edu>.
* include/apr_file_io.h (apr_file_mtime_set): declare.
* include/arch/win32/apr_arch_file_io.h: expand apr_file_open
internal flags; add new APR_WRITEATTRS value.
* file_io/win32/open.c (apr_file_open): honor APR_WRITEATTRS flag.
* file_io/win32/filestat.c (apr_file_mtime_set): implement in win32.
* file_io/unix/filestat.c (apr_file_mtime_set): implement in unix.
* test/testfileinfo.c (test_mtime_set): new API test.
git-svn-id: http://svn.apache.org/repos/asf/apr/apr/trunk@64563 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r-- | file_io/unix/filestat.c | 26 | ||||
-rw-r--r-- | file_io/win32/filestat.c | 34 | ||||
-rw-r--r-- | file_io/win32/open.c | 5 | ||||
-rw-r--r-- | include/apr_file_io.h | 12 | ||||
-rw-r--r-- | include/arch/win32/apr_arch_file_io.h | 9 | ||||
-rw-r--r-- | test/testfileinfo.c | 48 |
6 files changed, 129 insertions, 5 deletions
diff --git a/file_io/unix/filestat.c b/file_io/unix/filestat.c index 02a4df975..08646f109 100644 --- a/file_io/unix/filestat.c +++ b/file_io/unix/filestat.c @@ -213,6 +213,32 @@ APR_DECLARE(apr_status_t) apr_file_attrs_set(const char *fname, return apr_file_perms_set(fname, finfo.protection); } + +APR_DECLARE(apr_status_t) apr_file_mtime_set(const char *fname, + apr_time_t mtime, + apr_pool_t *pool) +{ + apr_status_t status; + apr_finfo_t finfo; + struct timeval tvp[2]; + + status = apr_stat(&finfo, fname, APR_FINFO_ATIME, pool); + if (!APR_STATUS_IS_SUCCESS(status)) { + return status; + } + + tvp[0].tv_sec = apr_time_sec(finfo.atime); + tvp[0].tv_usec = apr_time_usec(finfo.atime); + tvp[1].tv_sec = apr_time_sec(mtime); + tvp[1].tv_usec = apr_time_usec(mtime); + + if (utimes(fname, tvp) == -1) { + return errno; + } + return APR_SUCCESS; +} + + APR_DECLARE(apr_status_t) apr_stat(apr_finfo_t *finfo, const char *fname, apr_int32_t wanted, apr_pool_t *pool) diff --git a/file_io/win32/filestat.c b/file_io/win32/filestat.c index 91a7fc07a..56217c70d 100644 --- a/file_io/win32/filestat.c +++ b/file_io/win32/filestat.c @@ -762,3 +762,37 @@ APR_DECLARE(apr_status_t) apr_file_attrs_set(const char *fname, return APR_SUCCESS; } + + +APR_DECLARE(apr_status_t) apr_file_mtime_set(const char *fname, + apr_time_t mtime, + apr_pool_t *pool) +{ + apr_file_t *thefile; + apr_status_t rv; + + rv = apr_file_open(&thefile, fname, + APR_READ | APR_WRITEATTRS, + APR_OS_DEFAULT, pool); + if (!rv) + { + FILETIME file_ctime; + FILETIME file_atime; + FILETIME file_mtime; + + if (!GetFileTime(thefile->filehand, + &file_ctime, &file_atime, &file_mtime)) + rv = apr_get_os_error(); + else + { + AprTimeToFileTime(&file_mtime, mtime); + if (!SetFileTime(thefile->filehand, + &file_ctime, &file_atime, &file_mtime)) + rv = apr_get_os_error(); + } + + apr_file_close(thefile); + } + + return rv; +} diff --git a/file_io/win32/open.c b/file_io/win32/open.c index 2d59ee423..550206b88 100644 --- a/file_io/win32/open.c +++ b/file_io/win32/open.c @@ -309,7 +309,10 @@ APR_DECLARE(apr_status_t) apr_file_open(apr_file_t **new, const char *fname, if (flag & APR_WRITE) { oflags |= GENERIC_WRITE; } - + if (flag & APR_WRITEATTRS) { + oflags |= FILE_WRITE_ATTRIBUTES; + } + if (apr_os_level >= APR_WIN_NT) sharemode |= FILE_SHARE_DELETE; diff --git a/include/apr_file_io.h b/include/apr_file_io.h index 8ff621176..3d9e40413 100644 --- a/include/apr_file_io.h +++ b/include/apr_file_io.h @@ -657,6 +657,18 @@ APR_DECLARE(apr_status_t) apr_file_attrs_set(const char *fname, apr_pool_t *cont); /** + * Set the mtime of the specified file. + * @param fname The full path to the file (using / on all systems) + * @param mtime The mtime to apply to the file. + * @param pool The pool to use. + * @warning Platforms which do not implement this feature will return + * APR_ENOTIMPL. + */ +APR_DECLARE(apr_status_t) apr_file_mtime_set(const char *fname, + apr_time_t mtime, + apr_pool_t *pool); + +/** * Create a new directory on the file system. * @param path the path for the directory to be created. (use / on all systems) * @param perm Permissions for the new direcoty. diff --git a/include/arch/win32/apr_arch_file_io.h b/include/arch/win32/apr_arch_file_io.h index 06e6e091c..30e863a83 100644 --- a/include/arch/win32/apr_arch_file_io.h +++ b/include/arch/win32/apr_arch_file_io.h @@ -133,10 +133,11 @@ void *res_name_from_filename(const char *file, int global, apr_pool_t *pool); #endif /* Internal Flags for apr_file_open */ -#define APR_OPENINFO 0x4000 /* Open without READ or WRITE access */ -#define APR_OPENLINK 0x2000 /* Open a link itself, if supported */ -#define APR_READCONTROL 0x1000 /* Read the file's owner/perms */ -#define APR_WRITECONTROL 0x0800 /* Modifythe file's owner/perms */ +#define APR_OPENINFO 0x00100000 /* Open without READ or WRITE access */ +#define APR_OPENLINK 0x00200000 /* Open a link itself, if supported */ +#define APR_READCONTROL 0x00400000 /* Read the file's owner/perms */ +#define APR_WRITECONTROL 0x00800000 /* Modifythe file's owner/perms */ +#define APR_WRITEATTRS 0x01000000 /* Modify the file's attributes */ /* Entries missing from the MSVC 5.0 Win32 SDK: */ diff --git a/test/testfileinfo.c b/test/testfileinfo.c index a788193fb..3a7073b53 100644 --- a/test/testfileinfo.c +++ b/test/testfileinfo.c @@ -239,6 +239,53 @@ static void test_buffered_write_size(CuTest *tc) apr_file_close(thefile); } +static void test_mtime_set(CuTest *tc) +{ + apr_file_t *thefile; + apr_finfo_t finfo; + apr_time_t epoch = 0; + apr_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 = apr_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 = apr_stat(&finfo, NEWFILENAME, APR_FINFO_MTIME, p); + if (rv == APR_INCOMPLETE) { + char *str; + int i; + str = apr_pstrdup(p, "APR_INCOMPLETE: Missing "); + for (i = 0; vfi[i].bits; ++i) { + if (vfi[i].bits & ~finfo.valid) { + str = apr_pstrcat(p, str, vfi[i].description, " ", NULL); + } + } + CuFail(tc, str); + } + apr_assert_success(tc, "get initial mtime", rv); + CuAssertTrue(tc, finfo.mtime != epoch); + + /* Reset the mtime to the epoch and verify the result. + * Note: we blindly assume that if the first apr_stat succeeded, + * the second one will, too. + */ + rv = apr_file_mtime_set(NEWFILENAME, epoch, p); + apr_assert_success(tc, "set mtime", rv); + + rv = apr_stat(&finfo, NEWFILENAME, APR_FINFO_MTIME, p); + apr_assert_success(tc, "get modified mtime", rv); + CuAssertTrue(tc, finfo.mtime == epoch); + + apr_file_close(thefile); +} + CuSuite *testfileinfo(void) { CuSuite *suite = CuSuiteNew("File Info"); @@ -247,6 +294,7 @@ CuSuite *testfileinfo(void) SUITE_ADD_TEST(suite, test_stat); SUITE_ADD_TEST(suite, test_stat_eq_finfo); SUITE_ADD_TEST(suite, test_buffered_write_size); + SUITE_ADD_TEST(suite, test_mtime_set); return suite; } |