diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index c147d6156..c1d3bda5a 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,11 @@ +2005-04-13 Christopher Faylor + + * fhandler.h (fhandler_base::utimes_fs): New method. + * fhandler.cc (fhandler_base::utimes): Call utimes_fs if on-disk + special file. + * fhandler_disk_file.cc (fhandler_disk_file::utimes): Use utimes_fs. + (fhandler_base::utimes_fs): Handle on-disk device files. + 2005-04-13 Corinna Vinschen * fhandler_disk_file.cc (fhandler_disk_file::utimes): Don't set errno diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc index 1e7efc7d7..c64dcb1c9 100644 --- a/winsup/cygwin/fhandler.cc +++ b/winsup/cygwin/fhandler.cc @@ -1635,6 +1635,9 @@ fhandler_base::link (const char *newpath) int fhandler_base::utimes (const struct timeval *tvp) { + if (is_fs_special ()) + return utimes_fs (tvp); + set_errno (EINVAL); return -1; } diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 12c5b6445..787d78e33 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -271,6 +271,7 @@ class fhandler_base __attribute__ ((regparm (3))); int __stdcall fstat_by_handle (struct __stat64 *buf) __attribute__ ((regparm (2))); int __stdcall fstat_by_name (struct __stat64 *buf) __attribute__ ((regparm (2))); + int fhandler_base::utimes_fs (const struct timeval *) __attribute__ ((regparm (2))); virtual int __stdcall fchmod (mode_t mode) __attribute__ ((regparm (1))); virtual int __stdcall fchown (__uid32_t uid, __gid32_t gid) __attribute__ ((regparm (2))); virtual int __stdcall facl (int, int, __acl32 *) __attribute__ ((regparm (3))); diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc index fce53e985..1fe371341 100644 --- a/winsup/cygwin/fhandler_disk_file.cc +++ b/winsup/cygwin/fhandler_disk_file.cc @@ -826,19 +826,25 @@ docopy: int fhandler_disk_file::utimes (const struct timeval *tvp) +{ + return utimes_fs (tvp); +} + +int +fhandler_base::utimes_fs (const struct timeval *tvp) { FILETIME lastaccess, lastwrite, lastchange; struct timeval tmp[2]; query_open (query_write_attributes); - if (!open (O_BINARY, 0)) + if (!open_fs (O_BINARY, 0)) { /* It's documented in MSDN that FILE_WRITE_ATTRIBUTES is sufficient to change the timestamps. Unfortunately it's not sufficient for a remote HPFS which requires GENERIC_WRITE, so we just retry to open for writing, though this fails for R/O files of course. */ query_open (no_query); - if (!open (O_WRONLY | O_BINARY, 0)) + if (!open_fs (O_WRONLY | O_BINARY, 0)) { syscall_printf ("Opening file failed"); return -1; @@ -859,13 +865,20 @@ fhandler_disk_file::utimes (const struct timeval *tvp) /* Update ctime */ timeval_to_filetime (&tmp[0], &lastchange); debug_printf ("incoming lastaccess %08x %08x", tvp[0].tv_sec, tvp[0].tv_usec); - if (!SetFileTime (get_handle (), &lastchange, &lastaccess, &lastwrite)) + + if (is_fs_special ()) + SetFileAttributes (pc, (DWORD) pc & ~FILE_ATTRIBUTE_READONLY); + BOOL res = SetFileTime (get_handle (), &lastchange, &lastaccess, &lastwrite); + DWORD errcode = GetLastError (); + if (is_fs_special ()) + SetFileAttributes (pc, pc); + if (!res) { - DWORD errcode = GetLastError (); close (); __seterrno_from_win_error (errcode); return -1; } + close (); return 0; }