diff options
-rw-r--r-- | generic/tcl.h | 2 | ||||
-rw-r--r-- | generic/tclBasic.c | 17 | ||||
-rw-r--r-- | tests/cmdAH.test | 20 | ||||
-rw-r--r-- | win/tclWinPort.h | 11 | ||||
-rw-r--r-- | win/tclWinTest.c | 23 |
5 files changed, 63 insertions, 10 deletions
diff --git a/generic/tcl.h b/generic/tcl.h index 64c4683..f05112e 100644 --- a/generic/tcl.h +++ b/generic/tcl.h @@ -414,7 +414,7 @@ typedef unsigned TCL_WIDE_INT_TYPE Tcl_WideUInt; #if defined(__WIN32__) # ifdef __BORLANDC__ typedef struct stati64 Tcl_StatBuf; -# elif defined(_WIN64) +# elif defined(_WIN64) || defined(__MINGW_USE_VC2005_COMPAT) typedef struct __stat64 Tcl_StatBuf; # elif (defined(_MSC_VER) && (_MSC_VER < 1400)) || defined(_USE_32BIT_TIME_T) typedef struct _stati64 Tcl_StatBuf; diff --git a/generic/tclBasic.c b/generic/tclBasic.c index 3b9fca9..5ca4b82 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -414,15 +414,20 @@ Tcl_CreateInterp(void) } #if defined(_WIN32) && !defined(_WIN64) - if (sizeof(time_t) != 4) { + if (sizeof(time_t) == 4 || sizeof(time_t) == 8) { + Tcl_StatBuf buf; + if ( + sizeof(buf.st_atime) != sizeof(time_t) || + sizeof(buf.st_mtime) != sizeof(time_t) || + sizeof(buf.st_ctime) != sizeof(time_t) + ) { + /*NOTREACHED*/ + Tcl_Panic("<sys/stat.h> is not compatible with MSVC"); + } + } else { /*NOTREACHED*/ Tcl_Panic("<time.h> is not compatible with MSVC"); } - if ((TclOffset(Tcl_StatBuf,st_atime) != 32) - || (TclOffset(Tcl_StatBuf,st_ctime) != 40)) { - /*NOTREACHED*/ - Tcl_Panic("<sys/stat.h> is not compatible with MSVC"); - } #endif /* diff --git a/tests/cmdAH.test b/tests/cmdAH.test index 516505c..e4205f1 100644 --- a/tests/cmdAH.test +++ b/tests/cmdAH.test @@ -18,6 +18,10 @@ if {[lsearch [namespace children] ::tcltest] == -1} { testConstraint testchmod [llength [info commands testchmod]] testConstraint testsetplatform [llength [info commands testsetplatform]] testConstraint testvolumetype [llength [info commands testvolumetype]] +testConstraint time64bit [expr { + $::tcl_platform(pointerSize) >= 8 || + [llength [info command testsize]] && [testsize time_t] >= 8 +}] testConstraint linkDirectory [expr { ![testConstraint win] || ($::tcl_platform(osVersion) >= 5.0 @@ -1278,6 +1282,22 @@ test cmdAH-24.13 {Tcl_FileObjCmd: directory mtime} -setup { file delete -force $dirname } -result {0 1} +# 3155760000 is 64-bit unix time, Wed Jan 01 00:00:00 GMT 2070: +test cmdAH-24.20.1 {Tcl_FileObjCmd: atime 64-bit time_t, bug [4718b41c56]} -constraints {time64bit} -setup { + set filename [makeFile "" foo.text] +} -body { + list [file atime $filename 3155760000] [file atime $filename] +} -cleanup { + removeFile $filename +} -result {3155760000 3155760000} +test cmdAH-24.20.2 {Tcl_FileObjCmd: mtime 64-bit time_t, bug [4718b41c56]} -constraints {time64bit} -setup { + set filename [makeFile "" foo.text] +} -body { + list [file mtime $filename 3155760000] [file mtime $filename] +} -cleanup { + file delete -force $filename +} -result {3155760000 3155760000} + # owned test cmdAH-25.1 {Tcl_FileObjCmd: owned} { diff --git a/win/tclWinPort.h b/win/tclWinPort.h index c30d1bd..8b42348 100644 --- a/win/tclWinPort.h +++ b/win/tclWinPort.h @@ -14,9 +14,14 @@ #ifndef _TCLWINPORT #define _TCLWINPORT -#ifndef _WIN64 -/* See [Bug 3354324]: file mtime sets wrong time */ -# define _USE_32BIT_TIME_T +#if !defined(_WIN64) && !defined(_USE_32BIT_TIME_T) && !defined(__MINGW_USE_VC2005_COMPAT) +# if defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER >= 1400) +# define __MINGW_USE_VC2005_COMPAT + /* define _USE_64BIT_TIME_T to force 64-bit time_t */ +# elif !defined(_USE_64BIT_TIME_T) + /* See [Bug 3354324]: file mtime sets wrong time */ +# define _USE_32BIT_TIME_T +# endif #endif #define WIN32_LEAN_AND_MEAN diff --git a/win/tclWinTest.c b/win/tclWinTest.c index 7f49b63..dd5a60e 100644 --- a/win/tclWinTest.c +++ b/win/tclWinTest.c @@ -39,6 +39,8 @@ static int TestwinclockCmd(ClientData dummy, Tcl_Interp* interp, int objc, Tcl_Obj *const objv[]); static int TestwinsleepCmd(ClientData dummy, Tcl_Interp* interp, int objc, Tcl_Obj *const objv[]); +static int TestSizeCmd(ClientData dummy, Tcl_Interp* interp, + int objc, Tcl_Obj *const objv[]); static Tcl_ObjCmdProc TestExceptionCmd; static int TestplatformChmod(const char *nativePath, int pmode); static int TestchmodCmd(ClientData dummy, @@ -76,6 +78,7 @@ TclplatformtestInit( Tcl_CreateObjCommand(interp, "testwinclock", TestwinclockCmd, NULL, NULL); Tcl_CreateObjCommand(interp, "testwinsleep", TestwinsleepCmd, NULL, NULL); Tcl_CreateObjCommand(interp, "testexcept", TestExceptionCmd, NULL, NULL); + Tcl_CreateObjCommand(interp, "testsize", TestSizeCmd, NULL, NULL); return TCL_OK; } @@ -309,6 +312,26 @@ TestwinsleepCmd( return TCL_OK; } +static int +TestSizeCmd( + ClientData clientData, /* Unused */ + Tcl_Interp* interp, /* Tcl interpreter */ + int objc, /* Parameter count */ + Tcl_Obj *const * objv) /* Parameter vector */ +{ + if (objc != 2) { + goto syntax; + } + if (strcmp(Tcl_GetString(objv[1]), "time_t") == 0) { + Tcl_SetObjResult(interp, Tcl_NewWideIntObj(sizeof(time_t))); + return TCL_OK; + } + +syntax: + Tcl_WrongNumArgs(interp, 1, objv, "time_t"); + return TCL_ERROR; +} + /* *---------------------------------------------------------------------- * |