Mail Archives: cygwin-developers/1999/09/24/16:58:34
The following patch allow utimes() to set access and
modification times of a read only file. I tested this patch by
`tar', `touch -a', and `touch -m'.
`touch' without any options can't work for read only files,
because it doesn't use utime() but utime_now() defined in
touch.c which set their times by reading and writing their
contents.
--- times.cc- Tue Aug 24 10:46:25 1999
+++ times.cc Sat Sep 25 03:58:13 1999
@@ -15,6 +15,7 @@ details. */
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
+#include <sys/stat.h>
#include "winsup.h"
#define FACTOR (0x19db1ded53ea710LL)
@@ -453,20 +454,45 @@ extern "C"
int
utimes (const char *path, struct timeval *tvp)
{
- int res = 0;
+ int res = -1;
struct timeval tmp[2];
- path_conv win32 (path);
+ path_conv win32_path (path);
+ HANDLE h = INVALID_HANDLE_VALUE;
+ int unixattr = -1;
+ DWORD saved_attr;
+ uid_t saved_uid = 0;
+ uid_t saved_gid = 0;
+
+ if (win32_path.error)
+ {
+ set_errno (win32_path.error);
+ goto done;
+ }
+ /* FIXME: This makes utimes on a device succeed always. */
+ if (win32_path.is_device ())
+ {
+ res = 0;
+ goto done;
+ }
- if (win32.error)
+ saved_attr = win32_path.file_attributes ();
+ if (saved_attr == (DWORD)-1)
+ {
+ __seterrno ();
+ goto done;
+ }
+ if (saved_attr & FILE_ATTRIBUTE_READONLY &&
+ !SetFileAttributesA (win32_path.get_win32 (),
+ saved_attr & ~FILE_ATTRIBUTE_READONLY))
{
- set_errno (win32.error);
- syscall_printf ("-1 = utimes (%s, %x)", path, tvp);
- return -1;
+ __seterrno ();
+ goto done;
}
/* MSDN suggests using FILE_FLAG_BACKUP_SEMANTICS for accessing
the times of directories. FIXME: what about Win95??? */
- HANDLE h = CreateFileA (win32.get_win32 (),
+retry:
+ h = CreateFileA (win32_path.get_win32 (),
GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
&sec_none_nih,
@@ -476,54 +502,71 @@ utimes (const char *path, struct timeval
if (h == INVALID_HANDLE_VALUE)
{
- if ((res = GetFileAttributes (win32.get_win32 ())) != -1 &&
- (res & FILE_ATTRIBUTE_DIRECTORY))
+ if (allow_ntsec && win32_path.has_acls () &&
+ unixattr == -1 && GetLastError () == ERROR_ACCESS_DENIED)
{
- /* What we can do with directories more? */
- res = 0;
+ unixattr = 0;
+ if (get_file_attribute (TRUE, win32_path.get_win32 (), &unixattr))
+ {
+ unixattr = -1;
+ goto recover;
+ }
+ saved_uid = get_file_owner (TRUE, win32_path.get_win32 ());
+ saved_gid = get_file_group (TRUE, win32_path.get_win32 ());
+ if (set_file_attribute (TRUE, win32_path.get_win32 (),
+ saved_uid, saved_gid,
+ unixattr | S_IWUSR))
+ {
+ unixattr = -1;
+ goto recover;
+ }
+ goto retry;
}
- else
+ if ((res = GetFileAttributes (win32_path.get_win32 ())) != -1 &&
+ (res & FILE_ATTRIBUTE_DIRECTORY))
{
- res = -1;
- __seterrno ();
+ /* What we can do with directories more? */
+ res = 0;
+ goto recover;
}
+ __seterrno ();
+ goto recover;
}
- else
+ if (tvp == 0)
{
- if (tvp == 0)
- {
- gettimeofday (&tmp[0], 0);
- tmp[1] = tmp[0];
- tvp = tmp;
- }
+ gettimeofday (&tmp[0], 0);
+ tmp[1] = tmp[0];
+ tvp = tmp;
+ }
- FILETIME lastaccess;
- FILETIME lastwrite;
+ FILETIME lastaccess;
+ FILETIME lastwrite;
- timeval_to_filetime (tvp + 0, &lastaccess);
- timeval_to_filetime (tvp + 1, &lastwrite);
+ timeval_to_filetime (tvp + 0, &lastaccess);
+ timeval_to_filetime (tvp + 1, &lastwrite);
- debug_printf ("incoming lastaccess %08x %08x",
- tvp->tv_sec,
- tvp->tv_usec);
+ debug_printf ("incoming lastaccess %08x %08x",
+ tvp->tv_sec,
+ tvp->tv_usec);
// dump_filetime (lastaccess);
// dump_filetime (lastwrite);
- /* FIXME: SetFileTime needs a handle with a write lock
- on the file whose time is being modified. So calls to utime()
- fail for read only files. */
+ if (!SetFileTime (h, 0, &lastaccess, &lastwrite))
+ __seterrno ();
+ else
+ res = 0;
+ CloseHandle (h);
- if (!SetFileTime (h, 0, &lastaccess, &lastwrite))
- {
- __seterrno ();
- res = -1;
- }
- else
- res = 0;
- CloseHandle (h);
- }
+recover:
+ if (saved_attr & FILE_ATTRIBUTE_READONLY)
+ SetFileAttributesA (win32_path.get_win32 (), saved_attr);
+
+ if (unixattr != -1)
+ set_file_attribute (TRUE, win32_path.get_win32 (),
+ saved_uid, saved_gid, unixattr);
+done:
syscall_printf ("%d = utimes (%s, %x); (h%d)",
res, path, tvp, h);
return res;
____
| AIST Kazuhiro Fujieda <fujieda AT jaist DOT ac DOT jp>
| HOKURIKU School of Information Science
o_/ 1990 Japan Advanced Institute of Science and Technology
- Raw text -