Mail Archives: cygwin-developers/2001/09/05/16:37:59
--+hupnHfSQzmGFwlm
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
On Fri, Jul 27, 2001 at 09:58:42AM -0400, Jason Tishler wrote:
> On Fri, Jul 27, 2001 at 10:21:09AM +1000, Robert Collins wrote:
> > My guess would be it's the file header reading logic - looking for
> > #!/bin/foo
> >
> > that means that a file access _has occured_. CloseHandle triggering the
> > actual write might jsut eb a win32 optimisation, to only wr
>
> Bingo! Thanks for helping me to see what I was missing in my haste. I
> guess that the solution is to starting using ntsec (which I should be
> doing for other reasons too).
After converting to ntsec, the above problem has been corrected.
Unfortunately, I was still having problems with st_atime getting set
unexpectedly.
I finally found the root cause, WriteFile(). However Microsoft
obfuscated this fact by documenting it in the MSDN entries for
GetFileTime()/SetFileTime() instead of WriteFile():
lpLastAccessTime
Pointer to a FILETIME structure that contains the date and time the
file was last accessed. The last access time includes the last time
the file was written to, read from, or (in the case of executable
^^^^^^^
files) run. This parameter can be NULL if the application does not
need to set this information.
The first attachment, wtest4.c, demonstrates that the problem due is to
Win32 and not Cygwin.
The second attachment is a "patch" (I'm using the term very loosely)
that works around this Windows-ism so that Cygwin behaves Posix-like
with regard to write() and st_atime.
Does a cleaned up version of this patch have a chance of being accepted?
I'm concerned about race conditions, performance impact, affecting
non-disk files, etc. Is this simplistic approach the best way to work
around the problem? Or, are there better ways?
Thanks,
Jason
--+hupnHfSQzmGFwlm
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="wtest4.c"
#include <windows.h>
char d[] = "hello\n";
int
main(int argc, char* argv[])
{
HANDLE h;
BOOL s;
DWORD r;
FILETIME access;
h = CreateFile(
argv[1],
GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
0,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0);
if (h == INVALID_HANDLE_VALUE)
{
printf("CreateFile() failed with error = %ld\n", GetLastError());
exit(1);
}
r = SetFilePointer(h, 0, 0, FILE_END);
if (r == 0xFFFFFFFF)
{
printf("SetFilePoint() failed with error = %ld\n", GetLastError());
exit(1);
}
s = GetFileTime(h, 0, &access, 0);
if (!s)
{
printf("GetFileTime() failed with error = %ld\n", GetLastError());
exit(1);
}
s = WriteFile(h, d, strlen(d), &r, 0);
if (!s)
{
printf("WriteFile() failed with error = %ld\n", GetLastError());
exit(1);
}
/* XXX uncomment to workaround Windows XXX
s = SetFileTime(h, 0, &access, 0);
if (!s)
{
printf("SetFileTime() failed with error = %ld\n", GetLastError());
exit(1);
}
*/
CloseHandle(h);
}
--+hupnHfSQzmGFwlm
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="fhandler.cc.diff"
Index: fhandler.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/fhandler.cc,v
retrieving revision 1.77
diff -u -p -r1.77 fhandler.cc
--- fhandler.cc 2001/09/01 05:17:34 1.77
+++ fhandler.cc 2001/09/05 20:14:35
@@ -254,6 +254,8 @@ fhandler_base::raw_write (const void *pt
{
DWORD bytes_written;
+ FILETIME access;
+ GetFileTime(get_handle(), 0, &access, 0);
if (!WriteFile (get_handle(), ptr, len, &bytes_written, 0))
{
if (GetLastError () == ERROR_DISK_FULL && bytes_written > 0)
@@ -263,6 +265,7 @@ fhandler_base::raw_write (const void *pt
raise (SIGPIPE);
return -1;
}
+ SetFileTime(get_handle(), 0, &access, 0);
return bytes_written;
}
--+hupnHfSQzmGFwlm--
- Raw text -