View Ticket
Not logged in
Ticket UUID: 3354324
Title: Windows: file mtime sets wrong time
Type: Bug Version: obsolete: 8.5.10
Submitter: juergen18 Created on: 2011-07-05 14:50:36
Subsystem: 36. Pathname Management Assigned To: nijtmans
Priority: 5 Medium Severity:
Status: Closed Last Modified: 2011-11-22 15:31:57
Resolution: Fixed Closed By: nijtmans
    Closed on: 2011-11-22 08:31:57
Description:
"file mtime FILENAME TIMEVALUE" always sets the time to 0 (i.e. 01-01-1970, 00:00) on Windows (XP, Vista, Win7, Windows Server 2003).
TCL sources have been compiled with VC++9 and VC++10 on Windows Vista and Windows Server 2003.
OS language is English, file name in basic 8.3 DOS style, file sytem is NTFS.
The same sources compiled and run on Linux do not show this error.
"make test"  prints the appropriate error messaage:

==== cmdAH-24.10 Tcl_FileObjCmd: mtime touch FAILED
==== Contents of test case:

    waitForEvenSecondForFAT
    set mtime [file mtime $file]
    after 2100; # pause two secs to notice change in mtime on FAT fs'es
    set newmtime [clock seconds]
    set modmtime [file mtime $file $newmtime]
    expr {$newmtime == $modmtime ? 1 : "$newmtime != $modmtime"}

---- Result was:
1309876143 != 0
---- Result should have been (exact matching):
1
==== cmdAH-24.10 FAILED
User Comments: nijtmans added on 2011-11-22 15:31:57:

allow_comments - 1

Fixed in all open branches

nijtmans added on 2011-11-17 21:50:45:
Good analysis! This one was introduced with the fix
for [Bug 3288345], and only occurs with VS >= 2005.
The standard build uses MSVC 6.0, so there this
is no problem.

Will be fixed in next upcoming version.

juergen18 added on 2011-11-17 21:00:27:
The same bug occurs in 8.5.11
It occurs only when tclsh is compiled on 32-bit Windows.
The reason is that functions in generic/ pass a 'utimbuf*' with 64-bit-time_t in it to function TclpUptime() in win/tclIOUtil.c, where a 32-bit-time_t is used.

As a hack, remove in generic/tclMain.c:
-- extern CRTIMPORT int  isatty(int fd);

Add in generic/tclCmdAH.c and in generic/tclIOUtil.c:
++ #ifndef _WIN64
++ #   define _USE_32BIT_TIME_T
++ #endif

A fix should #define _USE_32BIT_TIME_T in a header, makefile.vc or rules.vc.