summaryrefslogtreecommitdiffstats
path: root/unix
diff options
context:
space:
mode:
authorapnadkarni <apnmbx-wits@yahoo.com>2023-07-27 16:26:38 (GMT)
committerapnadkarni <apnmbx-wits@yahoo.com>2023-07-27 16:26:38 (GMT)
commite253c3eed9122505c8c33fa337ccab63a75675c2 (patch)
tree92a176fadbeb5743cb12c73279115a05171cfd7d /unix
parent7f10145e496d9a3b8973e2c9d92c606d504fa0f8 (diff)
parentaf64c95042a9706c6d45118c8f341aafa5c26686 (diff)
downloadtcl-e253c3eed9122505c8c33fa337ccab63a75675c2.zip
tcl-e253c3eed9122505c8c33fa337ccab63a75675c2.tar.gz
tcl-e253c3eed9122505c8c33fa337ccab63a75675c2.tar.bz2
Merge trunk
Diffstat (limited to 'unix')
-rw-r--r--unix/Makefile.in3
-rwxr-xr-xunix/configure186
-rw-r--r--unix/configure.ac3
-rw-r--r--unix/tcl.m437
-rw-r--r--unix/tcl.pc.in4
-rw-r--r--unix/tclConfig.h.in24
-rw-r--r--unix/tclUnixFCmd.c5
-rw-r--r--unix/tclUnixPipe.c92
-rw-r--r--unix/tclUnixPort.h28
9 files changed, 294 insertions, 88 deletions
diff --git a/unix/Makefile.in b/unix/Makefile.in
index d35074e..2068c86 100644
--- a/unix/Makefile.in
+++ b/unix/Makefile.in
@@ -396,8 +396,7 @@ GENERIC_HDRS = \
$(GENERIC_DIR)/tclPatch.h \
$(GENERIC_DIR)/tclPlatDecls.h \
$(GENERIC_DIR)/tclPort.h \
- $(GENERIC_DIR)/tclRegexp.h \
- $(GENERIC_DIR)/tclArithSeries.h
+ $(GENERIC_DIR)/tclRegexp.h
GENERIC_SRCS = \
$(GENERIC_DIR)/regcomp.c \
diff --git a/unix/configure b/unix/configure
index 3f93ef3..c0a5575 100755
--- a/unix/configure
+++ b/unix/configure
@@ -737,6 +737,8 @@ RANLIB
TOMMATH_INCLUDE
TOMMATH_SRCS
TOMMATH_OBJS
+TCL_PC_CFLAGS
+TCL_PC_REQUIRES_PRIVATE
ZLIB_INCLUDE
ZLIB_SRCS
ZLIB_OBJS
@@ -5139,6 +5141,10 @@ fi
if test $libtommath_ok = yes
then :
+ TCL_PC_REQUIRES_PRIVATE='libtommath >= 1.2.0,'
+
+ TCL_PC_CFLAGS='-DTCL_WITH_EXTERNAL_TOMMATH'
+
printf "%s\n" "#define TCL_WITH_EXTERNAL_TOMMATH 1" >>confdefs.h
@@ -7323,6 +7329,33 @@ printf "%s\n" "#define HAVE_STDBOOL_H 1" >>confdefs.h
fi
+ # Check for vfork, posix_spawnp() and friends unconditionally
+ ac_fn_c_check_func "$LINENO" "vfork" "ac_cv_func_vfork"
+if test "x$ac_cv_func_vfork" = xyes
+then :
+ printf "%s\n" "#define HAVE_VFORK 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "posix_spawnp" "ac_cv_func_posix_spawnp"
+if test "x$ac_cv_func_posix_spawnp" = xyes
+then :
+ printf "%s\n" "#define HAVE_POSIX_SPAWNP 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "posix_spawn_file_actions_adddup2" "ac_cv_func_posix_spawn_file_actions_adddup2"
+if test "x$ac_cv_func_posix_spawn_file_actions_adddup2" = xyes
+then :
+ printf "%s\n" "#define HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "posix_spawnattr_setflags" "ac_cv_func_posix_spawnattr_setflags"
+if test "x$ac_cv_func_posix_spawnattr_setflags" = xyes
+then :
+ printf "%s\n" "#define HAVE_POSIX_SPAWNATTR_SETFLAGS 1" >>confdefs.h
+
+fi
+
+
# FIXME: This subst was left in only because the TCL_DL_LIBS
# entry in tclConfig.sh uses it. It is not clear why someone
# would use TCL_DL_LIBS instead of TCL_LIBS.
@@ -7486,6 +7519,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
@@ -7586,9 +7669,9 @@ 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 struct dirent64" >&5
-printf %s "checking for struct dirent64... " >&6; }
-if test ${tcl_cv_struct_dirent64+y}
+ { 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
@@ -7596,34 +7679,66 @@ else $as_nop
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <sys/types.h>
-#include <dirent.h>
int
main (void)
{
-struct dirent64 p;
+switch (0) {case 0: case (sizeof(time_t)==sizeof(long long)): ;}
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
- tcl_cv_struct_dirent64=yes
+ tcl_cv_time_t_64=yes
else $as_nop
- tcl_cv_struct_dirent64=no
+ 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_struct_dirent64" >&5
-printf "%s\n" "$tcl_cv_struct_dirent64" >&6; }
- if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then
+{ 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
-printf "%s\n" "#define HAVE_STRUCT_DIRENT64 1" >>confdefs.h
+ 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 DIR64" >&5
-printf %s "checking for DIR64... " >&6; }
-if test ${tcl_cv_DIR64+y}
+ { 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}
then :
printf %s "(cached) " >&6
else $as_nop
@@ -7635,60 +7750,60 @@ else $as_nop
int
main (void)
{
-struct dirent64 *p; DIR64 d = opendir64(".");
- p = readdir64(d); rewinddir64(d); closedir64(d);
+struct dirent64 p;
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
- tcl_cv_DIR64=yes
+ tcl_cv_struct_dirent64=yes
else $as_nop
- tcl_cv_DIR64=no
+ tcl_cv_struct_dirent64=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_DIR64" >&5
-printf "%s\n" "$tcl_cv_DIR64" >&6; }
- if test "x${tcl_cv_DIR64}" = "xyes" ; then
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_struct_dirent64" >&5
+printf "%s\n" "$tcl_cv_struct_dirent64" >&6; }
+ if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then
-printf "%s\n" "#define HAVE_DIR64 1" >>confdefs.h
+printf "%s\n" "#define HAVE_STRUCT_DIRENT64 1" >>confdefs.h
fi
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for struct stat64" >&5
-printf %s "checking for struct stat64... " >&6; }
-if test ${tcl_cv_struct_stat64+y}
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for DIR64" >&5
+printf %s "checking for DIR64... " >&6; }
+if test ${tcl_cv_DIR64+y}
then :
printf %s "(cached) " >&6
else $as_nop
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-#include <sys/stat.h>
+#include <sys/types.h>
+#include <dirent.h>
int
main (void)
{
-struct stat64 p;
-
+struct dirent64 *p; DIR64 d = opendir64(".");
+ p = readdir64(d); rewinddir64(d); closedir64(d);
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
- tcl_cv_struct_stat64=yes
+ tcl_cv_DIR64=yes
else $as_nop
- tcl_cv_struct_stat64=no
+ tcl_cv_DIR64=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_struct_stat64" >&5
-printf "%s\n" "$tcl_cv_struct_stat64" >&6; }
- if test "x${tcl_cv_struct_stat64}" = "xyes" ; then
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_DIR64" >&5
+printf "%s\n" "$tcl_cv_DIR64" >&6; }
+ if test "x${tcl_cv_DIR64}" = "xyes" ; then
-printf "%s\n" "#define HAVE_STRUCT_STAT64 1" >>confdefs.h
+printf "%s\n" "#define HAVE_DIR64 1" >>confdefs.h
fi
@@ -10072,9 +10187,6 @@ fi
fi
-printf "%s\n" "#define USE_VFORK 1" >>confdefs.h
-
-
printf "%s\n" "#define TCL_LOAD_FROM_MEMORY 1" >>confdefs.h
diff --git a/unix/configure.ac b/unix/configure.ac
index f7538c3..633b568 100644
--- a/unix/configure.ac
+++ b/unix/configure.ac
@@ -185,6 +185,8 @@ if test x"${libtommath_ok}" = x -o x"${libtommath_ok}" != xno; then
libtommath_ok=no])])
fi
AS_IF([test $libtommath_ok = yes], [
+ AC_SUBST(TCL_PC_REQUIRES_PRIVATE, ['libtommath >= 1.2.0,'])
+ AC_SUBST(TCL_PC_CFLAGS, ['-DTCL_WITH_EXTERNAL_TOMMATH'])
AC_DEFINE(TCL_WITH_EXTERNAL_TOMMATH, 1, [Tcl with external libtommath])
], [
AC_SUBST(TOMMATH_OBJS,[\${TOMMATH_OBJS}])
@@ -540,7 +542,6 @@ if test "`uname -s`" = "Darwin" ; then
AC_CHECK_HEADERS(libkern/OSAtomic.h)
AC_CHECK_FUNCS(OSSpinLockLock)
fi
- AC_DEFINE(USE_VFORK, 1, [Should we use vfork() instead of fork()?])
AC_DEFINE(TCL_LOAD_FROM_MEMORY, 1,
[Can this platform load code from memory?])
AC_DEFINE(TCL_WIDE_CLICKS, 1,
diff --git a/unix/tcl.m4 b/unix/tcl.m4
index 9dc39f2..fca47cc 100644
--- a/unix/tcl.m4
+++ b/unix/tcl.m4
@@ -1877,6 +1877,9 @@ dnl # preprocessing tests use only CPPFLAGS.
AC_CHECK_HEADER(stdbool.h, [AC_DEFINE(HAVE_STDBOOL_H, 1, [Do we have <stdbool.h>?])],)
+ # Check for vfork, posix_spawnp() and friends unconditionally
+ AC_CHECK_FUNCS(vfork posix_spawnp posix_spawn_file_actions_adddup2 posix_spawnattr_setflags)
+
# FIXME: This subst was left in only because the TCL_DL_LIBS
# entry in tclConfig.sh uses it. It is not clear why someone
# would use TCL_DL_LIBS instead of TCL_LIBS.
@@ -2294,6 +2297,7 @@ AC_DEFUN([SC_TCL_LINK_LIBS], [
#
# Might define the following vars:
# _ISOC99_SOURCE
+# _FILE_OFFSET_BITS
# _LARGEFILE64_SOURCE
#
#--------------------------------------------------------------------
@@ -2301,12 +2305,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 +2320,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
@@ -2338,8 +2344,8 @@ AC_DEFUN([SC_TCL_EARLY_FLAGS],[
# Might define the following vars:
# TCL_WIDE_INT_IS_LONG
# HAVE_STRUCT_DIRENT64, HAVE_DIR64
-# HAVE_STRUCT_STAT64
# HAVE_TYPE_OFF64_T
+# _TIME_BITS
#
#--------------------------------------------------------------------
@@ -2359,6 +2365,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;]])],
@@ -2376,14 +2399,6 @@ AC_DEFUN([SC_TCL_64BIT_FLAGS], [
AC_DEFINE(HAVE_DIR64, 1, [Is 'DIR64' in <sys/types.h>?])
fi
- AC_CACHE_CHECK([for struct stat64], tcl_cv_struct_stat64,[
- AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/stat.h>]], [[struct stat64 p;
-]])],
- [tcl_cv_struct_stat64=yes], [tcl_cv_struct_stat64=no])])
- if test "x${tcl_cv_struct_stat64}" = "xyes" ; then
- AC_DEFINE(HAVE_STRUCT_STAT64, 1, [Is 'struct stat64' in <sys/stat.h>?])
- fi
-
AC_CHECK_FUNCS(open64 lseek64)
AC_MSG_CHECKING([for off64_t])
AC_CACHE_VAL(tcl_cv_type_off64_t,[
diff --git a/unix/tcl.pc.in b/unix/tcl.pc.in
index 5f90c41..9c6da82 100644
--- a/unix/tcl.pc.in
+++ b/unix/tcl.pc.in
@@ -10,7 +10,7 @@ Name: Tool Command Language
Description: Tcl is a powerful, easy-to-learn dynamic programming language, suitable for a wide range of uses.
URL: https://www.tcl-lang.org/
Version: @TCL_VERSION@@TCL_PATCH_LEVEL@
-Requires.private: zlib >= 1.2.3, libtommath >= 1.2.0
+Requires.private: @TCL_PC_REQUIRES_PRIVATE@ zlib >= 1.2.3
Libs: -L${libdir} @TCL_LIB_FLAG@ @TCL_STUB_LIB_FLAG@
Libs.private: @TCL_LIBS@
-Cflags: -I${includedir}
+Cflags: -I${includedir} @TCL_PC_CFLAGS@
diff --git a/unix/tclConfig.h.in b/unix/tclConfig.h.in
index fe2c6d9..8500afb 100644
--- a/unix/tclConfig.h.in
+++ b/unix/tclConfig.h.in
@@ -181,6 +181,15 @@
/* Define to 1 if you have the `OSSpinLockLock' function. */
#undef HAVE_OSSPINLOCKLOCK
+/* Define to 1 if you have the `posix_spawnattr_setflags' function. */
+#undef HAVE_POSIX_SPAWNATTR_SETFLAGS
+
+/* Define to 1 if you have the `posix_spawnp' function. */
+#undef HAVE_POSIX_SPAWNP
+
+/* Define to 1 if you have the `posix_spawn_file_actions_adddup2' function. */
+#undef HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2
+
/* Should we use pselect()? */
#undef HAVE_PSELECT
@@ -229,9 +238,6 @@
/* Define to 1 if the system has the type `struct sockaddr_storage'. */
#undef HAVE_STRUCT_SOCKADDR_STORAGE
-/* Is 'struct stat64' in <sys/stat.h>? */
-#undef HAVE_STRUCT_STAT64
-
/* Define to 1 if `st_blksize' is a member of `struct stat'. */
#undef HAVE_STRUCT_STAT_ST_BLKSIZE
@@ -295,6 +301,9 @@
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
+/* Define to 1 if you have the `vfork' function. */
+#undef HAVE_VFORK
+
/* Define to 1 if you have the `waitpid' function. */
#undef HAVE_WAITPID
@@ -450,9 +459,6 @@
/* Should we use FIONBIO? */
#undef USE_FIONBIO
-/* Should we use vfork() instead of fork()? */
-#undef USE_VFORK
-
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */
#if defined AC_APPLE_UNIVERSAL_BUILD
@@ -471,6 +477,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 +498,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/unix/tclUnixFCmd.c b/unix/tclUnixFCmd.c
index b260cf4..dce71c4 100644
--- a/unix/tclUnixFCmd.c
+++ b/unix/tclUnixFCmd.c
@@ -266,10 +266,7 @@ MODULE_SCOPE long tclMacOSXDarwinRelease;
#endif /* NO_REALPATH */
#ifdef HAVE_FTS
-#if defined(HAVE_STRUCT_STAT64) && !defined(__APPLE__)
-/* fts doesn't do stat64 */
-# define noFtsStat 1
-#elif defined(__APPLE__) && defined(__LP64__) && \
+#if defined(__APPLE__) && defined(__LP64__) && \
defined(MAC_OS_X_VERSION_MIN_REQUIRED) && \
MAC_OS_X_VERSION_MIN_REQUIRED < 1050
/*
diff --git a/unix/tclUnixPipe.c b/unix/tclUnixPipe.c
index c1fae5d..4e8a758 100644
--- a/unix/tclUnixPipe.c
+++ b/unix/tclUnixPipe.c
@@ -13,7 +13,18 @@
#include "tclInt.h"
-#ifdef USE_VFORK
+#ifdef HAVE_POSIX_SPAWNP
+# if defined(HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2) \
+ && defined(HAVE_POSIX_SPAWNATTR_SETFLAGS) \
+ && !defined(HAVE_VFORK)
+# include <unistd.h>
+# include <spawn.h>
+# else
+# undef HAVE_POSIX_SPAWNP
+# endif
+#endif
+
+#ifdef HAVE_VFORK
#define fork vfork
#endif
@@ -412,6 +423,10 @@ TclpCreateProcess(
char **newArgv;
int pid;
size_t i;
+#if defined(HAVE_POSIX_SPAWNP)
+ int childErrno;
+ static int use_spawn = -1;
+#endif
errPipeIn = NULL;
errPipeOut = NULL;
@@ -440,7 +455,7 @@ TclpCreateProcess(
newArgv[i] = Tcl_UtfToExternalDString(NULL, argv[i], TCL_INDEX_NONE, &dsArray[i]);
}
-#ifdef USE_VFORK
+#if defined(HAVE_VFORK) || defined(HAVE_POSIX_SPAWNP)
/*
* After vfork(), do not call code in the child that changes global state,
* because it is using the parent's memory space at that point and writes
@@ -453,14 +468,80 @@ TclpCreateProcess(
Tcl_GetStdChannel(TCL_STDIN);
}
if (!outputFile) {
- Tcl_GetStdChannel(TCL_STDOUT);
+ Tcl_GetStdChannel(TCL_STDOUT);
}
if (!errorFile) {
- Tcl_GetStdChannel(TCL_STDERR);
+ Tcl_GetStdChannel(TCL_STDERR);
}
#endif
+#ifdef HAVE_POSIX_SPAWNP
+#ifdef _CS_GNU_LIBC_VERSION
+ if (use_spawn < 0) {
+ char conf[32], *p;
+ int major = 0, minor = 0;
+
+ use_spawn = 0;
+ memset(conf, 0, sizeof(conf));
+ confstr(_CS_GNU_LIBC_VERSION, conf, sizeof(conf));
+ p = strchr(conf, ' '); /* skip "glibc" */
+ if (p != NULL) {
+ ++p;
+ if (sscanf(p, "%d.%d", &major, &minor) > 1) {
+ if ((major > 2) || ((major == 2) && (minor >= 24))) {
+ use_spawn = 1;
+ }
+ }
+ }
+ }
+#endif
+ status = -1;
+ if (use_spawn) {
+ posix_spawn_file_actions_t actions;
+ posix_spawnattr_t attr;
+ sigset_t sigs;
+
+ posix_spawn_file_actions_init(&actions);
+ posix_spawnattr_init(&attr);
+ sigfillset(&sigs);
+ sigdelset(&sigs, SIGKILL);
+ sigdelset(&sigs, SIGSTOP);
+
+ posix_spawnattr_setflags(&attr,
+ POSIX_SPAWN_SETSIGDEF
+#ifdef POSIX_SPAWN_USEVFORK
+ | POSIX_SPAWN_USEVFORK
+#endif
+ );
+ posix_spawnattr_setsigdefault(&attr, &sigs);
+
+ posix_spawn_file_actions_adddup2(&actions, GetFd(inputFile), 0);
+ posix_spawn_file_actions_adddup2(&actions, GetFd(outputFile), 1);
+ posix_spawn_file_actions_adddup2(&actions, GetFd(errorFile), 2);
+
+ status = posix_spawnp(&pid, newArgv[0], &actions, &attr,
+ newArgv, environ);
+ childErrno = errno;
+ posix_spawn_file_actions_destroy(&actions);
+ posix_spawnattr_destroy(&attr);
+
+ /*
+ * Fork semantics:
+ * - pid == 0: child process
+ * - pid == -1: error
+ * - pid > 0: parent process
+ *
+ * Mimic fork semantics to minimize changes below,
+ * but retry with fork() as last ressort.
+ */
+ }
+ if (status != 0) {
+ pid = fork();
+ childErrno = errno;
+ }
+#else
pid = fork();
+#endif
if (pid == 0) {
size_t len;
int joinThisError = errorFile && (errorFile == outputFile);
@@ -510,6 +591,9 @@ TclpCreateProcess(
TclStackFree(interp, dsArray);
if (pid == -1) {
+#ifdef HAVE_POSIX_SPAWNP
+ errno = childErrno;
+#endif
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"couldn't fork child process: %s", Tcl_PosixError(interp)));
goto error;
diff --git a/unix/tclUnixPort.h b/unix/tclUnixPort.h
index 33c8971..cdc67d2 100644
--- a/unix/tclUnixPort.h
+++ b/unix/tclUnixPort.h
@@ -115,10 +115,6 @@ extern "C" {
#ifdef __cplusplus
}
#endif
-#elif defined(HAVE_STRUCT_STAT64) && !defined(__APPLE__)
-# define TclOSfstat(fd, buf) fstat64(fd, (struct stat64 *)buf)
-# define TclOSstat(name, buf) stat64(name, (struct stat64 *)buf)
-# define TclOSlstat(name,buf) lstat64(name, (struct stat64 *)buf)
#else
# define TclOSfstat(fd, buf) fstat(fd, (struct stat *)buf)
# define TclOSstat(name, buf) stat(name, (struct stat *)buf)
@@ -609,23 +605,13 @@ extern char ** environ;
defined(HAVE_WEAK_IMPORT) && MAC_OS_X_VERSION_MIN_REQUIRED < 1050
# warning "Weak import of 64-bit CoreFoundation is not supported, will not run on Mac OS X < 10.5."
# endif
-
-/*
- *---------------------------------------------------------------------------
- * At present, using vfork() instead of fork() causes execve() to fail
- * intermittently on Darwin x86_64. rdar://4685553
- *---------------------------------------------------------------------------
- */
-
-# if defined(__x86_64__) && !defined(FIXED_RDAR_4685553)
-# undef USE_VFORK
-# endif /* __x86_64__ */
-/* Workaround problems with vfork() when building with llvm-gcc-4.2 */
-# if defined (__llvm__) && \
- (__GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ > 2 || \
- (__GNUC_MINOR__ == 2 && __GNUC_PATCHLEVEL__ > 0))))
-# undef USE_VFORK
-# endif /* __llvm__ */
+ /*
+ * For now, test exec-17.1 fails (I/O setup after closing stdout) with
+ * posix_spawnp(), but the classic implementation (based on fork()+execvp())
+ * works well under macOS.
+ */
+# undef HAVE_POSIX_SPAWNP
+# undef HAVE_VFORK
#endif /* __APPLE__ */
/*