summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsussman <sussman@13f79535-47bb-0310-9956-ffa450edef68>2003-07-07 22:44:11 +0000
committersussman <sussman@13f79535-47bb-0310-9956-ffa450edef68>2003-07-07 22:44:11 +0000
commitdf9731f421df4af8b8d92c77099f07aa5d23e36f (patch)
tree0d3235b1a02a9f4302a6dadb0295b2fbad504658
parent8a3a3508e97ae81cb07a9d8b943ca7aafedb5a85 (diff)
downloadlibapr-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.c26
-rw-r--r--file_io/win32/filestat.c34
-rw-r--r--file_io/win32/open.c5
-rw-r--r--include/apr_file_io.h12
-rw-r--r--include/arch/win32/apr_arch_file_io.h9
-rw-r--r--test/testfileinfo.c48
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;
}