getatime() changes atime on cygwin

Jason Tishler jason at tishler.net
Tue Jul 2 17:03:30 EDT 2002


Thomas,

On Mon, Jul 01, 2002 at 12:18:54PM +0200, Thomas Guettler wrote:
> time.getatime() (access time) changes the atime on cygwin.
> 
> If a run the following script twice. The atime
> got changed by the first run.

See the following:

    http://www.google.com/search?hl=en&lr=&ie=ISO-8859-1&safe=off&q=site%3Acygwin.com+tishler+whacks+st_atime

As you can see, I have been in this "special" place before... :,)

Specifically, check out this one:

    http://www.cygwin.com/ml/cygwin-developers/2001-09/msg00076.html

My WAG is that you are either running under 9x/Me or NT/2000/XP without
ntsec.  If so, then just calling Cygwin's stat() via os.path.getatime()
will affect st_atime.

If you are running under NT/2000/XP, then set

    CYGWIN=ntsec

If you are running under 9x/Me, then you are SOL.


> If I use the native version, the access time does not get
> changed by calling time.getatime()

This is to be expected.  See the above.

> The next strange thing: 'cat foo.txt' in cygwin does not change the
> atime which you get if you call the getatime() in win32 python.
> If I open it in an windows application it get changed.

I can confirm the above.  However, the attached Win32 (i.e., not Cygwin)
program does *not* exhibit this behavior -- it properly notices the
st_atime change.  So, this may not be a Cygwin problem.  Sorry, but you
will have to dig deeper to solve this mystery.

Jason
-------------- next part --------------
/*
 * Copyright (c) 2002 Jason Tishler
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * A copy of the GNU General Public License can be found at
 * http://www.gnu.org/
 *
 */

#include <windows.h>

#define FACTOR (0x19db1ded53e8000LL)
#define NSPERSEC 10000000LL
long to_time_t (FILETIME *ptr);

int
main(int argc, char* argv[])
{
	HANDLE h;
	BY_HANDLE_FILE_INFORMATION info;
	BOOL s;
	time_t t;

	h = CreateFile(
		argv[1],
		GENERIC_READ,
		FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
		0,
		OPEN_EXISTING,
		0x2000000 | FILE_ATTRIBUTE_NORMAL,
		0);
	if (h == INVALID_HANDLE_VALUE)
	{
		printf("CreateFile() failed with error = %ld\n", GetLastError());
		exit(1);
	}

	s = GetFileInformationByHandle(h, &info);
	if (!s)
	{
		printf("GetFileInformationByHandle() failed with error = %ld\n", GetLastError());
		exit(2);
	}

	t = to_time_t(&info.ftLastAccessTime);
	printf("access time = %s", ctime(&t));

	CloseHandle(h);
}

long
to_time_t (FILETIME *ptr)
{
  /* A file time is the number of 100ns since jan 1 1601
     stuffed into two long words.
     A time_t is the number of seconds since jan 1 1970.  */

  long rem;
  long long x = ((long long) ptr->dwHighDateTime << 32) + ((unsigned)ptr->dwLowDateTime);

  /* pass "no time" as epoch */
  if (x == 0)
    return 0;

  x -= FACTOR;			/* number of 100ns between 1601 and 1970 */
  rem = x % ((long long)NSPERSEC);
  rem += (NSPERSEC / 2);
  x /= (long long) NSPERSEC;		/* number of 100ns in a second */
  x += (long long) (rem / NSPERSEC);
  return x;
}


More information about the Python-list mailing list