summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--generic/tclEnv.c70
-rw-r--r--tests/cmdAH.test4
-rwxr-xr-xunix/configure117
-rw-r--r--unix/tcl.m425
-rw-r--r--unix/tclConfig.h.in6
-rw-r--r--win/Makefile.in10
-rw-r--r--win/tclWinInit.c3
7 files changed, 200 insertions, 35 deletions
diff --git a/generic/tclEnv.c b/generic/tclEnv.c
index 608ebf6..8b73b21 100644
--- a/generic/tclEnv.c
+++ b/generic/tclEnv.c
@@ -19,20 +19,20 @@ TCL_DECLARE_MUTEX(envMutex) /* To serialize access to environ. */
#if defined(_WIN32)
# define tenviron _wenviron
-# define tenviron2utfdstr(string, len, dsPtr) (Tcl_DStringInit(dsPtr), \
- (char *)Tcl_Char16ToUtfDString((const unsigned short *)(string), ((((len) + 2) >> 1) - 1), (dsPtr)))
-# define utf2tenvirondstr(string, len, dsPtr) (Tcl_DStringInit(dsPtr), \
- (const WCHAR *)Tcl_UtfToChar16DString((string), (len), (dsPtr)))
+# define tenviron2utfdstr(str, dsPtr) (Tcl_DStringInit(dsPtr), \
+ (char *)Tcl_Char16ToUtfDString((const unsigned short *)(str), -1, (dsPtr)))
+# define utf2tenvirondstr(str, dsPtr) (Tcl_DStringInit(dsPtr), \
+ (const WCHAR *)Tcl_UtfToChar16DString((str), -1, (dsPtr)))
# define techar WCHAR
# ifdef USE_PUTENV
# define putenv(env) _wputenv((const wchar_t *)env)
# endif
#else
# define tenviron environ
-# define tenviron2utfdstr(tenvstr, len, dstr) \
- Tcl_ExternalToUtfDString(NULL, tenvstr, len, dstr)
-# define utf2tenvirondstr(str, len, dstr) \
- Tcl_UtfToExternalDString(NULL, str, len, dstr)
+# define tenviron2utfdstr(str, dsPtr) \
+ Tcl_ExternalToUtfDString(NULL, str, -1, dsPtr)
+# define utf2tenvirondstr(str, dsPtr) \
+ Tcl_UtfToExternalDString(NULL, str, -1, dsPtr)
# define techar char
#endif
@@ -42,7 +42,7 @@ size_t TclEnvEpoch = 0; /* Epoch of the tcl environment
* (if changed with tcl-env). */
static struct {
- size_t cacheSize; /* Number of env strings in cache. */
+ Tcl_Size cacheSize; /* Number of env strings in cache. */
char **cache; /* Array containing all of the environment
* strings that Tcl has allocated. */
#ifndef USE_PUTENV
@@ -159,7 +159,11 @@ TclSetupEnv(
const char *p1;
char *p2;
- p1 = tenviron2utfdstr(tenviron[i], -1, &envString);
+ p1 = tenviron2utfdstr(tenviron[i], &envString);
+ if (p1 == NULL) {
+ /* Ignore what cannot be decoded (should not happen) */
+ continue;
+ }
p2 = (char *)strchr(p1, '=');
if (p2 == NULL) {
/*
@@ -301,9 +305,9 @@ TclSetEnv(
* interpreters.
*/
- oldEnv = tenviron2utfdstr(tenviron[index], -1, &envString);
- if (strcmp(value, oldEnv + (length + 1)) == 0) {
- Tcl_DStringFree(&envString);
+ oldEnv = tenviron2utfdstr(tenviron[index], &envString);
+ if (oldEnv == NULL || strcmp(value, oldEnv + (length + 1)) == 0) {
+ Tcl_DStringFree(&envString); /* OK even if oldEnv is NULL */
Tcl_MutexUnlock(&envMutex);
return;
}
@@ -324,7 +328,13 @@ TclSetEnv(
memcpy(p, name, nameLength);
p[nameLength] = '=';
memcpy(p+nameLength+1, value, valueLength+1);
- p2 = utf2tenvirondstr(p, -1, &envString);
+ p2 = utf2tenvirondstr(p, &envString);
+ if (p2 == NULL) {
+ /* No way to signal error from here :-( but should not happen */
+ Tcl_Free(p);
+ Tcl_MutexUnlock(&envMutex);
+ return;
+ }
/*
* Copy the native string to heap memory.
@@ -502,7 +512,11 @@ TclUnsetEnv(
string[length] = '\0';
#endif /* _WIN32 */
- utf2tenvirondstr(string, -1, &envString);
+ if (utf2tenvirondstr(string, &envString) == NULL) {
+ /* Should not happen except memory alloc fail. */
+ Tcl_MutexUnlock(&envMutex);
+ return;
+ }
string = (char *)Tcl_Realloc(string, Tcl_DStringLength(&envString) + tNTL);
memcpy(string, Tcl_DStringValue(&envString),
Tcl_DStringLength(&envString) + tNTL);
@@ -577,17 +591,19 @@ TclGetEnv(
if (index != -1) {
Tcl_DString envStr;
- result = tenviron2utfdstr(tenviron[index], -1, &envStr);
- result += length;
- if (*result == '=') {
- result++;
- Tcl_DStringInit(valuePtr);
- Tcl_DStringAppend(valuePtr, result, -1);
- result = Tcl_DStringValue(valuePtr);
- } else {
- result = NULL;
+ result = tenviron2utfdstr(tenviron[index], &envStr);
+ if (result) {
+ result += length;
+ if (*result == '=') {
+ result++;
+ Tcl_DStringInit(valuePtr);
+ Tcl_DStringAppend(valuePtr, result, -1);
+ result = Tcl_DStringValue(valuePtr);
+ } else {
+ result = NULL;
+ }
+ Tcl_DStringFree(&envStr);
}
- Tcl_DStringFree(&envStr);
}
Tcl_MutexUnlock(&envMutex);
return result;
@@ -703,7 +719,7 @@ ReplaceString(
const char *oldStr, /* Old environment string. */
char *newStr) /* New environment string. */
{
- size_t i;
+ Tcl_Size i;
/*
* Check to see if the old value was allocated by Tcl. If so, it needs to
@@ -782,7 +798,7 @@ TclFinalizeEnvironment(void)
if (env.cache) {
#ifdef PURIFY
- size_t i;
+ Tcl_Size i;
for (i = 0; i < env.cacheSize; i++) {
Tcl_Free(env.cache[i]);
}
diff --git a/tests/cmdAH.test b/tests/cmdAH.test
index 555c70f..ad5a67d 100644
--- a/tests/cmdAH.test
+++ b/tests/cmdAH.test
@@ -1710,6 +1710,8 @@ test cmdAH-24.14.1 {
test cmdAH-24.20.1 {Tcl_FileObjCmd: atime 64-bit time_t, bug [4718b41c56]} -setup {
set filename [makeFile "" foo.text]
} -body {
+ # This test may fail if your system does not have a 64-bit time_t.
+ # That is to be expected and is not a problem with Tcl.
list [file atime $filename 3155760000] [file atime $filename]
} -cleanup {
removeFile $filename
@@ -1717,6 +1719,8 @@ test cmdAH-24.20.1 {Tcl_FileObjCmd: atime 64-bit time_t, bug [4718b41c56]} -setu
test cmdAH-24.20.2 {Tcl_FileObjCmd: mtime 64-bit time_t, bug [4718b41c56]} -setup {
set filename [makeFile "" foo.text]
} -body {
+ # This test may fail if your system does not have a 64-bit time_t.
+ # That is to be expected and is not a problem with Tcl.
list [file mtime $filename 3155760000] [file mtime $filename]
} -cleanup {
file delete -force $filename
diff --git a/unix/configure b/unix/configure
index a3102b8..66af4ce 100755
--- a/unix/configure
+++ b/unix/configure
@@ -7492,6 +7492,56 @@ printf "%s\n" "#define _ISOC99_SOURCE 1" >>confdefs.h
fi
+ if test ${tcl_cv_flag__file_offset_bits+y}
+then :
+ printf %s "(cached) " >&6
+else $as_nop
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/stat.h>
+int
+main (void)
+{
+switch (0) { case 0: case (sizeof(off_t)==sizeof(long long)): ; }
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+ tcl_cv_flag__file_offset_bits=no
+else $as_nop
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#define _FILE_OFFSET_BITS 64
+#include <sys/stat.h>
+int
+main (void)
+{
+switch (0) { case 0: case (sizeof(off_t)==sizeof(long long)): ; }
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+ tcl_cv_flag__file_offset_bits=yes
+else $as_nop
+ tcl_cv_flag__file_offset_bits=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+ if test "x${tcl_cv_flag__file_offset_bits}" = "xyes" ; then
+
+printf "%s\n" "#define _FILE_OFFSET_BITS 64" >>confdefs.h
+
+ tcl_flags="$tcl_flags _FILE_OFFSET_BITS"
+ fi
+
+
if test ${tcl_cv_flag__largefile64_source+y}
then :
printf %s "(cached) " >&6
@@ -7592,6 +7642,73 @@ printf "%s\n" "yes" >&6; }
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }
# Now check for auxiliary declarations
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for 64-bit time_t" >&5
+printf %s "checking for 64-bit time_t... " >&6; }
+if test ${tcl_cv_time_t_64+y}
+then :
+ printf %s "(cached) " >&6
+else $as_nop
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+int
+main (void)
+{
+switch (0) {case 0: case (sizeof(time_t)==sizeof(long long)): ;}
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+ tcl_cv_time_t_64=yes
+else $as_nop
+ tcl_cv_time_t_64=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_time_t_64" >&5
+printf "%s\n" "$tcl_cv_time_t_64" >&6; }
+ if test "x${tcl_cv_time_t_64}" = "xno" ; then
+ # Note that _TIME_BITS=64 requires _FILE_OFFSET_BITS=64
+ # which SC_TCL_EARLY_FLAGS has defined if necessary.
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if _TIME_BITS=64 enables 64-bit time_t" >&5
+printf %s "checking if _TIME_BITS=64 enables 64-bit time_t... " >&6; }
+if test ${tcl_cv__time_bits+y}
+then :
+ printf %s "(cached) " >&6
+else $as_nop
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#define _TIME_BITS 64
+#include <sys/types.h>
+int
+main (void)
+{
+switch (0) {case 0: case (sizeof(time_t)==sizeof(long long)): ;}
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+ tcl_cv__time_bits=yes
+else $as_nop
+ tcl_cv__time_bits=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv__time_bits" >&5
+printf "%s\n" "$tcl_cv__time_bits" >&6; }
+ if test "x${tcl_cv__time_bits}" = "xyes" ; then
+
+printf "%s\n" "#define _TIME_BITS 64" >>confdefs.h
+
+ fi
+ fi
+
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for struct dirent64" >&5
printf %s "checking for struct dirent64... " >&6; }
if test ${tcl_cv_struct_dirent64+y}
diff --git a/unix/tcl.m4 b/unix/tcl.m4
index 9dc39f2..beaac7e 100644
--- a/unix/tcl.m4
+++ b/unix/tcl.m4
@@ -2294,6 +2294,7 @@ AC_DEFUN([SC_TCL_LINK_LIBS], [
#
# Might define the following vars:
# _ISOC99_SOURCE
+# _FILE_OFFSET_BITS
# _LARGEFILE64_SOURCE
#
#--------------------------------------------------------------------
@@ -2301,12 +2302,12 @@ AC_DEFUN([SC_TCL_LINK_LIBS], [
AC_DEFUN([SC_TCL_EARLY_FLAG],[
AC_CACHE_VAL([tcl_cv_flag_]translit($1,[A-Z],[a-z]),
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[$2]], [[$3]])],
- [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no,[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[[#define ]$1[ 1
+ [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no,[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[[#define ]$1[ ]m4_default([$4],[1])[
]$2]], [[$3]])],
[tcl_cv_flag_]translit($1,[A-Z],[a-z])=yes,
[tcl_cv_flag_]translit($1,[A-Z],[a-z])=no)]))
if test ["x${tcl_cv_flag_]translit($1,[A-Z],[a-z])[}" = "xyes"] ; then
- AC_DEFINE($1, 1, [Add the ]$1[ flag when building])
+ AC_DEFINE($1, m4_default([$4],[1]), [Add the ]$1[ flag when building])
tcl_flags="$tcl_flags $1"
fi
])
@@ -2316,6 +2317,8 @@ AC_DEFUN([SC_TCL_EARLY_FLAGS],[
tcl_flags=""
SC_TCL_EARLY_FLAG(_ISOC99_SOURCE,[#include <stdlib.h>],
[char *p = (char *)strtoll; char *q = (char *)strtoull;])
+ SC_TCL_EARLY_FLAG(_FILE_OFFSET_BITS,[#include <sys/stat.h>],
+ [switch (0) { case 0: case (sizeof(off_t)==sizeof(long long)): ; }],64)
SC_TCL_EARLY_FLAG(_LARGEFILE64_SOURCE,[#include <sys/stat.h>],
[struct stat64 buf; int i = stat64("/", &buf);])
if test "x${tcl_flags}" = "x" ; then
@@ -2340,6 +2343,7 @@ AC_DEFUN([SC_TCL_EARLY_FLAGS],[
# HAVE_STRUCT_DIRENT64, HAVE_DIR64
# HAVE_STRUCT_STAT64
# HAVE_TYPE_OFF64_T
+# _TIME_BITS
#
#--------------------------------------------------------------------
@@ -2359,6 +2363,23 @@ AC_DEFUN([SC_TCL_64BIT_FLAGS], [
else
AC_MSG_RESULT([no])
# Now check for auxiliary declarations
+ AC_CACHE_CHECK([for 64-bit time_t], tcl_cv_time_t_64,[
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h>]],
+ [[switch (0) {case 0: case (sizeof(time_t)==sizeof(long long)): ;}]])],
+ [tcl_cv_time_t_64=yes],[tcl_cv_time_t_64=no])])
+ if test "x${tcl_cv_time_t_64}" = "xno" ; then
+ # Note that _TIME_BITS=64 requires _FILE_OFFSET_BITS=64
+ # which SC_TCL_EARLY_FLAGS has defined if necessary.
+ AC_CACHE_CHECK([if _TIME_BITS=64 enables 64-bit time_t], tcl_cv__time_bits,[
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#define _TIME_BITS 64
+#include <sys/types.h>]],
+ [[switch (0) {case 0: case (sizeof(time_t)==sizeof(long long)): ;}]])],
+ [tcl_cv__time_bits=yes],[tcl_cv__time_bits=no])])
+ if test "x${tcl_cv__time_bits}" = "xyes" ; then
+ AC_DEFINE(_TIME_BITS, 64, [_TIME_BITS=64 enables 64-bit time_t.])
+ fi
+ fi
+
AC_CACHE_CHECK([for struct dirent64], tcl_cv_struct_dirent64,[
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h>
#include <dirent.h>]], [[struct dirent64 p;]])],
diff --git a/unix/tclConfig.h.in b/unix/tclConfig.h.in
index fe2c6d9..a1b59df 100644
--- a/unix/tclConfig.h.in
+++ b/unix/tclConfig.h.in
@@ -471,6 +471,9 @@
/* Are Darwin SUSv3 extensions available? */
#undef _DARWIN_C_SOURCE
+/* Add the _FILE_OFFSET_BITS flag when building */
+#undef _FILE_OFFSET_BITS
+
/* Add the _ISOC99_SOURCE flag when building */
#undef _ISOC99_SOURCE
@@ -489,6 +492,9 @@
/* Do we want the thread-safe OS API? */
#undef _THREAD_SAFE
+/* _TIME_BITS=64 enables 64-bit time_t. */
+#undef _TIME_BITS
+
/* Do we want to use the XOPEN network library? */
#undef _XOPEN_SOURCE
diff --git a/win/Makefile.in b/win/Makefile.in
index 04ae08f..e648d3f 100644
--- a/win/Makefile.in
+++ b/win/Makefile.in
@@ -627,10 +627,14 @@ ${ZLIB_DLL_FILE}: ${TCL_STUB_LIB_FILE}
# use pre-built libtommath.dll
${TOMMATH_DLL_FILE}: ${TCL_STUB_LIB_FILE}
- @if test "@TOMMATH_LIBS@set" != "${TOMMATH_DIR_NATIVE}/win32/tommath.libset" ; then \
- $(COPY) $(TOMMATH_DIR)/win64/${TOMMATH_DLL_FILE} ${TOMMATH_DLL_FILE}; \
- else \
+ @if test "@TOMMATH_LIBS@set" = "${TOMMATH_DIR_NATIVE}/win64-arm/tommath.libset" ; then \
+ $(COPY) $(TOMMATH_DIR)/win64-arm/${TOMMATH_DLL_FILE} ${TOMMATH_DLL_FILE}; \
+ elif test "@TOMMATH_LIBS@set" = "${TOMMATH_DIR_NATIVE}/win64-arm/libtommath.dll.aset" ; then \
+ $(COPY) $(TOMMATH_DIR)/win64-arm/${TOMMATH_DLL_FILE} ${TOMMATH_DLL_FILE}; \
+ elif test "@TOMMATH_LIBS@set" = "${TOMMATH_DIR_NATIVE}/win32/tommath.libset" ; then \
$(COPY) $(TOMMATH_DIR)/win32/${TOMMATH_DLL_FILE} ${TOMMATH_DLL_FILE}; \
+ else \
+ $(COPY) $(TOMMATH_DIR)/win64/${TOMMATH_DLL_FILE} ${TOMMATH_DLL_FILE}; \
fi;
# Add the object extension to the implicit rules. By default .obj is not
diff --git a/win/tclWinInit.c b/win/tclWinInit.c
index 510b6df..d682006 100644
--- a/win/tclWinInit.c
+++ b/win/tclWinInit.c
@@ -566,9 +566,6 @@ TclpSetVariables(
*----------------------------------------------------------------------
*/
-# define tenviron2utfdstr(string, len, dsPtr) \
- (char *)Tcl_Char16ToUtfDString((const unsigned short *)(string), ((((len) + 2) >> 1) - 1), (dsPtr))
-
Tcl_Size
TclpFindVariable(
const char *name, /* Name of desired environment variable