delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin-developers/2001/09/05/16:37:59

Mailing-List: contact cygwin-developers-help AT sourceware DOT cygnus DOT com; run by ezmlm
List-Subscribe: <mailto:cygwin-developers-subscribe AT sources DOT redhat DOT com>
List-Archive: <http://sources.redhat.com/ml/cygwin-developers/>
List-Post: <mailto:cygwin-developers AT sources DOT redhat DOT com>
List-Help: <mailto:cygwin-developers-help AT sources DOT redhat DOT com>, <http://sources.redhat.com/ml/#faqs>
Sender: cygwin-developers-owner AT sources DOT redhat DOT com
Delivered-To: mailing list cygwin-developers AT sources DOT redhat DOT com
Date: Wed, 5 Sep 2001 16:38:56 -0400
From: Jason Tishler <jason AT tishler DOT net>
To: Cygwin-Developers <cygwin-developers AT sources DOT redhat DOT com>
Subject: WriteFile() whacks st_atime (was Re: stat() whacks st_atime)
Message-ID: <20010905163856.A616@dothill.com>
Mail-Followup-To: Cygwin-Developers <cygwin-developers AT sources DOT redhat DOT com>
Mime-Version: 1.0
In-Reply-To: <20010727095842.N439@dothill.com>
User-Agent: Mutt/1.3.18i

--+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 -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019