I wrote: >This interface looks sane, and I can cobble up a Windows implementation >in two eyeblinks. > > And here it is, including tests.
Index: include/apr_file_io.h =================================================================== RCS file: /home/cvs/apr/include/apr_file_io.h,v retrieving revision 1.141 diff -u -u -p -r1.141 apr_file_io.h --- include/apr_file_io.h 15 Jun 2003 00:05:26 -0000 1.141 +++ include/apr_file_io.h 4 Jul 2003 01:55:23 -0000 @@ -655,6 +658,18 @@ APR_DECLARE(apr_status_t) apr_file_attrs apr_fileattrs_t attributes, apr_fileattrs_t attr_mask, 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. Index: include/arch/win32/apr_arch_file_io.h =================================================================== RCS file: /home/cvs/apr/include/arch/win32/apr_arch_file_io.h,v retrieving revision 1.2 diff -u -u -p -r1.2 apr_arch_file_io.h --- include/arch/win32/apr_arch_file_io.h 24 Jan 2003 17:15:56 -0000 1.2 +++ include/arch/win32/apr_arch_file_io.h 4 Jul 2003 01:55:24 -0000 @@ -133,10 +133,11 @@ void *res_name_from_filename(const char #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: */ Index: file_io/win32/open.c =================================================================== RCS file: /home/cvs/apr/file_io/win32/open.c,v retrieving revision 1.117 diff -u -u -p -r1.117 open.c --- file_io/win32/open.c 7 Jan 2003 00:52:54 -0000 1.117 +++ file_io/win32/open.c 4 Jul 2003 01:55:23 -0000 @@ -309,7 +309,10 @@ APR_DECLARE(apr_status_t) apr_file_open( 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; Index: file_io/win32/filestat.c =================================================================== RCS file: /home/cvs/apr/file_io/win32/filestat.c,v retrieving revision 1.80 diff -u -u -p -r1.80 filestat.c --- file_io/win32/filestat.c 24 May 2003 10:30:39 -0000 1.80 +++ file_io/win32/filestat.c 4 Jul 2003 01:55:20 -0000 @@ -762,3 +762,37 @@ APR_DECLARE(apr_status_t) apr_file_attrs 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; +} Index: test/testfileinfo.c =================================================================== RCS file: /home/cvs/apr/test/testfileinfo.c,v retrieving revision 1.10 diff -u -u -p -r1.10 testfileinfo.c --- test/testfileinfo.c 7 Feb 2003 12:33:00 -0000 1.10 +++ test/testfileinfo.c 4 Jul 2003 01:55:24 -0000 3@@ -59,6 +59,7 @@ #include "apr_general.h" #include "apr_poll.h" #include "apr_lib.h" +#include "apr_time.h" #include "test_apr.h" #define FILENAME "data/file_datafile.txt" @@ -239,6 +240,53 @@ static void test_buffered_write_size(CuT 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 +296,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; } -- Brane Äibej <[EMAIL PROTECTED]> http://www.xbc.nu/brane/