summaryrefslogtreecommitdiffstats
path: root/unix
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2014-07-15 13:18:33 (GMT)
committerdgp <dgp@users.sourceforge.net>2014-07-15 13:18:33 (GMT)
commit64c066f9bb2daa64cc0cf366d0c0812a828d2d61 (patch)
tree934228bab58b4be058c64ed75ac9363292cc7474 /unix
parent773c4c75ee2ec9d60766f09ced30a5fef6d812c6 (diff)
parent74d71bafde63ca49cecadc990df7b3a2d7797849 (diff)
downloadtcl-dgp_pkg_migration.zip
tcl-dgp_pkg_migration.tar.gz
tcl-dgp_pkg_migration.tar.bz2
Diffstat (limited to 'unix')
-rw-r--r--unix/Makefile.in182
-rw-r--r--unix/README5
-rwxr-xr-xunix/configure845
-rw-r--r--unix/configure.in25
-rw-r--r--unix/dltest/Makefile.in15
-rw-r--r--unix/dltest/pkgb.c4
-rw-r--r--unix/dltest/pkgooa.c141
-rw-r--r--unix/tcl.m4289
-rw-r--r--unix/tcl.pc.in8
-rw-r--r--unix/tcl.spec2
-rw-r--r--unix/tclAppInit.c22
-rw-r--r--unix/tclConfig.h.in18
-rw-r--r--unix/tclConfig.sh.in2
-rw-r--r--unix/tclUnixChan.c412
-rw-r--r--unix/tclUnixCompat.c15
-rw-r--r--unix/tclUnixFCmd.c195
-rw-r--r--unix/tclUnixFile.c13
-rw-r--r--unix/tclUnixInit.c31
-rw-r--r--unix/tclUnixNotfy.c125
-rw-r--r--unix/tclUnixPipe.c10
-rw-r--r--unix/tclUnixPort.h66
-rw-r--r--unix/tclUnixSock.c354
-rw-r--r--unix/tclUnixTest.c58
-rw-r--r--unix/tclUnixThrd.c2
-rw-r--r--unix/tclUnixTime.c2
-rw-r--r--unix/tclXtNotify.c26
-rw-r--r--unix/tclooConfig.sh2
27 files changed, 1437 insertions, 1432 deletions
diff --git a/unix/Makefile.in b/unix/Makefile.in
index ee31282..5a2d9af 100644
--- a/unix/Makefile.in
+++ b/unix/Makefile.in
@@ -291,24 +291,24 @@ XTTEST_OBJS = xtTestInit.o tclTest.o tclTestObj.o tclTestProcBodyObj.o \
tclThreadTest.o tclUnixTest.o tclXtNotify.o tclXtTest.o
GENERIC_OBJS = regcomp.o regexec.o regfree.o regerror.o tclAlloc.o \
- tclAsync.o tclBasic.o tclBinary.o tclCkalloc.o tclClock.o \
- tclCmdAH.o tclCmdIL.o tclCmdMZ.o tclCompCmds.o tclCompCmdsSZ.o \
- tclCompExpr.o tclCompile.o tclConfig.o tclDate.o tclDictObj.o \
+ tclAssembly.o tclAsync.o tclBasic.o tclBinary.o tclCkalloc.o \
+ tclClock.o tclCmdAH.o tclCmdIL.o tclCmdMZ.o \
+ tclCompCmds.o tclCompCmdsGR.o tclCompCmdsSZ.o tclCompExpr.o \
+ tclCompile.o tclConfig.o tclDate.o tclDictObj.o \
tclEncoding.o tclEnsemble.o \
tclEnv.o tclEvent.o tclExecute.o tclFCmd.o tclFileName.o tclGet.o \
tclHash.o tclHistory.o tclIndexObj.o tclInterp.o tclIO.o tclIOCmd.o \
tclIORChan.o tclIORTrans.o tclIOGT.o tclIOSock.o tclIOUtil.o \
tclLink.o tclListObj.o \
tclLiteral.o tclLoad.o tclMain.o tclNamesp.o tclNotify.o \
- tclObj.o tclPanic.o tclParse.o tclPathObj.o tclPipe.o \
+ tclObj.o tclOptimize.o tclPanic.o tclParse.o tclPathObj.o tclPipe.o \
tclPkg.o tclPkgConfig.o tclPosixStr.o \
tclPreserve.o tclProc.o tclRegexp.o \
tclResolve.o tclResult.o tclScan.o tclStringObj.o \
tclStrToD.o tclThread.o \
tclThreadAlloc.o tclThreadJoin.o tclThreadStorage.o tclStubInit.o \
tclTimer.o tclTrace.o tclUtf.o tclUtil.o tclVar.o tclZlib.o \
- tclTomMathInterface.o \
- tclAssembly.o
+ tclTomMathInterface.o
OO_OBJS = tclOO.o tclOOBasic.o tclOOCall.o tclOODefineCmds.o tclOOInfo.o \
tclOOMethod.o tclOOStubInit.o
@@ -335,7 +335,10 @@ TOMMATH_OBJS = bncore.o bn_reverse.o bn_fast_s_mp_mul_digs.o \
bn_mp_unsigned_bin_size.o bn_mp_xor.o bn_mp_zero.o bn_s_mp_add.o \
bn_s_mp_mul_digs.o bn_s_mp_sqr.o bn_s_mp_sub.o
-STUB_LIB_OBJS = tclStubLib.o tclTomMathStubLib.o tclOOStubLib.o ${COMPAT_OBJS}
+STUB_LIB_OBJS = tclStubLib.o \
+ tclTomMathStubLib.o \
+ tclOOStubLib.o \
+ ${COMPAT_OBJS}
UNIX_OBJS = tclUnixChan.o tclUnixEvent.o tclUnixFCmd.o \
tclUnixFile.o tclUnixPipe.o tclUnixSock.o \
@@ -346,6 +349,8 @@ NOTIFY_OBJS = tclUnixNotfy.o
MAC_OSX_OBJS = tclMacOSXBundle.o tclMacOSXFCmd.o tclMacOSXNotify.o
+CYGWIN_OBJS = tclWinError.o
+
DTRACE_OBJ = tclDTrace.o
ZLIB_OBJS = Zadler32.o Zcompress.o Zcrc32.o Zdeflate.o Zinfback.o \
@@ -395,6 +400,7 @@ GENERIC_SRCS = \
$(GENERIC_DIR)/tclCmdIL.c \
$(GENERIC_DIR)/tclCmdMZ.c \
$(GENERIC_DIR)/tclCompCmds.c \
+ $(GENERIC_DIR)/tclCompCmdsGR.c \
$(GENERIC_DIR)/tclCompCmdsSZ.c \
$(GENERIC_DIR)/tclCompExpr.c \
$(GENERIC_DIR)/tclCompile.c \
@@ -428,6 +434,7 @@ GENERIC_SRCS = \
$(GENERIC_DIR)/tclNamesp.c \
$(GENERIC_DIR)/tclNotify.c \
$(GENERIC_DIR)/tclObj.c \
+ $(GENERIC_DIR)/tclOptimize.c \
$(GENERIC_DIR)/tclParse.c \
$(GENERIC_DIR)/tclPathObj.c \
$(GENERIC_DIR)/tclPipe.c \
@@ -573,6 +580,9 @@ MAC_OSX_SRCS = \
$(MAC_OSX_DIR)/tclMacOSXFCmd.c \
$(MAC_OSX_DIR)/tclMacOSXNotify.c
+CYGWIN_SRCS = \
+ $(TOP_DIR)/win/tclWinError.c
+
DTRACE_HDR = tclDTrace.h
DTRACE_SRC = $(GENERIC_DIR)/tclDTrace.d
@@ -603,7 +613,7 @@ SRCS = $(GENERIC_SRCS) $(TOMMATH_SRCS) $(UNIX_SRCS) $(NOTIFY_SRCS) \
all: binaries libraries doc packages
-binaries: ${LIB_FILE} $(STUB_LIB_FILE) ${TCL_EXE}
+binaries: ${LIB_FILE} ${TCL_EXE}
libraries:
@@ -611,15 +621,14 @@ doc:
# The following target is configured by autoconf to generate either a shared
# library or non-shared library for Tcl.
-${LIB_FILE}: ${OBJS} ${STUB_LIB_FILE}
+${LIB_FILE}: ${STUB_LIB_FILE} ${OBJS}
rm -f $@
@MAKE_LIB@
- @if test "x$(DLL_INSTALL_DIR)" = "x$(BIN_INSTALL_DIR)"; then\
- cp ${ZLIB_DIR}/win32/zlib1.dll .;\
- fi
-
${STUB_LIB_FILE}: ${STUB_LIB_OBJS}
+ @if test "x${LIB_FILE}" = "xlibtcl${MAJOR_VERSION}.${MINOR_VERSION}.dll"; then \
+ (cd ${TOP_DIR}/win; ${MAKE} tcldde14.dll tclreg13.dll); \
+ fi
rm -f $@
@MAKE_STUB_LIB@
@@ -633,9 +642,9 @@ tclLibObjs:
# This targets actually build the objects needed for the lib in the above case
objs: ${OBJS}
-${TCL_EXE}: ${TCLSH_OBJS} ${TCL_LIB_FILE}
+${TCL_EXE}: ${TCLSH_OBJS} ${TCL_LIB_FILE} ${TCL_STUB_LIB_FILE}
${CC} ${CFLAGS} ${LDFLAGS} ${TCLSH_OBJS} \
- @TCL_BUILD_LIB_SPEC@ ${LIBS} @EXTRA_TCLSH_LIBS@ \
+ @TCL_BUILD_LIB_SPEC@ ${TCL_STUB_LIB_FILE} ${LIBS} @EXTRA_TCLSH_LIBS@ \
${CC_SEARCH_FLAGS} -o ${TCL_EXE}
# Must be empty so it doesn't conflict with rule for ${TCL_EXE} above
@@ -787,11 +796,6 @@ install-binaries: binaries
else true; \
fi; \
done;
- @if test "x$(DLL_INSTALL_DIR)" = "x$(BIN_INSTALL_DIR)"; then\
- echo "Installing zlib1.dll to $(BIN_INSTALL_DIR)/";\
- $(INSTALL_LIBRARY) zlib1.dll "$(BIN_INSTALL_DIR)";\
- chmod 555 "$(BIN_INSTALL_DIR)/zlib1.dll";\
- fi
@echo "Installing $(LIB_FILE) to $(DLL_INSTALL_DIR)/"
@@INSTALL_LIB@
@chmod 555 "$(DLL_INSTALL_DIR)/$(LIB_FILE)"
@@ -839,20 +843,20 @@ install-libraries: libraries
do \
$(INSTALL_DATA) $$i "$(SCRIPT_INSTALL_DIR)"/http1.0; \
done;
- @echo "Installing package http 2.8.6 as a Tcl Module";
- @$(INSTALL_DATA) $(TOP_DIR)/library/http/http.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.6/http-2.8.6.tm;
+ @echo "Installing package http 2.8.8 as a Tcl Module";
+ @$(INSTALL_DATA) $(TOP_DIR)/library/http/http.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.6/http-2.8.8.tm;
@echo "Installing package opt0.4 files to $(SCRIPT_INSTALL_DIR)/opt0.4/";
@for i in $(TOP_DIR)/library/opt/*.tcl ; \
do \
$(INSTALL_DATA) $$i "$(SCRIPT_INSTALL_DIR)"/opt0.4; \
done;
- @echo "Installing package msgcat 1.5.0 as a Tcl Module";
- @$(INSTALL_DATA) $(TOP_DIR)/library/msgcat/msgcat.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.5/msgcat-1.5.0.tm;
- @echo "Installing package tcltest 2.3.5 as a Tcl Module";
- @$(INSTALL_DATA) $(TOP_DIR)/library/tcltest/tcltest.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.5/tcltest-2.3.5.tm;
+ @echo "Installing package msgcat 1.5.2 as a Tcl Module";
+ @$(INSTALL_DATA) $(TOP_DIR)/library/msgcat/msgcat.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.5/msgcat-1.5.2.tm;
+ @echo "Installing package tcltest 2.3.8 as a Tcl Module";
+ @$(INSTALL_DATA) $(TOP_DIR)/library/tcltest/tcltest.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.5/tcltest-2.3.8.tm;
- @echo "Installing package platform 1.0.10 as a Tcl Module";
- @$(INSTALL_DATA) $(TOP_DIR)/library/platform/platform.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.4/platform-1.0.10.tm;
+ @echo "Installing package platform 1.0.12 as a Tcl Module";
+ @$(INSTALL_DATA) $(TOP_DIR)/library/platform/platform.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.4/platform-1.0.12.tm;
@echo "Installing package platform::shell 1.1.4 as a Tcl Module";
@$(INSTALL_DATA) $(TOP_DIR)/library/platform/shell.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.4/platform/shell-1.1.4.tm;
@@ -866,10 +870,39 @@ install-libraries: libraries
"$(SCRIPT_INSTALL_DIR)"/tm.tcl; \
fi
-install-tzdata: ${NATIVE_TCLSH}
+install-tzdata:
+ @for i in tzdata; \
+ do \
+ if [ ! -d "$(SCRIPT_INSTALL_DIR)"/$$i ] ; then \
+ echo "Making directory $(SCRIPT_INSTALL_DIR)/$$i"; \
+ $(INSTALL_DATA_DIR) "$(SCRIPT_INSTALL_DIR)"/$$i; \
+ else true; \
+ fi; \
+ done;
@echo "Installing time zone files to $(SCRIPT_INSTALL_DIR)/tzdata/"
- @${NATIVE_TCLSH} $(TOOL_DIR)/installData.tcl \
- $(TOP_DIR)/library/tzdata "$(SCRIPT_INSTALL_DIR)"/tzdata
+ @for i in $(TOP_DIR)/library/tzdata/* ; do \
+ if [ -d $$i ] ; then \
+ ii=`basename $$i`; \
+ if [ ! -d "$(SCRIPT_INSTALL_DIR)"/tzdata/$$ii ] ; then \
+ $(INSTALL_DATA_DIR) "$(SCRIPT_INSTALL_DIR)"/tzdata/$$ii; \
+ fi; \
+ for j in $$i/* ; do \
+ if [ -d $$j ] ; then \
+ jj=`basename $$j`; \
+ if [ ! -d "$(SCRIPT_INSTALL_DIR)"/tzdata/$$ii/$$jj ] ; then \
+ $(INSTALL_DATA_DIR) "$(SCRIPT_INSTALL_DIR)"/tzdata/$$ii/$$jj; \
+ fi; \
+ for k in $$j/* ; do \
+ $(INSTALL_DATA) $$k "$(SCRIPT_INSTALL_DIR)"/tzdata/$$ii/$$jj; \
+ done; \
+ else \
+ $(INSTALL_DATA) $$j "$(SCRIPT_INSTALL_DIR)"/tzdata/$$ii; \
+ fi; \
+ done; \
+ else \
+ $(INSTALL_DATA) $$i "$(SCRIPT_INSTALL_DIR)"/tzdata; \
+ fi; \
+ done;
install-msgs:
@for i in msgs; \
@@ -1002,6 +1035,7 @@ IOHDR=$(GENERIC_DIR)/tclIO.h
MATHHDRS=$(GENERIC_DIR)/tommath.h $(GENERIC_DIR)/tclTomMath.h
PARSEHDR=$(GENERIC_DIR)/tclParse.h
NREHDR=$(GENERIC_DIR)/tclInt.h
+TRIMHDR=$(GENERIC_DIR)/tclStringTrim.h
regcomp.o: $(REGHDRS) $(GENERIC_DIR)/regcomp.c $(GENERIC_DIR)/regc_lex.c \
$(GENERIC_DIR)/regc_color.c $(GENERIC_DIR)/regc_locale.c \
@@ -1047,7 +1081,7 @@ tclCmdAH.o: $(GENERIC_DIR)/tclCmdAH.c
tclCmdIL.o: $(GENERIC_DIR)/tclCmdIL.c $(TCLREHDRS)
$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclCmdIL.c
-tclCmdMZ.o: $(GENERIC_DIR)/tclCmdMZ.c $(TCLREHDRS)
+tclCmdMZ.o: $(GENERIC_DIR)/tclCmdMZ.c $(TCLREHDRS) $(TRIMHDR)
$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclCmdMZ.c
tclDate.o: $(GENERIC_DIR)/tclDate.c
@@ -1056,7 +1090,10 @@ tclDate.o: $(GENERIC_DIR)/tclDate.c
tclCompCmds.o: $(GENERIC_DIR)/tclCompCmds.c $(COMPILEHDR)
$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclCompCmds.c
-tclCompCmdsSZ.o: $(GENERIC_DIR)/tclCompCmdsSZ.c $(COMPILEHDR)
+tclCompCmdsGR.o: $(GENERIC_DIR)/tclCompCmdsGR.c $(COMPILEHDR)
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclCompCmdsGR.c
+
+tclCompCmdsSZ.o: $(GENERIC_DIR)/tclCompCmdsSZ.c $(COMPILEHDR) $(TRIMHDR)
$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclCompCmdsSZ.c
tclCompExpr.o: $(GENERIC_DIR)/tclCompExpr.c $(COMPILEHDR)
@@ -1140,6 +1177,9 @@ tclLiteral.o: $(GENERIC_DIR)/tclLiteral.c $(COMPILEHDR)
tclObj.o: $(GENERIC_DIR)/tclObj.c $(COMPILEHDR) $(MATHHDRS)
$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclObj.c
+tclOptimize.o: $(GENERIC_DIR)/tclOptimize.c $(COMPILEHDR)
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclOptimize.c
+
tclLoad.o: $(GENERIC_DIR)/tclLoad.c
$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclLoad.c
@@ -1156,6 +1196,7 @@ tclLoadDld.o: $(UNIX_DIR)/tclLoadDld.c
$(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tclLoadDld.c
tclLoadDyld.o: $(UNIX_DIR)/tclLoadDyld.c
+ @echo Warnings are expected from compiling tclLoadDyld.c: deprecated API use
$(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tclLoadDyld.c
tclLoadNone.o: $(GENERIC_DIR)/tclLoadNone.c
@@ -1269,7 +1310,7 @@ tclStubInit.o: $(GENERIC_DIR)/tclStubInit.c
tclTrace.o: $(GENERIC_DIR)/tclTrace.c
$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclTrace.c
-tclUtil.o: $(GENERIC_DIR)/tclUtil.c $(PARSEHDR)
+tclUtil.o: $(GENERIC_DIR)/tclUtil.c $(PARSEHDR) $(TRIMHDR)
$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclUtil.c
tclUtf.o: $(GENERIC_DIR)/tclUtf.c $(GENERIC_DIR)/tclUniData.c
@@ -1571,7 +1612,7 @@ $(DTRACE_OBJ): $(DTRACE_SRC) $(TCL_OBJS)
# notifier can modify them to suit their own installation.
#--------------------------------------------------------------------------
-xttest: ${XTTEST_OBJS} ${TCL_LIB_FILE} ${TCL_STUB_LIB_FILE} ${BUILD_DLTEST}
+xttest: ${XTTEST_OBJS} ${TCL_LIB_FILE} ${TCL_STUB_LIB_FILE} ${BUILD_DLTEST}
${CC} ${CFLAGS} ${LDFLAGS} ${XTTEST_OBJS} \
@TCL_BUILD_LIB_SPEC@ ${TCL_STUB_LIB_FILE} ${LIBS} @EXTRA_TCLSH_LIBS@ \
${CC_SEARCH_FLAGS} -L/usr/openwin/lib -lXt -o xttest
@@ -1654,7 +1695,7 @@ Zzutil.o: $(ZLIB_DIR)/zutil.c
#--------------------------------------------------------------------------
tclStubLib.o: $(GENERIC_DIR)/tclStubLib.c
- $(CC) -c $(STUB_CC_SWITCHES) $(GENERIC_DIR)/tclStubLib.c
+ $(CC) -c $(STUB_CC_SWITCHES) -DSTATIC_BUILD $(GENERIC_DIR)/tclStubLib.c
tclTomMathStubLib.o: $(GENERIC_DIR)/tclTomMathStubLib.c
$(CC) -c $(STUB_CC_SWITCHES) $(GENERIC_DIR)/tclTomMathStubLib.c
@@ -1718,7 +1759,7 @@ install-packages: packages
fi; \
done
-test-packages: tcltest packages
+test-packages: ${TCLTEST_EXE} packages
@for i in $(PKGS_DIR)/*; do \
if [ -d $$i ]; then \
pkg=`basename $$i`; \
@@ -1913,6 +1954,7 @@ $(MAC_OSX_DIR)/configure: $(MAC_OSX_DIR)/configure.ac $(UNIX_DIR)/configure
$(UNIX_DIR)/tclConfig.h.in: $(MAC_OSX_DIR)/configure
cd $(MAC_OSX_DIR); autoheader; touch $@
+EOLFIX=$(NATIVE_TCLSH) $(TOOL_DIR)/eolFix.tcl
dist: $(UNIX_DIR)/configure $(UNIX_DIR)/tclConfig.h.in $(UNIX_DIR)/tcl.pc.in $(MAC_OSX_DIR)/configure genstubs dist-packages ${NATIVE_TCLSH}
rm -rf $(DISTDIR)
mkdir -p $(DISTDIR)/unix
@@ -1928,7 +1970,7 @@ dist: $(UNIX_DIR)/configure $(UNIX_DIR)/tclConfig.h.in $(UNIX_DIR)/tcl.pc.in $(M
$(UNIX_DIR)/tcl.pc.in $(DISTDIR)/unix
chmod 775 $(DISTDIR)/unix/configure $(DISTDIR)/unix/configure.in
chmod 775 $(DISTDIR)/unix/ldAix
- mkdir $(DISTDIR)/generic
+ @mkdir $(DISTDIR)/generic
cp -p $(GENERIC_DIR)/*.[cdh] $(DISTDIR)/generic
cp -p $(GENERIC_DIR)/*.decls $(DISTDIR)/generic
cp -p $(GENERIC_DIR)/README $(DISTDIR)/generic
@@ -1936,7 +1978,7 @@ dist: $(UNIX_DIR)/configure $(UNIX_DIR)/tclConfig.h.in $(UNIX_DIR)/tcl.pc.in $(M
cp -p $(TOP_DIR)/changes $(TOP_DIR)/ChangeLog $(TOP_DIR)/README* \
$(TOP_DIR)/ChangeLog.[12]??? $(TOP_DIR)/license.terms \
$(DISTDIR)
- mkdir $(DISTDIR)/library
+ @mkdir $(DISTDIR)/library
cp -p $(TOP_DIR)/license.terms $(TOP_DIR)/library/*.tcl \
$(TOP_DIR)/library/tclIndex $(DISTDIR)/library
for i in http1.0 http opt msgcat reg dde tcltest platform; \
@@ -1944,31 +1986,32 @@ dist: $(UNIX_DIR)/configure $(UNIX_DIR)/tclConfig.h.in $(UNIX_DIR)/tcl.pc.in $(M
mkdir $(DISTDIR)/library/$$i ;\
cp -p $(TOP_DIR)/library/$$i/*.tcl $(DISTDIR)/library/$$i; \
done;
- mkdir $(DISTDIR)/library/encoding
+ @mkdir $(DISTDIR)/library/encoding
cp -p $(TOP_DIR)/library/encoding/*.enc $(DISTDIR)/library/encoding
- mkdir $(DISTDIR)/library/msgs
+ @mkdir $(DISTDIR)/library/msgs
cp -p $(TOP_DIR)/library/msgs/*.msg $(DISTDIR)/library/msgs
- ( cd $(TOP_DIR); \
+ @echo cp -r $(TOP_DIR)/library/tzdata $(DISTDIR)/library/tzdata
+ @( cd $(TOP_DIR); \
find library/tzdata -name CVS -prune -o -type f -print ) \
| ( cd $(TOP_DIR) ; xargs tar cf - ) \
| ( cd $(DISTDIR) ; tar xfp - )
- mkdir $(DISTDIR)/doc
+ @mkdir $(DISTDIR)/doc
cp -p $(TOP_DIR)/license.terms $(TOP_DIR)/doc/*.[13n] \
$(TOP_DIR)/doc/man.macros $(DISTDIR)/doc
- mkdir $(DISTDIR)/compat
+ @mkdir $(DISTDIR)/compat
cp -p $(TOP_DIR)/license.terms $(COMPAT_DIR)/*.[ch] \
$(COMPAT_DIR)/README $(DISTDIR)/compat
- mkdir $(DISTDIR)/compat/zlib
+ @mkdir $(DISTDIR)/compat/zlib
( cd $(COMPAT_DIR)/zlib; \
find . -name CVS -prune -o -type f -print ) \
| ( cd $(COMPAT_DIR)/zlib ; xargs tar cf - ) \
| ( cd $(DISTDIR)/compat/zlib ; tar xfp - )
- mkdir $(DISTDIR)/tests
+ @mkdir $(DISTDIR)/tests
cp -p $(TOP_DIR)/license.terms $(DISTDIR)/tests
cp -p $(TOP_DIR)/tests/*.test $(TOP_DIR)/tests/README \
$(TOP_DIR)/tests/httpd $(TOP_DIR)/tests/*.tcl \
$(DISTDIR)/tests
- mkdir $(DISTDIR)/win
+ @mkdir $(DISTDIR)/win
cp $(TOP_DIR)/win/Makefile.in $(DISTDIR)/win
cp $(TOP_DIR)/win/configure.in $(TOP_DIR)/win/configure \
$(TOP_DIR)/win/tclConfig.sh.in $(TOP_DIR)/win/tclooConfig.sh \
@@ -1977,49 +2020,48 @@ dist: $(UNIX_DIR)/configure $(UNIX_DIR)/tclConfig.h.in $(UNIX_DIR)/tcl.pc.in $(M
cp -p $(TOP_DIR)/win/*.[ch] $(TOP_DIR)/win/*.ico $(TOP_DIR)/win/*.rc \
$(DISTDIR)/win
cp -p $(TOP_DIR)/win/*.bat $(DISTDIR)/win
- $(NATIVE_TCLSH) $(TOOL_DIR)/eolFix.tcl -crlf $(DISTDIR)/win/*.bat
+ @$(EOLFIX) -crlf $(DISTDIR)/win/*.bat
cp -p $(TOP_DIR)/win/makefile.* $(DISTDIR)/win
- $(NATIVE_TCLSH) $(TOOL_DIR)/eolFix.tcl -crlf $(DISTDIR)/win/makefile.*
+ @$(EOLFIX) -crlf $(DISTDIR)/win/makefile.bc $(DISTDIR)/win/makefile.vc
cp -p $(TOP_DIR)/win/rules.vc $(DISTDIR)/win
- $(NATIVE_TCLSH) $(TOOL_DIR)/eolFix.tcl -crlf $(DISTDIR)/win/rules.vc
+ @$(EOLFIX) -crlf $(DISTDIR)/win/rules.vc
cp -p $(TOP_DIR)/win/coffbase.txt $(DISTDIR)/win
- $(NATIVE_TCLSH) $(TOOL_DIR)/eolFix.tcl -crlf $(DISTDIR)/win/coffbase.txt
+ @$(EOLFIX) -crlf $(DISTDIR)/win/coffbase.txt
cp -p $(TOP_DIR)/win/tcl.hpj.in $(DISTDIR)/win
- $(NATIVE_TCLSH) $(TOOL_DIR)/eolFix.tcl -crlf $(DISTDIR)/win/tcl.hpj.in
+ @$(EOLFIX) -crlf $(DISTDIR)/win/tcl.hpj.in
cp -p $(TOP_DIR)/win/tcl.ds* $(DISTDIR)/win
- $(NATIVE_TCLSH) $(TOOL_DIR)/eolFix.tcl -crlf $(DISTDIR)/win/tcl.ds*
+ @$(EOLFIX) -crlf $(DISTDIR)/win/tcl.ds*
cp -p $(TOP_DIR)/win/README $(DISTDIR)/win
cp -p $(TOP_DIR)/license.terms $(DISTDIR)/win
- mkdir $(DISTDIR)/macosx
+ @mkdir $(DISTDIR)/macosx
cp -p $(MAC_OSX_DIR)/GNUmakefile $(MAC_OSX_DIR)/README \
$(MAC_OSX_DIR)/*.c $(MAC_OSX_DIR)/*.in \
$(MAC_OSX_DIR)/*.ac $(MAC_OSX_DIR)/*.xcconfig \
$(MAC_OSX_DIR)/configure $(DISTDIR)/macosx
cp -p $(TOP_DIR)/license.terms $(DISTDIR)/macosx
- mkdir $(DISTDIR)/macosx/Tcl.xcode
+ @mkdir $(DISTDIR)/macosx/Tcl.xcode
cp -p $(MAC_OSX_DIR)/Tcl.xcode/project.pbxproj \
$(MAC_OSX_DIR)/Tcl.xcode/default.pbxuser \
$(DISTDIR)/macosx/Tcl.xcode
- mkdir $(DISTDIR)/macosx/Tcl.xcodeproj
+ @mkdir $(DISTDIR)/macosx/Tcl.xcodeproj
cp -p $(MAC_OSX_DIR)/Tcl.xcodeproj/project.pbxproj \
$(MAC_OSX_DIR)/Tcl.xcodeproj/default.pbxuser \
$(DISTDIR)/macosx/Tcl.xcodeproj
- mkdir $(DISTDIR)/unix/dltest
+ @mkdir $(DISTDIR)/unix/dltest
cp -p $(UNIX_DIR)/dltest/*.c $(UNIX_DIR)/dltest/Makefile.in \
- $(UNIX_DIR)/dltest/README \
- $(DISTDIR)/unix/dltest
- mkdir $(DISTDIR)/tools
+ $(UNIX_DIR)/dltest/README $(DISTDIR)/unix/dltest
+ @mkdir $(DISTDIR)/tools
cp -p $(TOOL_DIR)/Makefile.in $(TOOL_DIR)/README \
$(TOOL_DIR)/configure $(TOOL_DIR)/configure.in \
$(TOOL_DIR)/*.tcl $(TOOL_DIR)/man2tcl.c \
$(TOOL_DIR)/*.bmp $(TOOL_DIR)/tcl.hpj.in \
$(DISTDIR)/tools
- $(NATIVE_TCLSH) $(TOOL_DIR)/eolFix.tcl -crlf $(DISTDIR)/tools/tcl.hpj.in
- mkdir $(DISTDIR)/libtommath
- cp -p $(TOMMATH_SRCS) $(TOMMATH_DIR)/*.h \
- $(DISTDIR)/libtommath
- mkdir $(DISTDIR)/pkgs
+ @$(EOLFIX) -crlf $(DISTDIR)/tools/tcl.hpj.in
+ @mkdir $(DISTDIR)/libtommath
+ cp -p $(TOMMATH_SRCS) $(TOMMATH_DIR)/*.h $(DISTDIR)/libtommath
+ @mkdir $(DISTDIR)/pkgs
cp $(TOP_DIR)/pkgs/README $(DISTDIR)/pkgs
+ cp $(TOP_DIR)/pkgs/package.list.txt $(DISTDIR)/pkgs
for i in `ls $(DISTROOT)/pkgs/*.tar.gz 2> /dev/null`; do \
tar -C $(DISTDIR)/pkgs -xzf "$$i"; \
done
@@ -2039,21 +2081,29 @@ alldist: dist
# build of this HTML documentation that has already been placed online. As
# such, this rule is not guaranteed to work well on all systems; it only needs
# to function on those of the Tcl/Tk maintainers.
+#
+# Also note that the 8.6 tool build requires an installed 8.6 native Tcl
+# interpreter in order to be able to run.
#--------------------------------------------------------------------------
html: ${NATIVE_TCLSH}
$(BUILD_HTML)
@EXTRA_BUILD_HTML@
+
html-tcl: ${NATIVE_TCLSH}
$(BUILD_HTML) --tcl
@EXTRA_BUILD_HTML@
+
html-tk: ${NATIVE_TCLSH}
$(BUILD_HTML) --tk
@EXTRA_BUILD_HTML@
+# You'd better have these programs or you will have problems creating Makefile
+# from Makefile.in in the first place...
+HTML_VERSION = `basename $(TOP_DIR) | sed s/tcl//`
BUILD_HTML = \
@${NATIVE_TCLSH} $(TOOL_DIR)/tcltk-man2html.tcl \
- --htmldir="$(HTML_INSTALL_DIR)" \
+ --useversion=$(HTML_VERSION) --htmldir="$(HTML_INSTALL_DIR)" \
--srcdir=$(TOP_DIR)/.. $(BUILD_HTML_FLAGS)
#--------------------------------------------------------------------------
diff --git a/unix/README b/unix/README
index 87b151a..d8f1090 100644
--- a/unix/README
+++ b/unix/README
@@ -163,6 +163,7 @@ you'll see a much more substantial printout for each error. See the README
file in the "tests" directory for more information on the test suite. Note:
don't run the tests as superuser: this will cause several of them to fail. If
a test is failing consistently, please send us a bug report with as much
-detail as you can manage. Please use the online database at
- http://tcl.sourceforge.net/
+detail as you can manage to our tracker:
+
+ http://core.tcl.tk/tcl/reportlist
diff --git a/unix/configure b/unix/configure
index f778a7b..bd85ba4 100755
--- a/unix/configure
+++ b/unix/configure
@@ -1335,9 +1335,12 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
TCL_VERSION=8.6
TCL_MAJOR_VERSION=8
TCL_MINOR_VERSION=6
-TCL_PATCH_LEVEL=".0"
+TCL_PATCH_LEVEL=".1"
VERSION=${TCL_VERSION}
+EXTRA_INSTALL_BINARIES=${EXTRA_INSTALL_BINARIES:-"@:"}
+EXTRA_BUILD_HTML=${EXTRA_BUILD_HTML:-"@:"}
+
#------------------------------------------------------------------------
# Setup configure arguments for bundled packages
#------------------------------------------------------------------------
@@ -4821,7 +4824,11 @@ echo "$as_me: WARNING: Don't know how to find pthread lib on your system - you m
# Does the pthread-implementation provide
# 'pthread_attr_setstacksize' ?
-for ac_func in pthread_attr_setstacksize
+ ac_saved_libs=$LIBS
+ LIBS="$LIBS $THREADS_LIBS"
+
+
+for ac_func in pthread_attr_setstacksize pthread_atfork
do
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
echo "$as_me:$LINENO: checking for $ac_func" >&5
@@ -4922,6 +4929,7 @@ _ACEOF
fi
done
+ LIBS=$ac_saved_libs
else
TCL_THREADS=0
fi
@@ -6485,80 +6493,6 @@ if test "${tcl_cv_cc_visibility_hidden+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
- if test "$SHARED_BUILD" = 1; then
-
- hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -fvisibility=hidden -Werror"
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-#if !defined(__GNUC__) || __GNUC__ < 4
-#error visibility hidden is not supported for this compiler
-#endif
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- tcl_cv_cc_visibility_hidden=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_cc_visibility_hidden=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
- CFLAGS=$hold_cflags
-
-else
-
- tcl_cv_cc_visibility_hidden=no
-
-fi
-
-
-fi
-echo "$as_me:$LINENO: result: $tcl_cv_cc_visibility_hidden" >&5
-echo "${ECHO_T}$tcl_cv_cc_visibility_hidden" >&6
- if test $tcl_cv_cc_visibility_hidden = yes; then
-
- CFLAGS="$CFLAGS -fvisibility=hidden"
-
-cat >>confdefs.h <<\_ACEOF
-#define MODULE_SCOPE extern
-_ACEOF
-
-
-else
-
hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror"
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
@@ -6609,7 +6543,10 @@ fi
rm -f conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
CFLAGS=$hold_cflags
- if test $tcl_cv_cc_visibility_hidden = yes; then
+fi
+echo "$as_me:$LINENO: result: $tcl_cv_cc_visibility_hidden" >&5
+echo "${ECHO_T}$tcl_cv_cc_visibility_hidden" >&6
+ if test $tcl_cv_cc_visibility_hidden = yes; then
cat >>confdefs.h <<\_ACEOF
@@ -6617,7 +6554,9 @@ cat >>confdefs.h <<\_ACEOF
_ACEOF
-fi
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_HIDDEN 1
+_ACEOF
fi
@@ -7063,13 +7002,16 @@ fi
SHLIB_CFLAGS=""
SHLIB_LD='${CC} -shared'
SHLIB_SUFFIX=".dll"
- DL_OBJS="tclLoadDl.o tclWinError.o"
+ DL_OBJS="tclLoadDl.o"
+ PLAT_OBJS='${CYGWIN_OBJS}'
+ PLAT_SRCS='${CYGWIN_SRCS}'
DL_LIBS="-ldl"
CC_SEARCH_FLAGS=""
LD_SEARCH_FLAGS=""
TCL_NEEDS_EXP_FILE=1
TCL_EXPORT_FILE_SUFFIX='${VERSION}\$\{DBGX\}.dll.a'
TCL_SHLIB_LD_EXTRAS='-Wl,--out-implib,$@.a'
+ TK_SHLIB_LD_EXTRAS='-Wl,--out-implib,$@.a'
echo "$as_me:$LINENO: checking for Cygwin version of gcc" >&5
echo $ECHO_N "checking for Cygwin version of gcc... $ECHO_C" >&6
if test "${ac_cv_cygwin+set}" = set; then
@@ -7138,10 +7080,15 @@ echo "$as_me: error: ${CC} is not a cygwin compiler." >&2;}
echo "$as_me: error: CYGWIN compile is only supported with --enable-threads" >&2;}
{ (exit 1); exit 1; }; }
fi
- if test "x${SHARED_BUILD}" = "x1" -a ! -f "../win/tcldde14.dll" -a ! -f "../win/tk86.dll"; then
- { { echo "$as_me:$LINENO: error: Please configure and make the ../win directory first." >&5
-echo "$as_me: error: Please configure and make the ../win directory first." >&2;}
- { (exit 1); exit 1; }; }
+ do64bit_ok=yes
+ if test "x${SHARED_BUILD}" = "x1"; then
+ echo "running cd ${TCL_SRC_DIR}/win; ${CONFIG_SHELL-/bin/sh} ./configure $ac_configure_args"
+ # The eval makes quoting arguments work.
+ if cd ${TCL_SRC_DIR}/win; eval ${CONFIG_SHELL-/bin/sh} ./configure $ac_configure_args; cd ../unix
+ then :
+ else
+ { echo "configure: error: configure failed for ../win" 1>&2; exit 1; }
+ fi
fi
;;
dgux*)
@@ -7577,7 +7524,7 @@ fi
fi
;;
- Linux*)
+ Linux*|GNU*|NetBSD-Debian)
SHLIB_CFLAGS="-fPIC"
SHLIB_SUFFIX=".so"
@@ -7683,21 +7630,6 @@ fi
fi
;;
- GNU*)
- SHLIB_CFLAGS="-fPIC"
- SHLIB_SUFFIX=".so"
-
- SHLIB_LD='${CC} -shared'
- DL_OBJS=""
- DL_LIBS="-ldl"
- LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
- CC_SEARCH_FLAGS=""
- LD_SEARCH_FLAGS=""
- if test "`uname -m`" = "alpha"; then
- CFLAGS="$CFLAGS -mieee"
-fi
-
- ;;
Lynx*)
SHLIB_CFLAGS="-fPIC"
SHLIB_SUFFIX=".so"
@@ -7734,71 +7666,15 @@ fi
CC_SEARCH_FLAGS=""
LD_SEARCH_FLAGS=""
;;
- NetBSD-1.*|FreeBSD-[1-2].*)
- SHLIB_CFLAGS="-fPIC"
- SHLIB_LD="ld -Bshareable -x"
- SHLIB_SUFFIX=".so"
- DL_OBJS="tclLoadDl.o"
- DL_LIBS=""
- if test $doRpath = yes; then
-
- CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
- LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
-fi
-
- echo "$as_me:$LINENO: checking for ELF" >&5
-echo $ECHO_N "checking for ELF... $ECHO_C" >&6
-if test "${tcl_cv_ld_elf+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-#ifdef __ELF__
- yes
-#endif
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "yes" >/dev/null 2>&1; then
- tcl_cv_ld_elf=yes
-else
- tcl_cv_ld_elf=no
-fi
-rm -f conftest*
-
-fi
-echo "$as_me:$LINENO: result: $tcl_cv_ld_elf" >&5
-echo "${ECHO_T}$tcl_cv_ld_elf" >&6
- if test $tcl_cv_ld_elf = yes; then
-
- SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so'
-
-else
-
- SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.${SHLIB_VERSION}'
-
-fi
-
-
- # Ancient FreeBSD doesn't handle version numbers with dots.
-
- UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
- TCL_LIB_VERSIONS_OK=nodots
- ;;
OpenBSD-*)
arch=`arch -s`
case "$arch" in
- m88k|vax)
+ vax)
# Equivalent using configure option --disable-load
# Step 4 will set the necessary variables
DL_OBJS=""
SHLIB_LD_LIBS=""
+ LDFLAGS=""
;;
*)
SHLIB_CFLAGS="-fPIC"
@@ -7813,10 +7689,11 @@ fi
LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.${SHLIB_VERSION}'
+ LDFLAGS="-Wl,-export-dynamic"
;;
esac
case "$arch" in
- m88k|vax)
+ vax)
CFLAGS_OPTIMIZE="-O1"
;;
sh)
@@ -7826,43 +7703,6 @@ fi
CFLAGS_OPTIMIZE="-O2"
;;
esac
- echo "$as_me:$LINENO: checking for ELF" >&5
-echo $ECHO_N "checking for ELF... $ECHO_C" >&6
-if test "${tcl_cv_ld_elf+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-#ifdef __ELF__
- yes
-#endif
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "yes" >/dev/null 2>&1; then
- tcl_cv_ld_elf=yes
-else
- tcl_cv_ld_elf=no
-fi
-rm -f conftest*
-
-fi
-echo "$as_me:$LINENO: result: $tcl_cv_ld_elf" >&5
-echo "${ECHO_T}$tcl_cv_ld_elf" >&6
- if test $tcl_cv_ld_elf = yes; then
-
- LDFLAGS=-Wl,-export-dynamic
-
-else
- LDFLAGS=""
-fi
-
if test "${TCL_THREADS}" = "1"; then
# On OpenBSD: Compile with -pthread
@@ -7876,9 +7716,8 @@ fi
UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
TCL_LIB_VERSIONS_OK=nodots
;;
- NetBSD-*|FreeBSD-[3-4].*)
- # FreeBSD 3.* and greater have ELF.
- # NetBSD 2.* has ELF and can use 'cc -shared' to build shared libs
+ NetBSD-*)
+ # NetBSD has ELF and can use 'cc -shared' to build shared libs
SHLIB_CFLAGS="-fPIC"
SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}'
SHLIB_SUFFIX=".so"
@@ -7900,20 +7739,13 @@ fi
fi
- case $system in
- FreeBSD-3.*)
- # FreeBSD-3 doesn't handle version numbers with dots.
- UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
- SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so'
- TCL_LIB_VERSIONS_OK=nodots
- ;;
- esac
;;
FreeBSD-*)
# This configuration from FreeBSD Ports.
SHLIB_CFLAGS="-fPIC"
SHLIB_LD="${CC} -shared"
- TCL_SHLIB_LD_EXTRAS="-soname \$@"
+ TCL_SHLIB_LD_EXTRAS="-Wl,-soname=\$@"
+ TK_SHLIB_LD_EXTRAS="-Wl,-soname,\$@"
SHLIB_SUFFIX=".so"
DL_OBJS="tclLoadDl.o"
DL_LIBS=""
@@ -7921,7 +7753,7 @@ fi
if test $doRpath = yes; then
CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
- LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
fi
if test "${TCL_THREADS}" = "1"; then
@@ -7932,11 +7764,15 @@ fi
LDFLAGS="$LDFLAGS $PTHREAD_LIBS"
fi
- # Version numbers are dot-stripped by system policy.
- TCL_TRIM_DOTS=`echo ${VERSION} | tr -d .`
- UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
- SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}\$\{DBGX\}.so.1'
- TCL_LIB_VERSIONS_OK=nodots
+ case $system in
+ FreeBSD-3.*)
+ # Version numbers are dot-stripped by system policy.
+ TCL_TRIM_DOTS=`echo ${VERSION} | tr -d .`
+ UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+ SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so'
+ TCL_LIB_VERSIONS_OK=nodots
+ ;;
+ esac
;;
Darwin-*)
CFLAGS_OPTIMIZE="-Os"
@@ -8249,7 +8085,6 @@ cat >>confdefs.h <<\_ACEOF
#define MODULE_SCOPE __private_extern__
_ACEOF
- tcl_cv_cc_visibility_hidden=yes
fi
@@ -9130,11 +8965,6 @@ cat >>confdefs.h <<\_ACEOF
_ACEOF
-cat >>confdefs.h <<\_ACEOF
-#define NO_VIZ
-_ACEOF
-
-
fi
@@ -9869,7 +9699,7 @@ cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <sys/types.h>
-#include <sys/dirent.h>
+#include <dirent.h>
int
main ()
{
@@ -13239,14 +13069,16 @@ fi
fi
#---------------------------------------------------------------------------
-# Determine which interface to use to talk to the serial port.
-# Note that #include lines must begin in leftmost column for
-# some compilers to recognize them as preprocessor directives.
+# Check for serial port interface.
+#
+# termios.h is present on all POSIX systems.
+# sys/ioctl.h is almost always present, though what it contains
+# is system-specific.
+# sys/modem.h is needed on HP-UX.
#---------------------------------------------------------------------------
-
-for ac_header in sys/modem.h
+for ac_header in termios.h
do
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
if eval "test \"\${$as_ac_Header+set}\" = set"; then
@@ -13395,310 +13227,305 @@ fi
done
- echo "$as_me:$LINENO: checking termios vs. termio vs. sgtty" >&5
-echo $ECHO_N "checking termios vs. termio vs. sgtty... $ECHO_C" >&6
-if test "${tcl_cv_api_serial+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test "$cross_compiling" = yes; then
- tcl_cv_api_serial=no
+for ac_header in sys/ioctl.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
else
- cat >conftest.$ac_ext <<_ACEOF
+ # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
-
-#include <termios.h>
-
-int main() {
- struct termios t;
- if (tcgetattr(0, &t) == 0) {
- cfsetospeed(&t, 0);
- t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB;
- return 0;
- }
- return 1;
-}
+$ac_includes_default
+#include <$ac_header>
_ACEOF
-rm -f conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- tcl_cv_api_serial=termios
-else
- echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-( exit $ac_status )
-tcl_cv_api_serial=no
-fi
-rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
-fi
- if test $tcl_cv_api_serial = no ; then
- if test "$cross_compiling" = yes; then
- tcl_cv_api_serial=no
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-#include <termio.h>
-
-int main() {
- struct termio t;
- if (ioctl(0, TCGETA, &t) == 0) {
- t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB;
- return 0;
- }
- return 1;
-}
-_ACEOF
-rm -f conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
- tcl_cv_api_serial=termio
+ ac_header_compiler=yes
else
- echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
+ echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
-( exit $ac_status )
-tcl_cv_api_serial=no
-fi
-rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+ac_header_compiler=no
fi
- fi
- if test $tcl_cv_api_serial = no ; then
- if test "$cross_compiling" = yes; then
- tcl_cv_api_serial=no
-else
- cat >conftest.$ac_ext <<_ACEOF
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
-
-#include <sgtty.h>
-
-int main() {
- struct sgttyb t;
- if (ioctl(0, TIOCGETP, &t) == 0) {
- t.sg_ospeed = 0;
- t.sg_flags |= ODDP | EVENP | RAW;
- return 0;
- }
- return 1;
-}
+#include <$ac_header>
_ACEOF
-rm -f conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- tcl_cv_api_serial=sgtty
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
else
- echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
-( exit $ac_status )
-tcl_cv_api_serial=no
-fi
-rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+ ac_header_preproc=no
fi
- fi
- if test $tcl_cv_api_serial = no ; then
- if test "$cross_compiling" = yes; then
- tcl_cv_api_serial=no
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
-#include <termios.h>
-#include <errno.h>
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+ (
+ cat <<\_ASBOX
+## ------------------------------ ##
+## Report this to the tcl lists. ##
+## ------------------------------ ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
-int main() {
- struct termios t;
- if (tcgetattr(0, &t) == 0
- || errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
- cfsetospeed(&t, 0);
- t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB;
- return 0;
- }
- return 1;
-}
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
_ACEOF
-rm -f conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- tcl_cv_api_serial=termios
-else
- echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-( exit $ac_status )
-tcl_cv_api_serial=no
fi
-rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+
+done
+
+
+for ac_header in sys/modem.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
fi
- fi
- if test $tcl_cv_api_serial = no; then
- if test "$cross_compiling" = yes; then
- tcl_cv_api_serial=no
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
else
- cat >conftest.$ac_ext <<_ACEOF
+ # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
-
-#include <termio.h>
-#include <errno.h>
-
-int main() {
- struct termio t;
- if (ioctl(0, TCGETA, &t) == 0
- || errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
- t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB;
- return 0;
- }
- return 1;
- }
+$ac_includes_default
+#include <$ac_header>
_ACEOF
-rm -f conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
- tcl_cv_api_serial=termio
+ ac_header_compiler=yes
else
- echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
+ echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
-( exit $ac_status )
-tcl_cv_api_serial=no
-fi
-rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+ac_header_compiler=no
fi
- fi
- if test $tcl_cv_api_serial = no; then
- if test "$cross_compiling" = yes; then
- tcl_cv_api_serial=none
-else
- cat >conftest.$ac_ext <<_ACEOF
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
-
-#include <sgtty.h>
-#include <errno.h>
-
-int main() {
- struct sgttyb t;
- if (ioctl(0, TIOCGETP, &t) == 0
- || errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
- t.sg_ospeed = 0;
- t.sg_flags |= ODDP | EVENP | RAW;
- return 0;
- }
- return 1;
-}
+#include <$ac_header>
_ACEOF
-rm -f conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- tcl_cv_api_serial=sgtty
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
else
- echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
-( exit $ac_status )
-tcl_cv_api_serial=none
+ ac_header_preproc=no
fi
-rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+ (
+ cat <<\_ASBOX
+## ------------------------------ ##
+## Report this to the tcl lists. ##
+## ------------------------------ ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ eval "$as_ac_Header=\$ac_header_preproc"
fi
- fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
fi
-echo "$as_me:$LINENO: result: $tcl_cv_api_serial" >&5
-echo "${ECHO_T}$tcl_cv_api_serial" >&6
- case $tcl_cv_api_serial in
- termios)
-cat >>confdefs.h <<\_ACEOF
-#define USE_TERMIOS 1
-_ACEOF
-;;
- termio)
-cat >>confdefs.h <<\_ACEOF
-#define USE_TERMIO 1
-_ACEOF
-;;
- sgtty)
-cat >>confdefs.h <<\_ACEOF
-#define USE_SGTTY 1
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
_ACEOF
-;;
- esac
+
+fi
+
+done
#--------------------------------------------------------------------
@@ -14402,11 +14229,7 @@ _ACEOF
# lack blkcnt_t.
#--------------------------------------------------------------------
-if test "$ac_cv_cygwin" = "yes"; then
- if test "x${SHARED_BUILD}" = "x1"; then
- TCL_SHLIB_LD_EXTRAS="${TCL_SHLIB_LD_EXTRAS} \${COMPAT_DIR}/zlib/win32/zdll.lib"
- fi
-else
+if test "$ac_cv_cygwin" != "yes"; then
echo "$as_me:$LINENO: checking for struct stat.st_blocks" >&5
echo $ECHO_N "checking for struct stat.st_blocks... $ECHO_C" >&6
if test "${ac_cv_member_struct_stat_st_blocks+set}" = set; then
@@ -18071,108 +17894,6 @@ _ACEOF
fi
done
-
-for ac_func in pthread_atfork
-do
-as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
-echo "$as_me:$LINENO: checking for $ac_func" >&5
-echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
-if eval "test \"\${$as_ac_var+set}\" = set"; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define $ac_func innocuous_$ac_func
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char $ac_func (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef $ac_func
-
-/* Override any gcc2 internal prototype to avoid an error. */
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char $ac_func ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
-choke me
-#else
-char (*f) () = $ac_func;
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-int
-main ()
-{
-return f != $ac_func;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- eval "$as_ac_var=yes"
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-eval "$as_ac_var=no"
-fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
-if test `eval echo '${'$as_ac_var'}'` = yes; then
- cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-done
-
fi
cat >>confdefs.h <<\_ACEOF
diff --git a/unix/configure.in b/unix/configure.in
index 087bb05..cb6cf82 100644
--- a/unix/configure.in
+++ b/unix/configure.in
@@ -25,9 +25,12 @@ m4_ifdef([SC_USE_CONFIG_HEADERS], [
TCL_VERSION=8.6
TCL_MAJOR_VERSION=8
TCL_MINOR_VERSION=6
-TCL_PATCH_LEVEL=".0"
+TCL_PATCH_LEVEL=".1"
VERSION=${TCL_VERSION}
+EXTRA_INSTALL_BINARIES=${EXTRA_INSTALL_BINARIES:-"@:"}
+EXTRA_BUILD_HTML=${EXTRA_BUILD_HTML:-"@:"}
+
#------------------------------------------------------------------------
# Setup configure arguments for bundled packages
#------------------------------------------------------------------------
@@ -259,12 +262,17 @@ if test "${TCL_THREADS}" = 1; then
fi
#---------------------------------------------------------------------------
-# Determine which interface to use to talk to the serial port.
-# Note that #include lines must begin in leftmost column for
-# some compilers to recognize them as preprocessor directives.
+# Check for serial port interface.
+#
+# termios.h is present on all POSIX systems.
+# sys/ioctl.h is almost always present, though what it contains
+# is system-specific.
+# sys/modem.h is needed on HP-UX.
#---------------------------------------------------------------------------
-SC_SERIAL_PORT
+AC_CHECK_HEADERS(termios.h)
+AC_CHECK_HEADERS(sys/ioctl.h)
+AC_CHECK_HEADERS(sys/modem.h)
#--------------------------------------------------------------------
# Include sys/select.h if it exists and if it supplies things
@@ -305,11 +313,7 @@ SC_TIME_HANDLER
# lack blkcnt_t.
#--------------------------------------------------------------------
-if test "$ac_cv_cygwin" = "yes"; then
- if test "x${SHARED_BUILD}" = "x1"; then
- TCL_SHLIB_LD_EXTRAS="${TCL_SHLIB_LD_EXTRAS} \${COMPAT_DIR}/zlib/win32/zdll.lib"
- fi
-else
+if test "$ac_cv_cygwin" != "yes"; then
AC_CHECK_MEMBERS([struct stat.st_blocks, struct stat.st_blksize])
fi
AC_CHECK_TYPES([blkcnt_t])
@@ -575,7 +579,6 @@ if test "`uname -s`" = "Darwin" ; then
if test $tcl_corefoundation = yes; then
AC_CHECK_HEADERS(libkern/OSAtomic.h)
AC_CHECK_FUNCS(OSSpinLockLock)
- AC_CHECK_FUNCS(pthread_atfork)
fi
AC_DEFINE(USE_VFORK, 1, [Should we use vfork() instead of fork()?])
AC_DEFINE(TCL_DEFAULT_ENCODING, "utf-8",
diff --git a/unix/dltest/Makefile.in b/unix/dltest/Makefile.in
index 01589d9..25b9376 100644
--- a/unix/dltest/Makefile.in
+++ b/unix/dltest/Makefile.in
@@ -22,14 +22,14 @@ LDFLAGS_DEBUG = @LDFLAGS_DEBUG@
LDFLAGS_OPTIMIZE = @LDFLAGS_OPTIMIZE@
LDFLAGS = @LDFLAGS_DEFAULT@ @LDFLAGS@
-CC_SWITCHES = $(CFLAGS) -I${SRC_DIR}/../../generic -I${BUILD_DIR}/.. -DTCL_MEM_DEBUG \
+CC_SWITCHES = $(CFLAGS) -I${SRC_DIR}/../../generic -DTCL_MEM_DEBUG \
${SHLIB_CFLAGS} -DUSE_TCL_STUBS ${AC_FLAGS}
-all: pkga${SHLIB_SUFFIX} pkgb${SHLIB_SUFFIX} pkgc${SHLIB_SUFFIX} pkgd${SHLIB_SUFFIX} pkge${SHLIB_SUFFIX} pkgua${SHLIB_SUFFIX}
+all: pkga${SHLIB_SUFFIX} pkgb${SHLIB_SUFFIX} pkgc${SHLIB_SUFFIX} pkgd${SHLIB_SUFFIX} pkge${SHLIB_SUFFIX} pkgua${SHLIB_SUFFIX} pkgooa${SHLIB_SUFFIX}
@if test -n "$(DLTEST_SUFFIX)"; then $(MAKE) dltest_suffix; fi
@touch ../dltest.marker
-dltest_suffix: pkga${DLTEST_SUFFIX} pkgb${DLTEST_SUFFIX} pkgc${DLTEST_SUFFIX} pkgd${DLTEST_SUFFIX} pkge${DLTEST_SUFFIX} pkgua${DLTEST_SUFFIX}
+dltest_suffix: pkga${DLTEST_SUFFIX} pkgb${DLTEST_SUFFIX} pkgc${DLTEST_SUFFIX} pkgd${DLTEST_SUFFIX} pkge${DLTEST_SUFFIX} pkgua${DLTEST_SUFFIX} pkgooa${DLTEST_SUFFIX}
@touch ../dltest.marker
pkga.o: $(SRC_DIR)/pkga.c
@@ -50,6 +50,9 @@ pkge.o: $(SRC_DIR)/pkge.c
pkgua.o: $(SRC_DIR)/pkgua.c
$(CC) -c $(CC_SWITCHES) $(SRC_DIR)/pkgua.c
+pkgooa.o: $(SRC_DIR)/pkgooa.c
+ $(CC) -c $(CC_SWITCHES) $(SRC_DIR)/pkgooa.c
+
pkga${SHLIB_SUFFIX}: pkga.o
${SHLIB_LD} -o pkga${SHLIB_SUFFIX} pkga.o ${SHLIB_LD_LIBS}
@@ -68,6 +71,9 @@ pkge${SHLIB_SUFFIX}: pkge.o
pkgua${SHLIB_SUFFIX}: pkgua.o
${SHLIB_LD} -o pkgua${SHLIB_SUFFIX} pkgua.o ${SHLIB_LD_LIBS}
+pkgooa${SHLIB_SUFFIX}: pkgooa.o
+ ${SHLIB_LD} -o pkgooa${SHLIB_SUFFIX} pkgooa.o ${SHLIB_LD_LIBS}
+
pkga${DLTEST_SUFFIX}: pkga.o
${DLTEST_LD} -o pkga${DLTEST_SUFFIX} pkga.o ${SHLIB_LD_LIBS}
@@ -86,6 +92,9 @@ pkge${DLTEST_SUFFIX}: pkge.o
pkgua${DLTEST_SUFFIX}: pkgua.o
${DLTEST_LD} -o pkgua${DLTEST_SUFFIX} pkgua.o ${SHLIB_LD_LIBS}
+pkgooa${DLTEST_SUFFIX}: pkgooa.o
+ ${DLTEST_LD} -o pkgooa${DLTEST_SUFFIX} pkgooa.o ${SHLIB_LD_LIBS}
+
clean:
rm -f *.o lib.exp ../dltest.marker
@if test "$(SHLIB_SUFFIX)" != ""; then \
diff --git a/unix/dltest/pkgb.c b/unix/dltest/pkgb.c
index ad61d77..f102496 100644
--- a/unix/dltest/pkgb.c
+++ b/unix/dltest/pkgb.c
@@ -144,7 +144,7 @@ Pkgb_Init(
if (Tcl_InitStubs(interp, "8.5-", 0) == NULL) {
return TCL_ERROR;
}
- code = Tcl_PkgProvideEx(interp, "Pkgb", "2.3", NULL);
+ code = Tcl_PkgProvide(interp, "Pkgb", "2.3");
if (code != TCL_OK) {
return code;
}
@@ -181,7 +181,7 @@ Pkgb_SafeInit(
if (Tcl_InitStubs(interp, "8.5-", 0) == NULL) {
return TCL_ERROR;
}
- code = Tcl_PkgProvideEx(interp, "Pkgb", "2.3", NULL);
+ code = Tcl_PkgProvide(interp, "Pkgb", "2.3");
if (code != TCL_OK) {
return code;
}
diff --git a/unix/dltest/pkgooa.c b/unix/dltest/pkgooa.c
new file mode 100644
index 0000000..78af376
--- /dev/null
+++ b/unix/dltest/pkgooa.c
@@ -0,0 +1,141 @@
+/*
+ * pkgooa.c --
+ *
+ * This file contains a simple Tcl package "pkgooa" that is intended for
+ * testing the Tcl dynamic loading facilities.
+ *
+ * Copyright (c) 1995 Sun Microsystems, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#undef STATIC_BUILD
+#include "tclOO.h"
+#include <string.h>
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Pkgooa_StubsOKObjCmd --
+ *
+ * This procedure is invoked to process the "pkgooa_stubsok" Tcl command.
+ * It gives 1 if stubs are used correctly, 0 if stubs are not OK.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+Pkgooa_StubsOKObjCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
+{
+ if (objc != 1) {
+ Tcl_WrongNumArgs(interp, 1, objv, "");
+ return TCL_ERROR;
+ }
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(
+ Tcl_CopyObjectInstance == tclOOStubsPtr->tcl_CopyObjectInstance));
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Pkgooa_Init --
+ *
+ * This is a package initialization procedure, which is called by Tcl
+ * when this package is to be added to an interpreter.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+extern void *tclOOIntStubsPtr;
+
+static TclOOStubs stubsCopy = {
+ TCL_STUB_MAGIC,
+ NULL,
+ /* It doesn't really matter what implementation of
+ * Tcl_CopyObjectInstance is put in the "pseudo"
+ * stub table, since the test-case never actually
+ * calls this function. All that matters is that it's
+ * a function with a different memory address than
+ * the real Tcl_CopyObjectInstance function in Tcl. */
+ (Tcl_Object (*) (Tcl_Interp *, Tcl_Object, const char *,
+ const char *t)) Pkgooa_StubsOKObjCmd
+ /* More entries could be here, but those are not used
+ * for this test-case. So, being NULL is OK. */
+};
+
+extern DLLEXPORT int
+Pkgooa_Init(
+ Tcl_Interp *interp) /* Interpreter in which the package is to be
+ * made available. */
+{
+ int code;
+
+ /* Any TclOO extension which uses stubs, calls
+ * both Tcl_InitStubs and Tcl_OOInitStubs() and
+ * does not use any Tcl 8.6 features should be
+ * loadable in Tcl 8.5 as well, provided the
+ * TclOO extension (for Tcl 8.5) is installed.
+ * This worked in Tcl 8.6.0, and is expected
+ * to keep working in all future Tcl 8.x releases.
+ */
+ if (Tcl_InitStubs(interp, "8.5", 0) == NULL) {
+ return TCL_ERROR;
+ }
+ if (tclStubsPtr == NULL) {
+ Tcl_AppendResult(interp, "Tcl stubs are not inialized, "
+ "did you compile using -DUSE_TCL_STUBS? ");
+ return TCL_ERROR;
+ }
+ if (Tcl_OOInitStubs(interp) == NULL) {
+ return TCL_ERROR;
+ }
+ if (tclOOStubsPtr == NULL) {
+ Tcl_AppendResult(interp, "TclOO stubs are not inialized");
+ return TCL_ERROR;
+ }
+ if (tclOOIntStubsPtr == NULL) {
+ Tcl_AppendResult(interp, "TclOO internal stubs are not inialized");
+ return TCL_ERROR;
+ }
+
+ /* Test case for Bug [f51efe99a7].
+ *
+ * Let tclOOStubsPtr point to an alternate stub table
+ * (with only a single function, that's enough for
+ * this test). This way, the function "pkgooa_stubsok"
+ * can check whether the TclOO function calls really
+ * use the stub table, or only pretend to.
+ *
+ * On platforms without backlinking (Windows, Cygwin,
+ * AIX), this code doesn't even compile without using
+ * stubs, but on UNIX ELF systems, the problem is
+ * less visible.
+ */
+
+ tclOOStubsPtr = &stubsCopy;
+
+ code = Tcl_PkgProvide(interp, "Pkgooa", "1.0");
+ if (code != TCL_OK) {
+ return code;
+ }
+ Tcl_CreateObjCommand(interp, "pkgooa_stubsok", Pkgooa_StubsOKObjCmd, NULL, NULL);
+ return TCL_OK;
+}
diff --git a/unix/tcl.m4 b/unix/tcl.m4
index b13fddd..b23b9ac 100644
--- a/unix/tcl.m4
+++ b/unix/tcl.m4
@@ -111,9 +111,9 @@ AC_DEFUN([SC_PATH_TCLCONFIG], [
`ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]] 2>/dev/null` \
`ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]]* 2>/dev/null` ; do
if test -f "$i/unix/tclConfig.sh" ; then
- ac_cv_c_tclconfig="`(cd $i/unix; pwd)`"
- break
- fi
+ ac_cv_c_tclconfig="`(cd $i/unix; pwd)`"
+ break
+ fi
done
fi
])
@@ -271,11 +271,10 @@ AC_DEFUN([SC_PATH_TKCONFIG], [
#
# Results:
#
-# Subst the following vars:
+# Substitutes the following vars:
# TCL_BIN_DIR
# TCL_SRC_DIR
# TCL_LIB_FILE
-#
#------------------------------------------------------------------------
AC_DEFUN([SC_LOAD_TCLCONFIG], [
@@ -439,11 +438,11 @@ AC_DEFUN([SC_LOAD_TKCONFIG], [
# extension can't assume that an executable Tcl shell exists at
# build time.
#
-# Arguments
+# Arguments:
# none
#
-# Results
-# Subst's the following values:
+# Results:
+# Substitutes the following vars:
# TCLSH_PROG
#------------------------------------------------------------------------
@@ -484,11 +483,11 @@ AC_DEFUN([SC_PROG_TCLSH], [
# when running tests from an extension build directory. It is not
# correct to use the TCLSH_PROG in cases like this.
#
-# Arguments
+# Arguments:
# none
#
-# Results
-# Subst's the following values:
+# Results:
+# Substitutes the following values:
# BUILD_TCLSH
#------------------------------------------------------------------------
@@ -676,7 +675,11 @@ AC_DEFUN([SC_ENABLE_THREADS], [
# Does the pthread-implementation provide
# 'pthread_attr_setstacksize' ?
- AC_CHECK_FUNCS(pthread_attr_setstacksize)
+
+ ac_saved_libs=$LIBS
+ LIBS="$LIBS $THREADS_LIBS"
+ AC_CHECK_FUNCS(pthread_attr_setstacksize pthread_atfork)
+ LIBS=$ac_saved_libs
else
TCL_THREADS=0
fi
@@ -786,7 +789,6 @@ AC_DEFUN([SC_ENABLE_SYMBOLS], [
#
# Defines the following vars:
# HAVE_LANGINFO Triggers use of nl_langinfo if defined.
-#
#------------------------------------------------------------------------
AC_DEFUN([SC_ENABLE_LANGINFO], [
@@ -1041,33 +1043,17 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [
AC_CACHE_CHECK([if compiler supports visibility "hidden"],
tcl_cv_cc_visibility_hidden, [
- AS_IF([test "$SHARED_BUILD" = 1], [
- hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -fvisibility=hidden -Werror"
- AC_TRY_COMPILE(,[#if !defined(__GNUC__) || __GNUC__ < 4
-#error visibility hidden is not supported for this compiler
-#endif
- ], tcl_cv_cc_visibility_hidden=yes,
- tcl_cv_cc_visibility_hidden=no)
- CFLAGS=$hold_cflags
- ], [
- tcl_cv_cc_visibility_hidden=no
- ])
- ])
- AS_IF([test $tcl_cv_cc_visibility_hidden = yes], [
- CFLAGS="$CFLAGS -fvisibility=hidden"
- AC_DEFINE(MODULE_SCOPE, [extern], [No need to mark inidividual symbols as hidden])
- ], [
hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror"
AC_TRY_LINK([
extern __attribute__((__visibility__("hidden"))) void f(void);
void f(void) {}], [f();], tcl_cv_cc_visibility_hidden=yes,
tcl_cv_cc_visibility_hidden=no)
- CFLAGS=$hold_cflags
- AS_IF([test $tcl_cv_cc_visibility_hidden = yes], [
- AC_DEFINE(MODULE_SCOPE,
- [extern __attribute__((__visibility__("hidden")))],
- [Compiler support for module scope symbols])
- ])
+ CFLAGS=$hold_cflags])
+ AS_IF([test $tcl_cv_cc_visibility_hidden = yes], [
+ AC_DEFINE(MODULE_SCOPE,
+ [extern __attribute__((__visibility__("hidden")))],
+ [Compiler support for module scope symbols])
+ AC_DEFINE(HAVE_HIDDEN, [1], [Compiler support for module scope symbols])
])
# Step 0.d: Disable -rpath support?
@@ -1223,13 +1209,16 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [
SHLIB_CFLAGS=""
SHLIB_LD='${CC} -shared'
SHLIB_SUFFIX=".dll"
- DL_OBJS="tclLoadDl.o tclWinError.o"
+ DL_OBJS="tclLoadDl.o"
+ PLAT_OBJS='${CYGWIN_OBJS}'
+ PLAT_SRCS='${CYGWIN_SRCS}'
DL_LIBS="-ldl"
CC_SEARCH_FLAGS=""
LD_SEARCH_FLAGS=""
TCL_NEEDS_EXP_FILE=1
TCL_EXPORT_FILE_SUFFIX='${VERSION}\$\{DBGX\}.dll.a'
TCL_SHLIB_LD_EXTRAS='-Wl,--out-implib,$[@].a'
+ TK_SHLIB_LD_EXTRAS='-Wl,--out-implib,$[@].a'
AC_CACHE_CHECK(for Cygwin version of gcc,
ac_cv_cygwin,
AC_TRY_COMPILE([
@@ -1246,8 +1235,15 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [
if test "x${TCL_THREADS}" = "x0"; then
AC_MSG_ERROR([CYGWIN compile is only supported with --enable-threads])
fi
- if test "x${SHARED_BUILD}" = "x1" -a ! -f "../win/tcldde14.dll" -a ! -f "../win/tk86.dll"; then
- AC_MSG_ERROR([Please configure and make the ../win directory first.])
+ do64bit_ok=yes
+ if test "x${SHARED_BUILD}" = "x1"; then
+ echo "running cd ${TCL_SRC_DIR}/win; ${CONFIG_SHELL-/bin/sh} ./configure $ac_configure_args"
+ # The eval makes quoting arguments work.
+ if cd ${TCL_SRC_DIR}/win; eval ${CONFIG_SHELL-/bin/sh} ./configure $ac_configure_args; cd ../unix
+ then :
+ else
+ { echo "configure: error: configure failed for ../win" 1>&2; exit 1; }
+ fi
fi
;;
dgux*)
@@ -1398,7 +1394,7 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [
])
])
;;
- Linux*)
+ Linux*|GNU*|NetBSD-Debian)
SHLIB_CFLAGS="-fPIC"
SHLIB_SUFFIX=".so"
@@ -1436,18 +1432,6 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [
AS_IF([test x"${USE_COMPAT}" != x],[CFLAGS="$CFLAGS -fno-inline"])
;;
- GNU*)
- SHLIB_CFLAGS="-fPIC"
- SHLIB_SUFFIX=".so"
-
- SHLIB_LD='${CC} -shared'
- DL_OBJS=""
- DL_LIBS="-ldl"
- LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
- CC_SEARCH_FLAGS=""
- LD_SEARCH_FLAGS=""
- AS_IF([test "`uname -m`" = "alpha"], [CFLAGS="$CFLAGS -mieee"])
- ;;
Lynx*)
SHLIB_CFLAGS="-fPIC"
SHLIB_SUFFIX=".so"
@@ -1481,40 +1465,15 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [
CC_SEARCH_FLAGS=""
LD_SEARCH_FLAGS=""
;;
- NetBSD-1.*|FreeBSD-[[1-2]].*)
- SHLIB_CFLAGS="-fPIC"
- SHLIB_LD="ld -Bshareable -x"
- SHLIB_SUFFIX=".so"
- DL_OBJS="tclLoadDl.o"
- DL_LIBS=""
- AS_IF([test $doRpath = yes], [
- CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
- LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
- AC_CACHE_CHECK([for ELF], tcl_cv_ld_elf, [
- AC_EGREP_CPP(yes, [
-#ifdef __ELF__
- yes
-#endif
- ], tcl_cv_ld_elf=yes, tcl_cv_ld_elf=no)])
- AS_IF([test $tcl_cv_ld_elf = yes], [
- SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so'
- ], [
- SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.${SHLIB_VERSION}'
- ])
-
- # Ancient FreeBSD doesn't handle version numbers with dots.
-
- UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
- TCL_LIB_VERSIONS_OK=nodots
- ;;
OpenBSD-*)
arch=`arch -s`
case "$arch" in
- m88k|vax)
+ vax)
# Equivalent using configure option --disable-load
# Step 4 will set the necessary variables
DL_OBJS=""
SHLIB_LD_LIBS=""
+ LDFLAGS=""
;;
*)
SHLIB_CFLAGS="-fPIC"
@@ -1526,10 +1485,11 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [
CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.${SHLIB_VERSION}'
+ LDFLAGS="-Wl,-export-dynamic"
;;
esac
case "$arch" in
- m88k|vax)
+ vax)
CFLAGS_OPTIMIZE="-O1"
;;
sh)
@@ -1539,15 +1499,6 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [
CFLAGS_OPTIMIZE="-O2"
;;
esac
- AC_CACHE_CHECK([for ELF], tcl_cv_ld_elf, [
- AC_EGREP_CPP(yes, [
-#ifdef __ELF__
- yes
-#endif
- ], tcl_cv_ld_elf=yes, tcl_cv_ld_elf=no)])
- AS_IF([test $tcl_cv_ld_elf = yes], [
- LDFLAGS=-Wl,-export-dynamic
- ], [LDFLAGS=""])
AS_IF([test "${TCL_THREADS}" = "1"], [
# On OpenBSD: Compile with -pthread
# Don't link with -lpthread
@@ -1558,9 +1509,8 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [
UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
TCL_LIB_VERSIONS_OK=nodots
;;
- NetBSD-*|FreeBSD-[[3-4]].*)
- # FreeBSD 3.* and greater have ELF.
- # NetBSD 2.* has ELF and can use 'cc -shared' to build shared libs
+ NetBSD-*)
+ # NetBSD has ELF and can use 'cc -shared' to build shared libs
SHLIB_CFLAGS="-fPIC"
SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}'
SHLIB_SUFFIX=".so"
@@ -1576,37 +1526,34 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [
CFLAGS="$CFLAGS -pthread"
LDFLAGS="$LDFLAGS -pthread"
])
- case $system in
- FreeBSD-3.*)
- # FreeBSD-3 doesn't handle version numbers with dots.
- UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
- SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so'
- TCL_LIB_VERSIONS_OK=nodots
- ;;
- esac
;;
FreeBSD-*)
# This configuration from FreeBSD Ports.
SHLIB_CFLAGS="-fPIC"
SHLIB_LD="${CC} -shared"
- TCL_SHLIB_LD_EXTRAS="-soname \$[@]"
+ TCL_SHLIB_LD_EXTRAS="-Wl,-soname=\$[@]"
+ TK_SHLIB_LD_EXTRAS="-Wl,-soname,\$[@]"
SHLIB_SUFFIX=".so"
DL_OBJS="tclLoadDl.o"
DL_LIBS=""
LDFLAGS=""
AS_IF([test $doRpath = yes], [
CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
- LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
+ LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
AS_IF([test "${TCL_THREADS}" = "1"], [
# The -pthread needs to go in the LDFLAGS, not LIBS
LIBS=`echo $LIBS | sed s/-pthread//`
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
LDFLAGS="$LDFLAGS $PTHREAD_LIBS"])
- # Version numbers are dot-stripped by system policy.
- TCL_TRIM_DOTS=`echo ${VERSION} | tr -d .`
- UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
- SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}\$\{DBGX\}.so.1'
- TCL_LIB_VERSIONS_OK=nodots
+ case $system in
+ FreeBSD-3.*)
+ # Version numbers are dot-stripped by system policy.
+ TCL_TRIM_DOTS=`echo ${VERSION} | tr -d .`
+ UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+ SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so'
+ TCL_LIB_VERSIONS_OK=nodots
+ ;;
+ esac
;;
Darwin-*)
CFLAGS_OPTIMIZE="-Os"
@@ -1685,7 +1632,6 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [
AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [
AC_DEFINE(MODULE_SCOPE, [__private_extern__],
[Compiler support for module scope symbols])
- tcl_cv_cc_visibility_hidden=yes
])
CC_SEARCH_FLAGS=""
LD_SEARCH_FLAGS=""
@@ -2087,7 +2033,6 @@ dnl # preprocessing tests use only CPPFLAGS.
AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [
AC_DEFINE(MODULE_SCOPE, [extern],
[No Compiler support for module scope symbols])
- AC_DEFINE(NO_VIZ, [], [No visibility attribute])
])
AS_IF([test "$SHARED_LIB_SUFFIX" = ""], [
@@ -2191,124 +2136,6 @@ dnl # preprocessing tests use only CPPFLAGS.
])
#--------------------------------------------------------------------
-# SC_SERIAL_PORT
-#
-# Determine which interface to use to talk to the serial port.
-# Note that #include lines must begin in leftmost column for
-# some compilers to recognize them as preprocessor directives,
-# and some build environments have stdin not pointing at a
-# pseudo-terminal (usually /dev/null instead.)
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Defines only one of the following vars:
-# HAVE_SYS_MODEM_H
-# USE_TERMIOS
-# USE_TERMIO
-# USE_SGTTY
-#
-#--------------------------------------------------------------------
-
-AC_DEFUN([SC_SERIAL_PORT], [
- AC_CHECK_HEADERS(sys/modem.h)
- AC_CACHE_CHECK([termios vs. termio vs. sgtty], tcl_cv_api_serial, [
- AC_TRY_RUN([
-#include <termios.h>
-
-int main() {
- struct termios t;
- if (tcgetattr(0, &t) == 0) {
- cfsetospeed(&t, 0);
- t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB;
- return 0;
- }
- return 1;
-}], tcl_cv_api_serial=termios, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
- if test $tcl_cv_api_serial = no ; then
- AC_TRY_RUN([
-#include <termio.h>
-
-int main() {
- struct termio t;
- if (ioctl(0, TCGETA, &t) == 0) {
- t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB;
- return 0;
- }
- return 1;
-}], tcl_cv_api_serial=termio, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
- fi
- if test $tcl_cv_api_serial = no ; then
- AC_TRY_RUN([
-#include <sgtty.h>
-
-int main() {
- struct sgttyb t;
- if (ioctl(0, TIOCGETP, &t) == 0) {
- t.sg_ospeed = 0;
- t.sg_flags |= ODDP | EVENP | RAW;
- return 0;
- }
- return 1;
-}], tcl_cv_api_serial=sgtty, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
- fi
- if test $tcl_cv_api_serial = no ; then
- AC_TRY_RUN([
-#include <termios.h>
-#include <errno.h>
-
-int main() {
- struct termios t;
- if (tcgetattr(0, &t) == 0
- || errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
- cfsetospeed(&t, 0);
- t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB;
- return 0;
- }
- return 1;
-}], tcl_cv_api_serial=termios, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
- fi
- if test $tcl_cv_api_serial = no; then
- AC_TRY_RUN([
-#include <termio.h>
-#include <errno.h>
-
-int main() {
- struct termio t;
- if (ioctl(0, TCGETA, &t) == 0
- || errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
- t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB;
- return 0;
- }
- return 1;
- }], tcl_cv_api_serial=termio, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
- fi
- if test $tcl_cv_api_serial = no; then
- AC_TRY_RUN([
-#include <sgtty.h>
-#include <errno.h>
-
-int main() {
- struct sgttyb t;
- if (ioctl(0, TIOCGETP, &t) == 0
- || errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
- t.sg_ospeed = 0;
- t.sg_flags |= ODDP | EVENP | RAW;
- return 0;
- }
- return 1;
-}], tcl_cv_api_serial=sgtty, tcl_cv_api_serial=none, tcl_cv_api_serial=none)
- fi])
- case $tcl_cv_api_serial in
- termios) AC_DEFINE(USE_TERMIOS, 1, [Use the termios API for serial lines]);;
- termio) AC_DEFINE(USE_TERMIO, 1, [Use the termio API for serial lines]);;
- sgtty) AC_DEFINE(USE_SGTTY, 1, [Use the sgtty API for serial lines]);;
- esac
-])
-
-#--------------------------------------------------------------------
# SC_MISSING_POSIX_HEADERS
#
# Supply substitutes for missing POSIX header files. Special
@@ -2420,9 +2247,9 @@ AC_DEFUN([SC_PATH_X], [
not_really_there=""
if test "$no_x" = ""; then
if test "$x_includes" = ""; then
- AC_TRY_CPP([#include <X11/XIntrinsic.h>], , not_really_there="yes")
+ AC_TRY_CPP([#include <X11/Xlib.h>], , not_really_there="yes")
else
- if test ! -r $x_includes/X11/Intrinsic.h; then
+ if test ! -r $x_includes/X11/Xlib.h; then
not_really_there="yes"
fi
fi
@@ -2430,11 +2257,11 @@ AC_DEFUN([SC_PATH_X], [
if test "$no_x" = "yes" -o "$not_really_there" = "yes"; then
AC_MSG_CHECKING([for X11 header files])
found_xincludes="no"
- AC_TRY_CPP([#include <X11/Intrinsic.h>], found_xincludes="yes", found_xincludes="no")
+ AC_TRY_CPP([#include <X11/Xlib.h>], found_xincludes="yes", found_xincludes="no")
if test "$found_xincludes" = "no"; then
dirs="/usr/unsupported/include /usr/local/include /usr/X386/include /usr/X11R6/include /usr/X11R5/include /usr/include/X11R5 /usr/include/X11R4 /usr/openwin/include /usr/X11/include /usr/sww/include"
for i in $dirs ; do
- if test -r $i/X11/Intrinsic.h; then
+ if test -r $i/X11/Xlib.h; then
AC_MSG_RESULT([$i])
XINCLUDES=" -I$i"
found_xincludes="yes"
@@ -2805,7 +2632,7 @@ AC_DEFUN([SC_TCL_64BIT_FLAGS], [
# Now check for auxiliary declarations
AC_CACHE_CHECK([for struct dirent64], tcl_cv_struct_dirent64,[
AC_TRY_COMPILE([#include <sys/types.h>
-#include <sys/dirent.h>],[struct dirent64 p;],
+#include <dirent.h>],[struct dirent64 p;],
tcl_cv_struct_dirent64=yes,tcl_cv_struct_dirent64=no)])
if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then
AC_DEFINE(HAVE_STRUCT_DIRENT64, 1, [Is 'struct dirent64' in <sys/types.h>?])
diff --git a/unix/tcl.pc.in b/unix/tcl.pc.in
index 8bf67cd..846cb11 100644
--- a/unix/tcl.pc.in
+++ b/unix/tcl.pc.in
@@ -8,8 +8,8 @@ includedir=@includedir@
Name: Tool Command Language
Description: Tcl is a powerful, easy-to-learn dynamic programming language, suitable for a wide range of uses.
URL: http://www.tcl.tk/
-Version: @TCL_VERSION@
-Requires:
-Conflicts:
-Libs: -L${libdir} @TCL_LIBS@
+Version: @TCL_VERSION@@TCL_PATCH_LEVEL@
+Requires.private: zlib >= 1.2.3
+Libs: -L${libdir} @TCL_LIB_FLAG@ @TCL_STUB_LIB_FLAG@
+Libs.private: @TCL_LIBS@
Cflags: -I${includedir}
diff --git a/unix/tcl.spec b/unix/tcl.spec
index 27f7189..678222c 100644
--- a/unix/tcl.spec
+++ b/unix/tcl.spec
@@ -4,7 +4,7 @@
Name: tcl
Summary: Tcl scripting language development environment
-Version: 8.6.0
+Version: 8.6.1
Release: 2
License: BSD
Group: Development/Languages
diff --git a/unix/tclAppInit.c b/unix/tclAppInit.c
index 159bbd8..9bbc88b 100644
--- a/unix/tclAppInit.c
+++ b/unix/tclAppInit.c
@@ -22,14 +22,14 @@ extern Tcl_PackageInitProc Tcltest_SafeInit;
#endif /* TCL_TEST */
#ifdef TCL_XT_TEST
-extern void XtToolkitInitialize(void);
-extern int Tclxttest_Init(Tcl_Interp *interp);
-#endif
+extern void XtToolkitInitialize(void);
+extern Tcl_PackageInitProc Tclxttest_Init;
+#endif /* TCL_XT_TEST */
/*
* The following #if block allows you to change the AppInit function by using
* a #define of TCL_LOCAL_APPINIT instead of rewriting this entire file. The
- * #if checks for that #define and uses Tcl_AppInit if it doesn't exist.
+ * #if checks for that #define and uses Tcl_AppInit if it does not exist.
*/
#ifndef TCL_LOCAL_APPINIT
@@ -48,7 +48,7 @@ MODULE_SCOPE int main(int, char **);
*/
#ifdef TCL_LOCAL_MAIN_HOOK
-extern int TCL_LOCAL_MAIN_HOOK(int *argc, char ***argv);
+MODULE_SCOPE int TCL_LOCAL_MAIN_HOOK(int *argc, char ***argv);
#endif
/*
@@ -71,7 +71,7 @@ extern int TCL_LOCAL_MAIN_HOOK(int *argc, char ***argv);
int
main(
int argc, /* Number of command-line arguments. */
- char **argv) /* Values of command-line arguments. */
+ char *argv[]) /* Values of command-line arguments. */
{
#ifdef TCL_XT_TEST
XtToolkitInitialize();
@@ -145,14 +145,16 @@ Tcl_AppInit(
/*
* Specify a user-specific startup file to invoke if the application is
* run interactively. Typically the startup file is "~/.apprc" where "app"
- * is the name of the application. If this line is deleted then no user-
- * specific startup file will be run under any conditions.
+ * is the name of the application. If this line is deleted then no
+ * user-specific startup file will be run under any conditions.
*/
#ifdef DJGPP
- (Tcl_SetVar)(interp, "tcl_rcFileName", "~/tclsh.rc", TCL_GLOBAL_ONLY);
+ (Tcl_ObjSetVar2)(interp, Tcl_NewStringObj("tcl_rcFileName", -1), NULL,
+ Tcl_NewStringObj("~/tclsh.rc", -1), TCL_GLOBAL_ONLY);
#else
- (Tcl_SetVar)(interp, "tcl_rcFileName", "~/.tclshrc", TCL_GLOBAL_ONLY);
+ (Tcl_ObjSetVar2)(interp, Tcl_NewStringObj("tcl_rcFileName", -1), NULL,
+ Tcl_NewStringObj("~/.tclshrc", -1), TCL_GLOBAL_ONLY);
#endif
return TCL_OK;
diff --git a/unix/tclConfig.h.in b/unix/tclConfig.h.in
index f171cce..e55dcd0 100644
--- a/unix/tclConfig.h.in
+++ b/unix/tclConfig.h.in
@@ -115,6 +115,9 @@
/* Define to 1 if you have the `gmtime_r' function. */
#undef HAVE_GMTIME_R
+/* Compiler support for module scope symbols */
+#undef HAVE_HIDDEN
+
/* Do we have the intptr_t type? */
#undef HAVE_INTPTR_T
@@ -241,6 +244,9 @@
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
+/* Define to 1 if you have the <termios.h> header file. */
+#undef HAVE_TERMIOS_H
+
/* Should we use the global timezone variable? */
#undef HAVE_TIMEZONE_VAR
@@ -340,9 +346,6 @@
/* Do we have <values.h>? */
#undef NO_VALUES_H
-/* No visibility attribute */
-#undef NO_VIZ
-
/* Do we have wait3() */
#undef NO_WAIT3
@@ -433,15 +436,6 @@
/* Should we use FIONBIO? */
#undef USE_FIONBIO
-/* Use the sgtty API for serial lines */
-#undef USE_SGTTY
-
-/* Use the termio API for serial lines */
-#undef USE_TERMIO
-
-/* Use the termios API for serial lines */
-#undef USE_TERMIOS
-
/* Do we want to use the threaded memory allocator? */
#undef USE_THREAD_ALLOC
diff --git a/unix/tclConfig.sh.in b/unix/tclConfig.sh.in
index d47e686..b58e9fd 100644
--- a/unix/tclConfig.sh.in
+++ b/unix/tclConfig.sh.in
@@ -165,5 +165,5 @@ TCL_BUILD_STUB_LIB_PATH='@TCL_BUILD_STUB_LIB_PATH@'
# Path to the Tcl stub library in the install directory.
TCL_STUB_LIB_PATH='@TCL_STUB_LIB_PATH@'
-# Flag, 1: we built Tcl with threads enables, 0 we didn't
+# Flag, 1: we built Tcl with threads enabled, 0 we didn't
TCL_THREADS=@TCL_THREADS@
diff --git a/unix/tclUnixChan.c b/unix/tclUnixChan.c
index 9ee37f1..fdc9d1d 100644
--- a/unix/tclUnixChan.c
+++ b/unix/tclUnixChan.c
@@ -14,16 +14,9 @@
#include "tclInt.h" /* Internal definitions for Tcl. */
#include "tclIO.h" /* To get Channel type declaration. */
-#define SUPPORTS_TTY
-
-#undef DIRECT_BAUD
-#ifdef B4800
-# if (B4800 == 4800)
-# define DIRECT_BAUD
-# endif /* B4800 == 4800 */
-#endif /* B4800 */
-
-#ifdef USE_TERMIOS
+#undef SUPPORTS_TTY
+#if defined(HAVE_TERMIOS_H)
+# define SUPPORTS_TTY 1
# include <termios.h>
# ifdef HAVE_SYS_IOCTL_H
# include <sys/ioctl.h>
@@ -31,60 +24,29 @@
# ifdef HAVE_SYS_MODEM_H
# include <sys/modem.h>
# endif /* HAVE_SYS_MODEM_H */
-# define IOSTATE struct termios
-# define GETIOSTATE(fd, statePtr) tcgetattr((fd), (statePtr))
-# define SETIOSTATE(fd, statePtr) tcsetattr((fd), TCSADRAIN, (statePtr))
-# define GETCONTROL(fd, intPtr) ioctl((fd), TIOCMGET, (intPtr))
-# define SETCONTROL(fd, intPtr) ioctl((fd), TIOCMSET, (intPtr))
# ifdef FIONREAD
# define GETREADQUEUE(fd, int) ioctl((fd), FIONREAD, &(int))
# elif defined(FIORDCHK)
# define GETREADQUEUE(fd, int) int = ioctl((fd), FIORDCHK, NULL)
-# endif /* FIONREAD */
+# else
+# define GETREADQUEUE(fd, int) int = 0
+# endif
+
# ifdef TIOCOUTQ
# define GETWRITEQUEUE(fd, int) ioctl((fd), TIOCOUTQ, &(int))
-# endif /* TIOCOUTQ */
-# if defined(TIOCSBRK) && defined(TIOCCBRK)
-
-/*
- * Can't use ?: operator below because that messes up types on either Linux or
- * Solaris (the two are mutually exclusive!)
- */
+# else
+# define GETWRITEQUEUE(fd, int) int = 0
+# endif
-# define SETBREAK(fd, flag) \
- if (flag) { \
- ioctl((fd), TIOCSBRK, NULL); \
- } else { \
- ioctl((fd), TIOCCBRK, NULL); \
- }
-# endif /* TIOCSBRK&TIOCCBRK */
# if !defined(CRTSCTS) && defined(CNEW_RTSCTS)
# define CRTSCTS CNEW_RTSCTS
# endif /* !CRTSCTS&CNEW_RTSCTS */
# if !defined(PAREXT) && defined(CMSPAR)
# define PAREXT CMSPAR
# endif /* !PAREXT&&CMSPAR */
-#else /* !USE_TERMIOS */
-
-#ifdef USE_TERMIO
-# include <termio.h>
-# define IOSTATE struct termio
-# define GETIOSTATE(fd, statePtr) ioctl((fd), TCGETA, (statePtr))
-# define SETIOSTATE(fd, statePtr) ioctl((fd), TCSETAW, (statePtr))
-#else /* !USE_TERMIO */
-
-#ifdef USE_SGTTY
-# include <sgtty.h>
-# define IOSTATE struct sgttyb
-# define GETIOSTATE(fd, statePtr) ioctl((fd), TIOCGETP, (statePtr))
-# define SETIOSTATE(fd, statePtr) ioctl((fd), TIOCSETP, (statePtr))
-#else /* !USE_SGTTY */
-# undef SUPPORTS_TTY
-#endif /* !USE_SGTTY */
-
-#endif /* !USE_TERMIO */
-#endif /* !USE_TERMIOS */
+
+#endif /* HAVE_TERMIOS_H */
/*
* Helper macros to make parts of this file clearer. The macros do exactly
@@ -110,18 +72,6 @@ typedef struct FileState {
#ifdef SUPPORTS_TTY
/*
- * The following structure describes per-instance state of a tty-based
- * channel.
- */
-
-typedef struct TtyState {
- FileState fs; /* Per-instance state of the file descriptor.
- * Must be the first field. */
- IOSTATE savedState; /* Initial state of device. Used to reset
- * state when device closed. */
-} TtyState;
-
-/*
* The following structure is used to set or get the serial port attributes in
* a platform-independant manner.
*/
@@ -167,15 +117,12 @@ static void TtyGetAttributes(int fd, TtyAttrs *ttyPtr);
static int TtyGetOptionProc(ClientData instanceData,
Tcl_Interp *interp, const char *optionName,
Tcl_DString *dsPtr);
-#ifndef DIRECT_BAUD
-static int TtyGetBaud(unsigned long speed);
-static unsigned long TtyGetSpeed(int baud);
-#endif /* DIRECT_BAUD */
-static FileState * TtyInit(int fd, int initialize);
+static int TtyGetBaud(speed_t speed);
+static speed_t TtyGetSpeed(int baud);
+static void TtyInit(int fd);
static void TtyModemStatusStr(int status, Tcl_DString *dsPtr);
static int TtyParseMode(Tcl_Interp *interp, const char *mode,
- int *speedPtr, int *parityPtr, int *dataPtr,
- int *stopPtr);
+ TtyAttrs *ttyPtr);
static void TtySetAttributes(int fd, TtyAttrs *ttyPtr);
static int TtySetOptionProc(ClientData instanceData,
Tcl_Interp *interp, const char *optionName,
@@ -573,7 +520,6 @@ FileGetHandleProc(
}
#ifdef SUPPORTS_TTY
-#ifdef USE_TERMIOS
/*
*----------------------------------------------------------------------
*
@@ -606,7 +552,6 @@ TtyModemStatusStr(
Tcl_DStringAppendElement(dsPtr, (status & TIOCM_CD) ? "1" : "0");
#endif /* TIOCM_CD */
}
-#endif /* USE_TERMIOS */
/*
*----------------------------------------------------------------------
@@ -636,11 +581,9 @@ TtySetOptionProc(
FileState *fsPtr = instanceData;
unsigned int len, vlen;
TtyAttrs tty;
-#ifdef USE_TERMIOS
- int flag, control, argc;
+ int argc;
const char **argv;
- IOSTATE iostate;
-#endif /* USE_TERMIOS */
+ struct termios iostate;
len = strlen(optionName);
vlen = strlen(value);
@@ -650,8 +593,7 @@ TtySetOptionProc(
*/
if ((len > 2) && (strncmp(optionName, "-mode", len) == 0)) {
- if (TtyParseMode(interp, value, &tty.baud, &tty.parity, &tty.data,
- &tty.stop) != TCL_OK) {
+ if (TtyParseMode(interp, value, &tty) != TCL_OK) {
return TCL_ERROR;
}
@@ -663,7 +605,6 @@ TtySetOptionProc(
return TCL_OK;
}
-#ifdef USE_TERMIOS
/*
* Option -handshake none|xonxoff|rtscts|dtrdsr
@@ -674,25 +615,25 @@ TtySetOptionProc(
* Reset all handshake options. DTR and RTS are ON by default.
*/
- GETIOSTATE(fsPtr->fd, &iostate);
+ tcgetattr(fsPtr->fd, &iostate);
CLEAR_BITS(iostate.c_iflag, IXON | IXOFF | IXANY);
#ifdef CRTSCTS
CLEAR_BITS(iostate.c_cflag, CRTSCTS);
#endif /* CRTSCTS */
- if (strncasecmp(value, "NONE", vlen) == 0) {
+ if (Tcl_UtfNcasecmp(value, "NONE", vlen) == 0) {
/*
* Leave all handshake options disabled.
*/
- } else if (strncasecmp(value, "XONXOFF", vlen) == 0) {
+ } else if (Tcl_UtfNcasecmp(value, "XONXOFF", vlen) == 0) {
SET_BITS(iostate.c_iflag, IXON | IXOFF | IXANY);
- } else if (strncasecmp(value, "RTSCTS", vlen) == 0) {
+ } else if (Tcl_UtfNcasecmp(value, "RTSCTS", vlen) == 0) {
#ifdef CRTSCTS
SET_BITS(iostate.c_cflag, CRTSCTS);
#else /* !CRTSTS */
UNSUPPORTED_OPTION("-handshake RTSCTS");
return TCL_ERROR;
#endif /* CRTSCTS */
- } else if (strncasecmp(value, "DTRDSR", vlen) == 0) {
+ } else if (Tcl_UtfNcasecmp(value, "DTRDSR", vlen) == 0) {
UNSUPPORTED_OPTION("-handshake DTRDSR");
return TCL_ERROR;
} else {
@@ -705,7 +646,7 @@ TtySetOptionProc(
}
return TCL_ERROR;
}
- SETIOSTATE(fsPtr->fd, &iostate);
+ tcsetattr(fsPtr->fd, TCSADRAIN, &iostate);
return TCL_OK;
}
@@ -730,7 +671,7 @@ TtySetOptionProc(
return TCL_ERROR;
}
- GETIOSTATE(fsPtr->fd, &iostate);
+ tcgetattr(fsPtr->fd, &iostate);
Tcl_UtfToExternalDString(NULL, argv[0], -1, &ds);
iostate.c_cc[VSTART] = *(const cc_t *) Tcl_DStringValue(&ds);
@@ -741,7 +682,7 @@ TtySetOptionProc(
Tcl_DStringFree(&ds);
ckfree(argv);
- SETIOSTATE(fsPtr->fd, &iostate);
+ tcsetattr(fsPtr->fd, TCSADRAIN, &iostate);
return TCL_OK;
}
@@ -752,22 +693,22 @@ TtySetOptionProc(
if ((len > 2) && (strncmp(optionName, "-timeout", len) == 0)) {
int msec;
- GETIOSTATE(fsPtr->fd, &iostate);
+ tcgetattr(fsPtr->fd, &iostate);
if (Tcl_GetInt(interp, value, &msec) != TCL_OK) {
return TCL_ERROR;
}
iostate.c_cc[VMIN] = 0;
iostate.c_cc[VTIME] = (msec==0) ? 0 : (msec<100) ? 1 : (msec+50)/100;
- SETIOSTATE(fsPtr->fd, &iostate);
+ tcsetattr(fsPtr->fd, TCSADRAIN, &iostate);
return TCL_OK;
}
/*
* Option -ttycontrol {DTR 1 RTS 0 BREAK 0}
*/
-
if ((len > 4) && (strncmp(optionName, "-ttycontrol", len) == 0)) {
- int i;
+#if defined(TIOCMGET) && defined(TIOCMSET)
+ int i, control, flag;
if (Tcl_SplitList(interp, value, &argc, &argv) == TCL_ERROR) {
return TCL_ERROR;
@@ -784,44 +725,36 @@ TtySetOptionProc(
return TCL_ERROR;
}
- GETCONTROL(fsPtr->fd, &control);
+ ioctl(fsPtr->fd, TIOCMGET, &control);
for (i = 0; i < argc-1; i += 2) {
if (Tcl_GetBoolean(interp, argv[i+1], &flag) == TCL_ERROR) {
ckfree(argv);
return TCL_ERROR;
}
- if (strncasecmp(argv[i], "DTR", strlen(argv[i])) == 0) {
-#ifdef TIOCM_DTR
+ if (Tcl_UtfNcasecmp(argv[i], "DTR", strlen(argv[i])) == 0) {
if (flag) {
SET_BITS(control, TIOCM_DTR);
} else {
CLEAR_BITS(control, TIOCM_DTR);
}
-#else /* !TIOCM_DTR */
- UNSUPPORTED_OPTION("-ttycontrol DTR");
- ckfree(argv);
- return TCL_ERROR;
-#endif /* TIOCM_DTR */
- } else if (strncasecmp(argv[i], "RTS", strlen(argv[i])) == 0) {
-#ifdef TIOCM_RTS
+ } else if (Tcl_UtfNcasecmp(argv[i], "RTS", strlen(argv[i])) == 0) {
if (flag) {
SET_BITS(control, TIOCM_RTS);
} else {
CLEAR_BITS(control, TIOCM_RTS);
}
-#else /* !TIOCM_RTS*/
- UNSUPPORTED_OPTION("-ttycontrol RTS");
- ckfree(argv);
- return TCL_ERROR;
-#endif /* TIOCM_RTS*/
- } else if (strncasecmp(argv[i], "BREAK", strlen(argv[i])) == 0) {
-#ifdef SETBREAK
- SETBREAK(fsPtr->fd, flag);
-#else /* !SETBREAK */
+ } else if (Tcl_UtfNcasecmp(argv[i], "BREAK", strlen(argv[i])) == 0) {
+#if defined(TIOCSBRK) && defined(TIOCCBRK)
+ if (flag) {
+ ioctl(fsPtr->fd, TIOCSBRK, NULL);
+ } else {
+ ioctl(fsPtr->fd, TIOCCBRK, NULL);
+ }
+#else /* TIOCSBRK & TIOCCBRK */
UNSUPPORTED_OPTION("-ttycontrol BREAK");
ckfree(argv);
return TCL_ERROR;
-#endif /* SETBREAK */
+#endif /* TIOCSBRK & TIOCCBRK */
} else {
if (interp) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
@@ -835,17 +768,16 @@ TtySetOptionProc(
}
} /* -ttycontrol options loop */
- SETCONTROL(fsPtr->fd, &control);
+ ioctl(fsPtr->fd, TIOCMSET, &control);
ckfree(argv);
return TCL_OK;
+#else /* TIOCMGET&TIOCMSET */
+ UNSUPPORTED_OPTION("-ttycontrol");
+#endif /* TIOCMGET&TIOCMSET */
}
return Tcl_BadChannelOption(interp, optionName,
"mode handshake timeout ttycontrol xchar");
-
-#else /* !USE_TERMIOS */
- return Tcl_BadChannelOption(interp, optionName, "mode");
-#endif /* USE_TERMIOS */
}
/*
@@ -860,12 +792,8 @@ TtySetOptionProc(
*
* Results:
* A standard Tcl result. Also sets the supplied DString to the string
- * value of the option(s) returned.
- *
- * Side effects:
- * The string returned by this function is in static storage and may be
- * reused at any time subsequent to the call. Sets error message if
- * needed (by calling Tcl_BadChannelOption).
+ * value of the option(s) returned. Sets error message if needed
+ * (by calling Tcl_BadChannelOption).
*
*----------------------------------------------------------------------
*/
@@ -899,7 +827,6 @@ TtyGetOptionProc(
Tcl_DStringAppendElement(dsPtr, buf);
}
-#ifdef USE_TERMIOS
/*
* Get option -xchar
*/
@@ -909,11 +836,11 @@ TtyGetOptionProc(
Tcl_DStringStartSublist(dsPtr);
}
if (len==0 || (len>1 && strncmp(optionName, "-xchar", len)==0)) {
- IOSTATE iostate;
+ struct termios iostate;
Tcl_DString ds;
valid = 1;
- GETIOSTATE(fsPtr->fd, &iostate);
+ tcgetattr(fsPtr->fd, &iostate);
Tcl_DStringInit(&ds);
Tcl_ExternalToUtfDString(NULL, (char *) &iostate.c_cc[VSTART], 1, &ds);
@@ -938,12 +865,8 @@ TtyGetOptionProc(
int inQueue=0, outQueue=0, inBuffered, outBuffered;
valid = 1;
-#ifdef GETREADQUEUE
GETREADQUEUE(fsPtr->fd, inQueue);
-#endif /* GETREADQUEUE */
-#ifdef GETWRITEQUEUE
GETWRITEQUEUE(fsPtr->fd, outQueue);
-#endif /* GETWRITEQUEUE */
inBuffered = Tcl_InputBuffered(fsPtr->channel);
outBuffered = Tcl_OutputBuffered(fsPtr->channel);
@@ -953,37 +876,31 @@ TtyGetOptionProc(
Tcl_DStringAppendElement(dsPtr, buf);
}
+#if defined(TIOCMGET)
/*
* Get option -ttystatus
* Option is readonly and returned by [fconfigure chan -ttystatus] but not
* returned by unnamed [fconfigure chan].
*/
-
if ((len > 4) && (strncmp(optionName, "-ttystatus", len) == 0)) {
int status;
valid = 1;
- GETCONTROL(fsPtr->fd, &status);
+ ioctl(fsPtr->fd, TIOCMGET, &status);
TtyModemStatusStr(status, dsPtr);
}
-#endif /* USE_TERMIOS */
+#endif /* TIOCMGET */
if (valid) {
return TCL_OK;
}
return Tcl_BadChannelOption(interp, optionName, "mode"
-#ifdef USE_TERMIOS
" queue ttystatus xchar"
-#endif /* USE_TERMIOS */
);
}
-#ifdef DIRECT_BAUD
-# define TtyGetSpeed(baud) ((unsigned) (baud))
-# define TtyGetBaud(speed) ((int) (speed))
-#else /* !DIRECT_BAUD */
-static const struct {int baud; unsigned long speed;} speeds[] = {
+static const struct {int baud; speed_t speed;} speeds[] = {
#ifdef B0
{0, B0},
#endif
@@ -1079,20 +996,16 @@ static const struct {int baud; unsigned long speed;} speeds[] = {
*
* TtyGetSpeed --
*
- * Given a baud rate, get the mask value that should be stored in the
- * termios, termio, or sgttyb structure in order to select that baud
- * rate.
+ * Given an integer baud rate, get the speed_t value that should be
+ * used to select that baud rate.
*
* Results:
* As above.
*
- * Side effects:
- * None.
- *
*---------------------------------------------------------------------------
*/
-static unsigned long
+static speed_t
TtyGetSpeed(
int baud) /* The baud rate to look up. */
{
@@ -1125,21 +1038,17 @@ TtyGetSpeed(
*
* TtyGetBaud --
*
- * Given a speed mask value from a termios, termio, or sgttyb structure,
- * get the baus rate that corresponds to that mask value.
+ * Return the integer baud rate corresponding to a given speed_t value.
*
* Results:
* As above. If the mask value was not recognized, 0 is returned.
*
- * Side effects:
- * None.
- *
*---------------------------------------------------------------------------
*/
static int
TtyGetBaud(
- unsigned long speed) /* Speed mask value to look up. */
+ speed_t speed) /* Speed mask value to look up. */
{
int i;
@@ -1150,7 +1059,6 @@ TtyGetBaud(
}
return 0;
}
-#endif /* !DIRECT_BAUD */
/*
*---------------------------------------------------------------------------
@@ -1175,12 +1083,11 @@ TtyGetAttributes(
TtyAttrs *ttyPtr) /* Buffer filled with serial port
* attributes. */
{
- IOSTATE iostate;
+ struct termios iostate;
int baud, parity, data, stop;
- GETIOSTATE(fd, &iostate);
+ tcgetattr(fd, &iostate);
-#ifdef USE_TERMIOS
baud = TtyGetBaud(cfgetospeed(&iostate));
parity = 'n';
@@ -1202,39 +1109,6 @@ TtyGetAttributes(
data = (data == CS5) ? 5 : (data == CS6) ? 6 : (data == CS7) ? 7 : 8;
stop = (iostate.c_cflag & CSTOPB) ? 2 : 1;
-#endif /* USE_TERMIOS */
-
-#ifdef USE_TERMIO
- baud = TtyGetBaud(iostate.c_cflag & CBAUD);
-
- parity = 'n';
- switch (iostate.c_cflag & (PARENB | PARODD | PAREXT)) {
- case PARENB : parity = 'e'; break;
- case PARENB | PARODD : parity = 'o'; break;
- case PARENB | PAREXT : parity = 's'; break;
- case PARENB | PARODD | PAREXT : parity = 'm'; break;
- }
-
- data = iostate.c_cflag & CSIZE;
- data = (data == CS5) ? 5 : (data == CS6) ? 6 : (data == CS7) ? 7 : 8;
-
- stop = (iostate.c_cflag & CSTOPB) ? 2 : 1;
-#endif /* USE_TERMIO */
-
-#ifdef USE_SGTTY
- baud = TtyGetBaud(iostate.sg_ospeed);
-
- parity = 'n';
- if (iostate.sg_flags & EVENP) {
- parity = 'e';
- } else if (iostate.sg_flags & ODDP) {
- parity = 'o';
- }
-
- data = (iostate.sg_flags & (EVENP | ODDP)) ? 7 : 8;
-
- stop = 1;
-#endif /* USE_SGTTY */
ttyPtr->baud = baud;
ttyPtr->parity = parity;
@@ -1265,12 +1139,10 @@ TtySetAttributes(
TtyAttrs *ttyPtr) /* Buffer containing new attributes for serial
* port. */
{
- IOSTATE iostate;
-
-#ifdef USE_TERMIOS
+ struct termios iostate;
int parity, data, flag;
- GETIOSTATE(fd, &iostate);
+ tcgetattr(fd, &iostate);
cfsetospeed(&iostate, TtyGetSpeed(ttyPtr->baud));
cfsetispeed(&iostate, TtyGetSpeed(ttyPtr->baud));
@@ -1300,58 +1172,7 @@ TtySetAttributes(
CLEAR_BITS(iostate.c_cflag, PARENB | PARODD | CSIZE | CSTOPB);
SET_BITS(iostate.c_cflag, flag);
-#endif /* USE_TERMIOS */
-
-#ifdef USE_TERMIO
- int parity, data, flag;
-
- GETIOSTATE(fd, &iostate);
- CLEAR_BITS(iostate.c_cflag, CBAUD);
- SET_BITS(iostate.c_cflag, TtyGetSpeed(ttyPtr->baud));
-
- flag = 0;
- parity = ttyPtr->parity;
- if (parity != 'n') {
- SET_BITS(flag, PARENB);
- if ((parity == 'm') || (parity == 's')) {
- SET_BITS(flag, PAREXT);
- }
- if ((parity == 'm') || (parity == 'o')) {
- SET_BITS(flag, PARODD);
- }
- }
- data = ttyPtr->data;
- SET_BITS(flag,
- (data == 5) ? CS5 :
- (data == 6) ? CS6 :
- (data == 7) ? CS7 : CS8);
- if (ttyPtr->stop == 2) {
- SET_BITS(flag, CSTOPB);
- }
-
- CLEAR_BITS(iostate.c_cflag, PARENB | PARODD | PAREXT | CSIZE | CSTOPB);
- SET_BITS(iostate.c_cflag, flag);
-
-#endif /* USE_TERMIO */
-
-#ifdef USE_SGTTY
- int parity;
-
- GETIOSTATE(fd, &iostate);
- iostate.sg_ospeed = TtyGetSpeed(ttyPtr->baud);
- iostate.sg_ispeed = TtyGetSpeed(ttyPtr->baud);
-
- parity = ttyPtr->parity;
- if (parity == 'e') {
- CLEAR_BITS(iostate.sg_flags, ODDP);
- SET_BITS(iostate.sg_flags, EVENP);
- } else if (parity == 'o') {
- CLEAR_BITS(iostate.sg_flags, EVENP);
- SET_BITS(iostate.sg_flags, ODDP);
- }
-#endif /* USE_SGTTY */
-
- SETIOSTATE(fd, &iostate);
+ tcsetattr(fd, TCSADRAIN, &iostate);
}
/*
@@ -1367,9 +1188,6 @@ TtySetAttributes(
* TCL_ERROR otherwise. If TCL_ERROR is returned, an error message is
* left in the interp's result (if interp is non-NULL).
*
- * Side effects:
- * None.
- *
*---------------------------------------------------------------------------
*/
@@ -1377,17 +1195,17 @@ static int
TtyParseMode(
Tcl_Interp *interp, /* If non-NULL, interp for error return. */
const char *mode, /* Mode string to be parsed. */
- int *speedPtr, /* Filled with baud rate from mode string. */
- int *parityPtr, /* Filled with parity from mode string. */
- int *dataPtr, /* Filled with data bits from mode string. */
- int *stopPtr) /* Filled with stop bits from mode string. */
+ TtyAttrs *ttyPtr) /* Filled with data from mode string */
{
int i, end;
char parity;
- static const char *bad = "bad value for -mode";
+ const char *bad = "bad value for -mode";
- i = sscanf(mode, "%d,%c,%d,%d%n", speedPtr, &parity, dataPtr,
- stopPtr, &end);
+ i = sscanf(mode, "%d,%c,%d,%d%n",
+ &ttyPtr->baud,
+ &parity,
+ &ttyPtr->data,
+ &ttyPtr->stop, &end);
if ((i != 4) || (mode[end] != '\0')) {
if (interp != NULL) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
@@ -1407,27 +1225,27 @@ TtyParseMode(
*/
if (
-#if defined(PAREXT) || defined(USE_TERMIO)
+#if defined(PAREXT)
strchr("noems", parity)
#else
strchr("noe", parity)
-#endif /* PAREXT|USE_TERMIO */
+#endif /* PAREXT */
== NULL) {
if (interp != NULL) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"%s parity: should be %s", bad,
-#if defined(PAREXT) || defined(USE_TERMIO)
+#if defined(PAREXT)
"n, o, e, m, or s"
#else
"n, o, or e"
-#endif /* PAREXT|USE_TERMIO */
+#endif /* PAREXT */
));
Tcl_SetErrorCode(interp, "TCL", "VALUE", "SERIALMODE", NULL);
}
return TCL_ERROR;
}
- *parityPtr = parity;
- if ((*dataPtr < 5) || (*dataPtr > 8)) {
+ ttyPtr->parity = parity;
+ if ((ttyPtr->data < 5) || (ttyPtr->data > 8)) {
if (interp != NULL) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"%s data: should be 5, 6, 7, or 8", bad));
@@ -1435,7 +1253,7 @@ TtyParseMode(
}
return TCL_ERROR;
}
- if ((*stopPtr < 0) || (*stopPtr > 2)) {
+ if ((ttyPtr->stop < 0) || (ttyPtr->stop > 2)) {
if (interp != NULL) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"%s stop: should be 1 or 2", bad));
@@ -1453,71 +1271,38 @@ TtyParseMode(
*
* Given file descriptor that refers to a serial port, initialize the
* serial port to a set of sane values so that Tcl can talk to a device
- * located on the serial port. Note that no initialization happens if the
- * initialize flag is not set; this is necessary for the correct handling
- * of UNIX console TTYs at startup.
- *
- * Results:
- * A pointer to a FileState suitable for use with Tcl_CreateChannel and
- * the ttyChannelType structure.
+ * located on the serial port.
*
* Side effects:
* Serial device initialized to non-blocking raw mode, similar to sockets
- * (if initialize flag is non-zero.) All other modes can be simulated on
- * top of this in Tcl.
+ * All other modes can be simulated on top of this in Tcl.
*
*---------------------------------------------------------------------------
*/
-static FileState *
+static void
TtyInit(
- int fd, /* Open file descriptor for serial port to be
- * initialized. */
- int initialize)
+ int fd) /* Open file descriptor for serial port to be initialized. */
{
- TtyState *ttyPtr = ckalloc(sizeof(TtyState));
- int stateUpdated = 0;
-
- GETIOSTATE(fd, &ttyPtr->savedState);
- if (initialize) {
- IOSTATE iostate = ttyPtr->savedState;
-
-#if defined(USE_TERMIOS) || defined(USE_TERMIO)
- if (iostate.c_iflag != IGNBRK
- || iostate.c_oflag != 0
- || iostate.c_lflag != 0
- || iostate.c_cflag & CREAD
- || iostate.c_cc[VMIN] != 1
- || iostate.c_cc[VTIME] != 0) {
- stateUpdated = 1;
- }
+ struct termios iostate;
+ tcgetattr(fd, &iostate);
+
+ if (iostate.c_iflag != IGNBRK
+ || iostate.c_oflag != 0
+ || iostate.c_lflag != 0
+ || iostate.c_cflag & CREAD
+ || iostate.c_cc[VMIN] != 1
+ || iostate.c_cc[VTIME] != 0)
+ {
iostate.c_iflag = IGNBRK;
iostate.c_oflag = 0;
iostate.c_lflag = 0;
- SET_BITS(iostate.c_cflag, CREAD);
+ iostate.c_cflag |= CREAD;
iostate.c_cc[VMIN] = 1;
iostate.c_cc[VTIME] = 0;
-#endif /* USE_TERMIOS|USE_TERMIO */
-
-#ifdef USE_SGTTY
- if ((iostate.sg_flags & (EVENP | ODDP))
- || !(iostate.sg_flags & RAW)) {
- ttyPtr->stateUpdated = 1;
- }
- iostate.sg_flags &= EVENP | ODDP;
- SET_BITS(iostate.sg_flags, RAW);
-#endif /* USE_SGTTY */
-
- /*
- * Only update if we're changing anything to avoid possible blocking.
- */
- if (stateUpdated) {
- SETIOSTATE(fd, &iostate);
- }
+ tcsetattr(fd, TCSADRAIN, &iostate);
}
-
- return &ttyPtr->fs;
}
#endif /* SUPPORTS_TTY */
@@ -1621,15 +1406,15 @@ TclpOpenFileChannel(
translation = "auto crlf";
channelTypePtr = &ttyChannelType;
- fsPtr = TtyInit(fd, 1);
+ TtyInit(fd);
} else
#endif /* SUPPORTS_TTY */
{
translation = NULL;
channelTypePtr = &fileChannelType;
- fsPtr = ckalloc(sizeof(FileState));
}
+ fsPtr = ckalloc(sizeof(FileState));
fsPtr->validMask = channelPermissions | TCL_EXCEPTION;
fsPtr->fd = fd;
@@ -1692,7 +1477,6 @@ Tcl_MakeFileChannel(
#ifdef SUPPORTS_TTY
if (isatty(fd)) {
- fsPtr = TtyInit(fd, 0);
channelTypePtr = &ttyChannelType;
sprintf(channelName, "serial%d", fd);
} else
@@ -1703,10 +1487,10 @@ Tcl_MakeFileChannel(
return TclpMakeTcpClientChannelMode(INT2PTR(fd), mode);
} else {
channelTypePtr = &fileChannelType;
- fsPtr = ckalloc(sizeof(FileState));
sprintf(channelName, "file%d", fd);
}
+ fsPtr = ckalloc(sizeof(FileState));
fsPtr->fd = fd;
fsPtr->validMask = mode | TCL_EXCEPTION;
fsPtr->channel = Tcl_CreateChannel(channelTypePtr, channelName,
diff --git a/unix/tclUnixCompat.c b/unix/tclUnixCompat.c
index e201018..2a68f7f 100644
--- a/unix/tclUnixCompat.c
+++ b/unix/tclUnixCompat.c
@@ -995,12 +995,19 @@ TclWinCPUID(
/* See: <http://en.wikipedia.org/wiki/CPUID> */
#if defined(HAVE_CPUID)
- __asm__ __volatile__("mov %%ebx, %%edi \n\t" /* save %ebx */
+#if defined(__x86_64__) || defined(_M_AMD64) || defined (_M_X64)
+ __asm__ __volatile__("movq %%rbx, %%rsi \n\t" /* save %rbx */
"cpuid \n\t"
- "mov %%ebx, %%esi \n\t" /* save what cpuid just put in %ebx */
- "mov %%edi, %%ebx \n\t" /* restore the old %ebx */
+ "xchgq %%rsi, %%rbx \n\t" /* restore the old %rbx */
: "=a"(regsPtr[0]), "=S"(regsPtr[1]), "=c"(regsPtr[2]), "=d"(regsPtr[3])
- : "a"(index) : "edi");
+ : "a"(index));
+#else
+ __asm__ __volatile__("mov %%ebx, %%esi \n\t" /* save %ebx */
+ "cpuid \n\t"
+ "xchg %%esi, %%ebx \n\t" /* restore the old %ebx */
+ : "=a"(regsPtr[0]), "=S"(regsPtr[1]), "=c"(regsPtr[2]), "=d"(regsPtr[3])
+ : "a"(index));
+#endif
status = TCL_OK;
#endif
return status;
diff --git a/unix/tclUnixFCmd.c b/unix/tclUnixFCmd.c
index a703935..3b1b6ca 100644
--- a/unix/tclUnixFCmd.c
+++ b/unix/tclUnixFCmd.c
@@ -40,7 +40,6 @@
* DAMAGE.
*/
-#include <sys/stat.h>
#include "tclInt.h"
#include <utime.h>
#include <grp.h>
@@ -92,10 +91,10 @@ static int SetPermissionsAttribute(Tcl_Interp *interp,
Tcl_Obj *attributePtr);
static int GetModeFromPermString(Tcl_Interp *interp,
const char *modeStringPtr, mode_t *modePtr);
-#if defined(HAVE_CHFLAGS) && defined(UF_IMMUTABLE)
-static int GetReadOnlyAttribute(Tcl_Interp *interp, int objIndex,
+#if defined(HAVE_CHFLAGS) && defined(UF_IMMUTABLE) || defined(__CYGWIN__)
+static int GetUnixFileAttributes(Tcl_Interp *interp, int objIndex,
Tcl_Obj *fileName, Tcl_Obj **attributePtrPtr);
-static int SetReadOnlyAttribute(Tcl_Interp *interp, int objIndex,
+static int SetUnixFileAttributes(Tcl_Interp *interp, int objIndex,
Tcl_Obj *fileName, Tcl_Obj *attributePtr);
#endif
@@ -125,10 +124,20 @@ extern const char *const tclpFileAttrStrings[];
#else /* !DJGPP */
enum {
- UNIX_GROUP_ATTRIBUTE, UNIX_OWNER_ATTRIBUTE, UNIX_PERMISSIONS_ATTRIBUTE,
-#if defined(HAVE_CHFLAGS) && defined(UF_IMMUTABLE)
+#if defined(__CYGWIN__)
+ UNIX_ARCHIVE_ATTRIBUTE,
+#endif
+ UNIX_GROUP_ATTRIBUTE,
+#if defined(__CYGWIN__)
+ UNIX_HIDDEN_ATTRIBUTE,
+#endif
+ UNIX_OWNER_ATTRIBUTE, UNIX_PERMISSIONS_ATTRIBUTE,
+#if defined(HAVE_CHFLAGS) && defined(UF_IMMUTABLE) || defined(__CYGWIN__)
UNIX_READONLY_ATTRIBUTE,
#endif
+#if defined(__CYGWIN__)
+ UNIX_SYSTEM_ATTRIBUTE,
+#endif
#ifdef MAC_OSX_TCL
MACOSX_CREATOR_ATTRIBUTE, MACOSX_TYPE_ATTRIBUTE, MACOSX_HIDDEN_ATTRIBUTE,
MACOSX_RSRCLENGTH_ATTRIBUTE,
@@ -138,10 +147,20 @@ enum {
MODULE_SCOPE const char *const tclpFileAttrStrings[];
const char *const tclpFileAttrStrings[] = {
- "-group", "-owner", "-permissions",
-#if defined(HAVE_CHFLAGS) && defined(UF_IMMUTABLE)
+#if defined(__CYGWIN__)
+ "-archive",
+#endif
+ "-group",
+#if defined(__CYGWIN__)
+ "-hidden",
+#endif
+ "-owner", "-permissions",
+#if defined(HAVE_CHFLAGS) && defined(UF_IMMUTABLE) || defined(__CYGWIN__)
"-readonly",
#endif
+#if defined(__CYGWIN__)
+ "-system",
+#endif
#ifdef MAC_OSX_TCL
"-creator", "-type", "-hidden", "-rsrclength",
#endif
@@ -150,11 +169,20 @@ const char *const tclpFileAttrStrings[] = {
MODULE_SCOPE const TclFileAttrProcs tclpFileAttrProcs[];
const TclFileAttrProcs tclpFileAttrProcs[] = {
+#if defined(__CYGWIN__)
+ {GetUnixFileAttributes, SetUnixFileAttributes},
+#endif
{GetGroupAttribute, SetGroupAttribute},
+#if defined(__CYGWIN__)
+ {GetUnixFileAttributes, SetUnixFileAttributes},
+#endif
{GetOwnerAttribute, SetOwnerAttribute},
{GetPermissionsAttribute, SetPermissionsAttribute},
-#if defined(HAVE_CHFLAGS) && defined(UF_IMMUTABLE)
- {GetReadOnlyAttribute, SetReadOnlyAttribute},
+#if defined(HAVE_CHFLAGS) && defined(UF_IMMUTABLE) || defined(__CYGWIN__)
+ {GetUnixFileAttributes, SetUnixFileAttributes},
+#endif
+#if defined(__CYGWIN__)
+ {GetUnixFileAttributes, SetUnixFileAttributes},
#endif
#ifdef MAC_OSX_TCL
{TclMacOSXGetFileAttribute, TclMacOSXSetFileAttribute},
@@ -245,7 +273,7 @@ MODULE_SCOPE long tclMacOSXDarwinRelease;
#endif /* NO_REALPATH */
#ifdef HAVE_FTS
-#ifdef HAVE_STRUCT_STAT64
+#if defined(HAVE_STRUCT_STAT64) && !defined(__APPLE__)
/* fts doesn't do stat64 */
# define noFtsStat 1
#elif defined(__APPLE__) && defined(__LP64__) && \
@@ -463,10 +491,10 @@ DoCopyFile(
switch ((int) (statBufPtr->st_mode & S_IFMT)) {
#ifndef DJGPP
case S_IFLNK: {
- char linkBuf[MAXPATHLEN];
+ char linkBuf[MAXPATHLEN+1];
int length;
- length = readlink(src, linkBuf, sizeof(linkBuf));
+ length = readlink(src, linkBuf, MAXPATHLEN);
/* INTL: Native. */
if (length == -1) {
return TCL_ERROR;
@@ -2227,13 +2255,13 @@ DefaultTempDir(void)
dir = getenv("TMPDIR");
if (dir && dir[0] && stat(dir, &buf) == 0 && S_ISDIR(buf.st_mode)
- && access(dir, W_OK)) {
+ && access(dir, W_OK) == 0) {
return dir;
}
#ifdef P_tmpdir
dir = P_tmpdir;
- if (stat(dir, &buf) == 0 && S_ISDIR(buf.st_mode) && access(dir, W_OK)) {
+ if (stat(dir, &buf)==0 && S_ISDIR(buf.st_mode) && access(dir, W_OK)==0) {
return dir;
}
#endif
@@ -2247,11 +2275,138 @@ DefaultTempDir(void)
return TCL_TEMPORARY_FILE_DIRECTORY;
}
-#if defined(HAVE_CHFLAGS) && defined(UF_IMMUTABLE)
+#if defined(__CYGWIN__)
+
+static void
+StatError(
+ Tcl_Interp *interp, /* The interp that has the error */
+ Tcl_Obj *fileName) /* The name of the file which caused the
+ * error. */
+{
+ TclWinConvertError(GetLastError());
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf("could not read \"%s\": %s",
+ TclGetString(fileName), Tcl_PosixError(interp)));
+}
+
+static WCHAR *
+winPathFromObj(
+ Tcl_Obj *fileName)
+{
+ int size;
+ const char *native = Tcl_FSGetNativePath(fileName);
+ WCHAR *winPath;
+
+ size = cygwin_conv_path(1, native, NULL, 0);
+ winPath = ckalloc(size);
+ cygwin_conv_path(1, native, winPath, size);
+
+ return winPath;
+}
+
+static const int attributeArray[] = {
+ 0x20, 0, 2, 0, 0, 1, 4};
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetUnixFileAttributes
+ *
+ * Gets the readonly attribute of a file.
+ *
+ * Results:
+ * Standard TCL result. Returns a new Tcl_Obj in attributePtrPtr if there
+ * is no error. The object will have ref count 0.
+ *
+ * Side effects:
+ * A new object is allocated.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+GetUnixFileAttributes(
+ Tcl_Interp *interp, /* The interp we are using for errors. */
+ int objIndex, /* The index of the attribute. */
+ Tcl_Obj *fileName, /* The name of the file (UTF-8). */
+ Tcl_Obj **attributePtrPtr) /* A pointer to return the object with. */
+{
+ int fileAttributes;
+ WCHAR *winPath = winPathFromObj(fileName);
+
+ fileAttributes = GetFileAttributesW(winPath);
+ ckfree(winPath);
+
+ if (fileAttributes == -1) {
+ StatError(interp, fileName);
+ return TCL_ERROR;
+ }
+
+ *attributePtrPtr = Tcl_NewIntObj((fileAttributes&attributeArray[objIndex])!=0);
+
+ return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * SetUnixFileAttributes
+ *
+ * Sets the readonly attribute of a file.
+ *
+ * Results:
+ * Standard TCL result.
+ *
+ * Side effects:
+ * The readonly attribute of the file is changed.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static int
+SetUnixFileAttributes(
+ Tcl_Interp *interp, /* The interp we are using for errors. */
+ int objIndex, /* The index of the attribute. */
+ Tcl_Obj *fileName, /* The name of the file (UTF-8). */
+ Tcl_Obj *attributePtr) /* The attribute to set. */
+{
+ int yesNo, fileAttributes, old;
+ WCHAR *winPath;
+
+ if (Tcl_GetBooleanFromObj(interp, attributePtr, &yesNo) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ winPath = winPathFromObj(fileName);
+
+ fileAttributes = old = GetFileAttributesW(winPath);
+
+ if (fileAttributes == -1) {
+ ckfree(winPath);
+ StatError(interp, fileName);
+ return TCL_ERROR;
+ }
+
+ if (yesNo) {
+ fileAttributes |= attributeArray[objIndex];
+ } else {
+ fileAttributes &= ~attributeArray[objIndex];
+ }
+
+ if ((fileAttributes != old)
+ && !SetFileAttributesW(winPath, fileAttributes)) {
+ ckfree(winPath);
+ StatError(interp, fileName);
+ return TCL_ERROR;
+ }
+
+ ckfree(winPath);
+ return TCL_OK;
+}
+#elif defined(HAVE_CHFLAGS) && defined(UF_IMMUTABLE)
/*
*----------------------------------------------------------------------
*
- * GetReadOnlyAttribute
+ * GetUnixFileAttributes
*
* Gets the readonly attribute (user immutable flag) of a file.
*
@@ -2266,7 +2421,7 @@ DefaultTempDir(void)
*/
static int
-GetReadOnlyAttribute(
+GetUnixFileAttributes(
Tcl_Interp *interp, /* The interp we are using for errors. */
int objIndex, /* The index of the attribute. */
Tcl_Obj *fileName, /* The name of the file (UTF-8). */
@@ -2294,7 +2449,7 @@ GetReadOnlyAttribute(
/*
*---------------------------------------------------------------------------
*
- * SetReadOnlyAttribute
+ * SetUnixFileAttributes
*
* Sets the readonly attribute (user immutable flag) of a file.
*
@@ -2308,7 +2463,7 @@ GetReadOnlyAttribute(
*/
static int
-SetReadOnlyAttribute(
+SetUnixFileAttributes(
Tcl_Interp *interp, /* The interp we are using for errors. */
int objIndex, /* The index of the attribute. */
Tcl_Obj *fileName, /* The name of the file (UTF-8). */
diff --git a/unix/tclUnixFile.c b/unix/tclUnixFile.c
index f1fedc3..2cb0027 100644
--- a/unix/tclUnixFile.c
+++ b/unix/tclUnixFile.c
@@ -10,7 +10,6 @@
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
-#include <sys/stat.h>
#include "tclInt.h"
#include "tclFileSystem.h"
@@ -1106,6 +1105,12 @@ TclNativeCreateNativeRep(
str = Tcl_GetStringFromObj(validPathPtr, &len);
Tcl_UtfToExternalDString(NULL, str, len, &ds);
len = Tcl_DStringLength(&ds) + sizeof(char);
+ if (strlen(Tcl_DStringValue(&ds)) < len - sizeof(char)) {
+ /* See bug [3118489]: NUL in filenames */
+ Tcl_DecrRefCount(validPathPtr);
+ Tcl_DStringFree(&ds);
+ return NULL;
+ }
Tcl_DecrRefCount(validPathPtr);
nativePathPtr = ckalloc(len);
memcpy(nativePathPtr, Tcl_DStringValue(&ds), (size_t) len);
@@ -1182,9 +1187,10 @@ TclpUtime(
int
TclOSstat(
const char *name,
- Tcl_StatBuf *statBuf)
+ void *cygstat)
{
struct stat buf;
+ Tcl_StatBuf *statBuf = cygstat;
int result = stat(name, &buf);
statBuf->st_mode = buf.st_mode;
@@ -1204,9 +1210,10 @@ TclOSstat(
int
TclOSlstat(
const char *name,
- Tcl_StatBuf *statBuf)
+ void *cygstat)
{
struct stat buf;
+ Tcl_StatBuf *statBuf = cygstat;
int result = lstat(name, &buf);
statBuf->st_mode = buf.st_mode;
diff --git a/unix/tclUnixInit.c b/unix/tclUnixInit.c
index 6653e4b..1617cba 100644
--- a/unix/tclUnixInit.c
+++ b/unix/tclUnixInit.c
@@ -8,7 +8,6 @@
* All rights reserved.
*/
-#include <sys/stat.h>
#include "tclInt.h"
#include <stddef.h>
#include <locale.h>
@@ -34,7 +33,10 @@
#endif
#ifdef __CYGWIN__
-DLLIMPORT extern __stdcall unsigned char GetVersionExA(void *);
+DLLIMPORT extern __stdcall unsigned char GetVersionExW(void *);
+DLLIMPORT extern __stdcall void *LoadLibraryW(const void *);
+DLLIMPORT extern __stdcall void FreeLibrary(void *);
+DLLIMPORT extern __stdcall void *GetProcAddress(void *, const char *);
DLLIMPORT extern __stdcall void GetSystemInfo(void *);
#define NUMPLATFORMS 4
@@ -67,14 +69,14 @@ typedef struct _SYSTEM_INFO {
int wProcessorRevision;
} SYSTEM_INFO;
-typedef struct _OSVERSIONINFOA {
+typedef struct _OSVERSIONINFOW {
DWORD dwOSVersionInfoSize;
DWORD dwMajorVersion;
DWORD dwMinorVersion;
DWORD dwBuildNumber;
DWORD dwPlatformId;
- char szCSDVersion[128];
-} OSVERSIONINFOA;
+ wchar_t szCSDVersion[128];
+} OSVERSIONINFOW;
#endif
#ifdef HAVE_COREFOUNDATION
@@ -748,7 +750,8 @@ TclpSetVariables(
{
#ifdef __CYGWIN__
SYSTEM_INFO sysInfo;
- OSVERSIONINFOA osInfo;
+ static OSVERSIONINFOW osInfo;
+ static int osInfoInitialized = 0;
char buffer[TCL_INTEGER_SPACE * 2];
#elif !defined(NO_UNAME)
struct utsname name;
@@ -861,8 +864,20 @@ TclpSetVariables(
unameOK = 0;
#ifdef __CYGWIN__
unameOK = 1;
- osInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
- GetVersionExA(&osInfo);
+ if (!osInfoInitialized) {
+ HANDLE handle = LoadLibraryW(L"NTDLL");
+ int(__stdcall *getversion)(void *) =
+ (int(__stdcall *)(void *))GetProcAddress(handle, "RtlGetVersion");
+ osInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW);
+ if (!getversion || getversion(&osInfo)) {
+ GetVersionExW(&osInfo);
+ }
+ if (handle) {
+ FreeLibrary(handle);
+ }
+ osInfoInitialized = 1;
+ }
+
GetSystemInfo(&sysInfo);
if (osInfo.dwPlatformId < NUMPLATFORMS) {
diff --git a/unix/tclUnixNotfy.c b/unix/tclUnixNotfy.c
index b87af1b..b234667 100644
--- a/unix/tclUnixNotfy.c
+++ b/unix/tclUnixNotfy.c
@@ -96,7 +96,7 @@ typedef struct ThreadSpecificData {
* that an event is ready to be processed
* by sending this event. */
void *hwnd; /* Messaging window. */
-#else
+#else /* !__CYGWIN__ */
Tcl_Condition waitCV; /* Any other thread alerts a notifier that an
* event is ready to be processed by signaling
* this condition variable. */
@@ -120,6 +120,15 @@ static Tcl_ThreadDataKey dataKey;
static int notifierCount = 0;
/*
+ * The following static stores the process ID of the initialized notifier
+ * thread. If it changes, we have passed a fork and we should start a new
+ * notifier thread.
+ *
+ * You must hold the notifierMutex lock before accessing this variable.
+ */
+static pid_t processIDInitialized = 0;
+
+/*
* The following variable points to the head of a doubly-linked list of
* ThreadSpecificData structures for all threads that are currently waiting on
* an event.
@@ -184,9 +193,15 @@ static Tcl_ThreadId notifierThread;
*/
#ifdef TCL_THREADS
-static void NotifierThreadProc(ClientData clientData);
-#endif
-static int FileHandlerEventProc(Tcl_Event *evPtr, int flags);
+static void NotifierThreadProc(ClientData clientData);
+#if defined(HAVE_PTHREAD_ATFORK) && !defined(__APPLE__) && !defined(__hpux)
+static int atForkInit = 0;
+static void AtForkPrepare(void);
+static void AtForkParent(void);
+static void AtForkChild(void);
+#endif /* HAVE_PTHREAD_ATFORK */
+#endif /* TCL_THREADS */
+static int FileHandlerEventProc(Tcl_Event *evPtr, int flags);
/*
* Import of Windows API when building threaded with Cygwin.
@@ -213,14 +228,14 @@ typedef struct {
void *hCursor;
void *hbrBackground;
void *lpszMenuName;
- void *lpszClassName;
+ const void *lpszClassName;
} WNDCLASS;
extern void __stdcall CloseHandle(void *);
extern void *__stdcall CreateEventW(void *, unsigned char, unsigned char,
void *);
-extern void * __stdcall CreateWindowExW(void *, void *, void *, DWORD, int,
- int, int, int, void *, void *, void *, void *);
+extern void * __stdcall CreateWindowExW(void *, const void *, const void *,
+ DWORD, int, int, int, int, void *, void *, void *, void *);
extern DWORD __stdcall DefWindowProcW(void *, int, void *, void *);
extern unsigned char __stdcall DestroyWindow(void *);
extern int __stdcall DispatchMessageW(const MSG *);
@@ -275,11 +290,38 @@ Tcl_InitNotifier(void)
*/
Tcl_MutexLock(&notifierMutex);
+#if defined(HAVE_PTHREAD_ATFORK) && !defined(__APPLE__) && !defined(__hpux)
+ /*
+ * Install pthread_atfork handlers to reinitialize the notifier in the
+ * child of a fork.
+ */
+
+ if (!atForkInit) {
+ int result = pthread_atfork(AtForkPrepare, AtForkParent, AtForkChild);
+
+ if (result) {
+ Tcl_Panic("Tcl_InitNotifier: pthread_atfork failed");
+ }
+ atForkInit = 1;
+ }
+#endif /* HAVE_PTHREAD_ATFORK */
+ /*
+ * Check if my process id changed, e.g. I was forked
+ * In this case, restart the notifier thread and close the
+ * pipe to the original notifier thread
+ */
+ if (notifierCount > 0 && processIDInitialized != getpid()) {
+ notifierCount = 0;
+ processIDInitialized = 0;
+ close(triggerPipe);
+ triggerPipe = -1;
+ }
if (notifierCount == 0) {
if (TclpThreadCreate(&notifierThread, NotifierThreadProc, NULL,
TCL_THREAD_STACK_DEFAULT, TCL_THREAD_JOINABLE) != TCL_OK) {
Tcl_Panic("Tcl_InitNotifier: unable to start notifier thread");
}
+ processIDInitialized = getpid();
}
notifierCount++;
@@ -1270,6 +1312,75 @@ NotifierThreadProc(
TclpThreadExit(0);
}
+
+#if defined(HAVE_PTHREAD_ATFORK) && !defined(__APPLE__) && !defined(__hpux)
+/*
+ *----------------------------------------------------------------------
+ *
+ * AtForkPrepare --
+ *
+ * Lock the notifier in preparation for a fork.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+AtForkPrepare(void)
+{
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * AtForkParent --
+ *
+ * Unlock the notifier in the parent after a fork.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+AtForkParent(void)
+{
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * AtForkChild --
+ *
+ * Unlock and reinstall the notifier in the child after a fork.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+AtForkChild(void)
+{
+ notifierMutex = NULL;
+ notifierCV = NULL;
+ Tcl_InitNotifier();
+}
+#endif /* HAVE_PTHREAD_ATFORK */
+
#endif /* TCL_THREADS */
#endif /* !HAVE_COREFOUNDATION */
diff --git a/unix/tclUnixPipe.c b/unix/tclUnixPipe.c
index 9c21b28..95bc8d1 100644
--- a/unix/tclUnixPipe.c
+++ b/unix/tclUnixPipe.c
@@ -229,7 +229,7 @@ TclpCreateTempFile(
Tcl_Obj *
TclpTempFileName(void)
{
- Tcl_Obj *nameObj = Tcl_NewObj();
+ Tcl_Obj *retVal, *nameObj = Tcl_NewObj();
int fd;
Tcl_IncrRefCount(nameObj);
@@ -242,7 +242,9 @@ TclpTempFileName(void)
fcntl(fd, F_SETFD, FD_CLOEXEC);
TclpObjDeleteFile(nameObj);
close(fd);
- return nameObj;
+ retVal = Tcl_DuplicateObj(nameObj);
+ Tcl_DecrRefCount(nameObj);
+ return retVal;
}
/*
@@ -1143,7 +1145,7 @@ PipeWatchProc(
if (psPtr->inFile) {
newmask = mask & (TCL_READABLE | TCL_EXCEPTION);
if (newmask) {
- Tcl_CreateFileHandler(GetFd(psPtr->inFile), mask,
+ Tcl_CreateFileHandler(GetFd(psPtr->inFile), newmask,
(Tcl_FileProc *) Tcl_NotifyChannel, psPtr->channel);
} else {
Tcl_DeleteFileHandler(GetFd(psPtr->inFile));
@@ -1152,7 +1154,7 @@ PipeWatchProc(
if (psPtr->outFile) {
newmask = mask & (TCL_WRITABLE | TCL_EXCEPTION);
if (newmask) {
- Tcl_CreateFileHandler(GetFd(psPtr->outFile), mask,
+ Tcl_CreateFileHandler(GetFd(psPtr->outFile), newmask,
(Tcl_FileProc *) Tcl_NotifyChannel, psPtr->channel);
} else {
Tcl_DeleteFileHandler(GetFd(psPtr->outFile));
diff --git a/unix/tclUnixPort.h b/unix/tclUnixPort.h
index aa59258..f64d453 100644
--- a/unix/tclUnixPort.h
+++ b/unix/tclUnixPort.h
@@ -21,10 +21,6 @@
#ifndef _TCLUNIXPORT
#define _TCLUNIXPORT
-
-#ifndef MODULE_SCOPE
-#define MODULE_SCOPE extern
-#endif
/*
*---------------------------------------------------------------------------
@@ -89,26 +85,31 @@ typedef off_t Tcl_SeekOffset;
# define SOCKET unsigned int
# define WSAEWOULDBLOCK 10035
typedef unsigned short WCHAR;
- DLLIMPORT extern __stdcall int GetModuleHandleExW(unsigned int, const char *, void *);
- DLLIMPORT extern __stdcall int GetModuleFileNameW(void *, const char *, int);
- DLLIMPORT extern __stdcall int WideCharToMultiByte(int, int, const char *, int,
+ __declspec(dllimport) extern __stdcall int GetModuleHandleExW(unsigned int, const char *, void *);
+ __declspec(dllimport) extern __stdcall int GetModuleFileNameW(void *, const char *, int);
+ __declspec(dllimport) extern __stdcall int WideCharToMultiByte(int, int, const char *, int,
const char *, int, const char *, const char *);
- DLLIMPORT extern __stdcall int MultiByteToWideChar(int, int, const char *, int,
+ __declspec(dllimport) extern __stdcall int MultiByteToWideChar(int, int, const char *, int,
WCHAR *, int);
- DLLIMPORT extern __stdcall void OutputDebugStringW(const WCHAR *);
- DLLIMPORT extern __stdcall int IsDebuggerPresent();
-
- DLLIMPORT extern int cygwin_conv_path(int, const void *, void *, int);
- DLLIMPORT extern int cygwin_conv_path_list(int, const void *, void *, int);
+ __declspec(dllimport) extern __stdcall void OutputDebugStringW(const WCHAR *);
+ __declspec(dllimport) extern __stdcall int IsDebuggerPresent();
+ __declspec(dllimport) extern __stdcall int GetLastError();
+ __declspec(dllimport) extern __stdcall int GetFileAttributesW(const WCHAR *);
+ __declspec(dllimport) extern __stdcall int SetFileAttributesW(const WCHAR *, int);
+
+ __declspec(dllimport) extern int cygwin_conv_path(int, const void *, void *, int);
+ __declspec(dllimport) extern int cygwin_conv_path_list(int, const void *, void *, int);
# define USE_PUTENV 1
# define USE_PUTENV_FOR_UNSET 1
/* On Cygwin, the environment is imported from the Cygwin DLL. */
+#ifndef __x86_64__
# define environ __cygwin_environ
+ extern char **__cygwin_environ;
+#endif
# define timezone _timezone
- DLLIMPORT extern char **__cygwin_environ;
- MODULE_SCOPE int TclOSstat(const char *name, Tcl_StatBuf *statBuf);
- MODULE_SCOPE int TclOSlstat(const char *name, Tcl_StatBuf *statBuf);
-#elif defined(HAVE_STRUCT_STAT64)
+ extern int TclOSstat(const char *name, void *statBuf);
+ extern int TclOSlstat(const char *name, void *statBuf);
+#elif defined(HAVE_STRUCT_STAT64) && !defined(__APPLE__)
# define TclOSstat stat64
# define TclOSlstat lstat64
#else
@@ -157,7 +158,7 @@ typedef off_t Tcl_SeekOffset;
# include "../compat/unistd.h"
#endif
-MODULE_SCOPE int TclUnixSetBlockingMode(int fd, int mode);
+extern int TclUnixSetBlockingMode(int fd, int mode);
#include <utime.h>
@@ -582,19 +583,6 @@ extern char ** environ;
/*
*---------------------------------------------------------------------------
- * The termios configure test program relies on the configure script being run
- * from a terminal, which is not the case e.g., when configuring from Xcode.
- * Since termios is known to be present on all Mac OS X releases since 10.0,
- * override the configure defines for serial API here. [Bug 497147]
- *---------------------------------------------------------------------------
- */
-
-# define USE_TERMIOS 1
-# undef USE_TERMIO
-# undef USE_SGTTY
-
-/*
- *---------------------------------------------------------------------------
* Include AvailabilityMacros.h here (when available) to ensure any symbolic
* MAC_OS_X_VERSION_* constants passed on the command line are translated.
*---------------------------------------------------------------------------
@@ -715,8 +703,6 @@ typedef int socklen_t;
#ifdef TCL_THREADS
# include <pthread.h>
-# undef inet_ntoa
-# define inet_ntoa(x) TclpInetNtoa(x)
#endif /* TCL_THREADS */
/* FIXME - Hyper-enormous platform assumption! */
@@ -735,14 +721,14 @@ typedef int socklen_t;
#include <pwd.h>
#include <grp.h>
-MODULE_SCOPE struct passwd * TclpGetPwNam(const char *name);
-MODULE_SCOPE struct group * TclpGetGrNam(const char *name);
-MODULE_SCOPE struct passwd * TclpGetPwUid(uid_t uid);
-MODULE_SCOPE struct group * TclpGetGrGid(gid_t gid);
-MODULE_SCOPE struct hostent * TclpGetHostByName(const char *name);
-MODULE_SCOPE struct hostent * TclpGetHostByAddr(const char *addr,
+extern struct passwd * TclpGetPwNam(const char *name);
+extern struct group * TclpGetGrNam(const char *name);
+extern struct passwd * TclpGetPwUid(uid_t uid);
+extern struct group * TclpGetGrGid(gid_t gid);
+extern struct hostent * TclpGetHostByName(const char *name);
+extern struct hostent * TclpGetHostByAddr(const char *addr,
int length, int type);
-MODULE_SCOPE void *TclpMakeTcpClientChannelMode(
+extern void *TclpMakeTcpClientChannelMode(
void *tcpSocket, int mode);
#endif /* _TCLUNIXPORT */
diff --git a/unix/tclUnixSock.c b/unix/tclUnixSock.c
index 528f009..96700ce 100644
--- a/unix/tclUnixSock.c
+++ b/unix/tclUnixSock.c
@@ -55,6 +55,8 @@ struct TcpState {
TcpFdList fds; /* The file descriptors of the sockets. */
int flags; /* ORed combination of the bitfields defined
* below. */
+ int interest; /* Event types of interest */
+
/*
* Only needed for server sockets
*/
@@ -73,7 +75,7 @@ struct TcpState {
struct addrinfo *myaddr; /* Iterator over myaddrlist. */
int filehandlers; /* Caches FileHandlers that get set up while
* an async socket is not yet connected. */
- int status; /* Cache status of async socket. */
+ int connectError; /* Cache SO_ERROR of async socket. */
int cachedBlocking; /* Cache blocking mode of async socket. */
};
@@ -82,8 +84,13 @@ struct TcpState {
* structure.
*/
-#define TCP_ASYNC_SOCKET (1<<0) /* Asynchronous socket. */
+#define TCP_NONBLOCKING (1<<0) /* Socket with non-blocking I/O */
#define TCP_ASYNC_CONNECT (1<<1) /* Async connect in progress. */
+#define TCP_ASYNC_PENDING (1<<4) /* TcpConnect was called to
+ * process an async connect. This
+ * flag indicates that reentry is
+ * still pending */
+#define TCP_ASYNC_FAILED (1<<5) /* An async connect finally failed */
/*
* The following defines the maximum length of the listen queue. This is the
@@ -110,7 +117,7 @@ struct TcpState {
* Static routines for this file:
*/
-static int CreateClientSocket(Tcl_Interp *interp,
+static int TcpConnect(Tcl_Interp *interp,
TcpState *state);
static void TcpAccept(ClientData data, int mask);
static int TcpBlockModeProc(ClientData data, int mode);
@@ -129,6 +136,7 @@ static int TcpOutputProc(ClientData instanceData,
const char *buf, int toWrite, int *errorCode);
static void TcpWatchProc(ClientData instanceData, int mask);
static int WaitForConnect(TcpState *statePtr, int *errorCodePtr);
+static void WrapNotify(ClientData clientData, int mask);
/*
* This structure describes the channel type structure for TCP socket
@@ -163,6 +171,21 @@ static TclInitProcessGlobalValueProc InitializeHostName;
static ProcessGlobalValue hostName =
{0, 0, NULL, NULL, InitializeHostName, NULL, NULL};
+#if 0
+/* printf debugging */
+void printaddrinfo(struct addrinfo *addrlist, char *prefix)
+{
+ char host[NI_MAXHOST], port[NI_MAXSERV];
+ struct addrinfo *ai;
+ for (ai = addrlist; ai != NULL; ai = ai->ai_next) {
+ getnameinfo(ai->ai_addr, ai->ai_addrlen,
+ host, sizeof(host),
+ port, sizeof(port),
+ NI_NUMERICHOST|NI_NUMERICSERV);
+ fprintf(stderr,"%s: %s:%s\n", prefix, host, port);
+ }
+}
+#endif
/*
*----------------------------------------------------------------------
*
@@ -349,9 +372,9 @@ TcpBlockModeProc(
TcpState *statePtr = instanceData;
if (mode == TCL_MODE_BLOCKING) {
- CLEAR_BITS(statePtr->flags, TCP_ASYNC_SOCKET);
+ CLEAR_BITS(statePtr->flags, TCP_NONBLOCKING);
} else {
- SET_BITS(statePtr->flags, TCP_ASYNC_SOCKET);
+ SET_BITS(statePtr->flags, TCP_NONBLOCKING);
}
if (statePtr->flags & TCP_ASYNC_CONNECT) {
statePtr->cachedBlocking = mode;
@@ -368,48 +391,80 @@ TcpBlockModeProc(
*
* WaitForConnect --
*
- * Wait for a connection on an asynchronously opened socket to be
- * completed. In nonblocking mode, just test if the connection
- * has completed without blocking.
+ * Check the state of an async connect process. If a connection
+ * attempt terminated, process it, which may finalize it or may
+ * start the next attempt. If a connect error occures, it is saved
+ * in statePtr->connectError to be reported by 'fconfigure -error'.
+ *
+ * There are two modes of operation, defined by errorCodePtr:
+ * * non-NULL: Called by explicite read/write command. block if
+ * socket is blocking.
+ * May return two error codes:
+ * * EWOULDBLOCK: if connect is still in progress
+ * * ENOTCONN: if connect failed. This would be the error
+ * message of a rect or sendto syscall so this is
+ * emulated here.
+ * * NULL: Called by a backround operation. Do not block and
+ * don't return any error code.
*
* Results:
* 0 if the connection has completed, -1 if still in progress
* or there is an error.
*
+ * Side effects:
+ * Processes socket events off the system queue.
+ * May process asynchroneous connect.
+ *
*----------------------------------------------------------------------
*/
static int
WaitForConnect(
TcpState *statePtr, /* State of the socket. */
- int *errorCodePtr) /* Where to store errors? */
+ int *errorCodePtr)
{
- int timeOut; /* How long to wait. */
- int state; /* Of calling TclWaitForFile. */
+ int timeout;
/*
- * If an asynchronous connect is in progress, attempt to wait for it to
- * complete before reading.
+ * Check if an async connect failed already and error reporting is demanded,
+ * return the error ENOTCONN
*/
- if (statePtr->flags & TCP_ASYNC_CONNECT) {
- if (statePtr->flags & TCP_ASYNC_SOCKET) {
- timeOut = 0;
- } else {
- timeOut = -1;
- }
- errno = 0;
- state = TclUnixWaitForFile(statePtr->fds.fd,
- TCL_WRITABLE | TCL_EXCEPTION, timeOut);
- if (state & TCL_EXCEPTION) {
- return -1;
- }
- if (state & TCL_WRITABLE) {
- CLEAR_BITS(statePtr->flags, TCP_ASYNC_CONNECT);
- } else if (timeOut == 0) {
- *errorCodePtr = errno = EWOULDBLOCK;
- return -1;
- }
+ if (errorCodePtr != NULL && (statePtr->flags & TCP_ASYNC_FAILED)) {
+ *errorCodePtr = ENOTCONN;
+ return -1;
+ }
+
+ /*
+ * Check if an async connect is running. If not return ok
+ */
+
+ if (!(statePtr->flags & TCP_ASYNC_PENDING)) {
+ return 0;
+ }
+
+ if (errorCodePtr == NULL || (statePtr->flags & TCP_NONBLOCKING)) {
+ timeout = 0;
+ } else {
+ timeout = -1;
+ }
+ do {
+ if (TclUnixWaitForFile(statePtr->fds.fd,
+ TCL_WRITABLE | TCL_EXCEPTION, timeout) != 0) {
+ TcpConnect(NULL, statePtr);
+ }
+ /* Do this only once in the nonblocking case and repeat it until the
+ * socket is final when blocking */
+ } while (timeout == -1 && statePtr->flags & TCP_ASYNC_CONNECT);
+
+ if (errorCodePtr != NULL) {
+ if (statePtr->flags & TCP_ASYNC_PENDING) {
+ *errorCodePtr = EAGAIN;
+ return -1;
+ } else if (statePtr->connectError != 0) {
+ *errorCodePtr = ENOTCONN;
+ return -1;
+ }
}
return 0;
}
@@ -503,6 +558,7 @@ TcpOutputProc(
return -1;
}
written = send(statePtr->fds.fd, buf, (size_t) toWrite, 0);
+
if (written > -1) {
return written;
}
@@ -726,6 +782,8 @@ TcpGetOptionProc(
TcpState *statePtr = instanceData;
size_t len = 0;
+ WaitForConnect(statePtr, NULL);
+
if (optionName != NULL) {
len = strlen(optionName);
}
@@ -733,24 +791,33 @@ TcpGetOptionProc(
if ((len > 1) && (optionName[1] == 'e') &&
(strncmp(optionName, "-error", len) == 0)) {
socklen_t optlen = sizeof(int);
- int err, ret;
- if (statePtr->status == 0) {
- ret = getsockopt(statePtr->fds.fd, SOL_SOCKET, SO_ERROR,
- (char *) &err, &optlen);
- if (ret < 0) {
- err = errno;
- }
+ if (statePtr->flags & TCP_ASYNC_CONNECT) {
+ /* Suppress errors as long as we are not done */
+ errno = 0;
+ } else if (statePtr->connectError != 0) {
+ errno = statePtr->connectError;
+ statePtr->connectError = 0;
} else {
- err = statePtr->status;
- statePtr->status = 0;
+ int err;
+ getsockopt(statePtr->fds.fd, SOL_SOCKET, SO_ERROR,
+ (char *) &err, &optlen);
+ errno = err;
+ }
+ if (errno != 0) {
+ Tcl_DStringAppend(dsPtr, Tcl_ErrnoMsg(errno), -1);
}
- if (err != 0) {
- Tcl_DStringAppend(dsPtr, Tcl_ErrnoMsg(err), -1);
- }
return TCL_OK;
}
+ if ((len > 1) && (optionName[1] == 'c') &&
+ (strncmp(optionName, "-connecting", len) == 0)) {
+
+ Tcl_DStringAppend(dsPtr,
+ (statePtr->flags & TCP_ASYNC_CONNECT) ? "1" : "0", -1);
+ return TCL_OK;
+ }
+
if ((len == 0) || ((len > 1) && (optionName[1] == 'p') &&
(strncmp(optionName, "-peername", len) == 0))) {
address peername;
@@ -842,6 +909,35 @@ TcpGetOptionProc(
*/
static void
+WrapNotify(
+ ClientData clientData,
+ int mask)
+{
+ TcpState *statePtr = (TcpState *) clientData;
+ int newmask = mask & statePtr->interest;
+
+ if (newmask == 0) {
+ /*
+ * There was no overlap between the states the channel is
+ * interested in notifications for, and the states that are
+ * reported present on the file descriptor by select(). The
+ * only way that can happen is when the channel is interested
+ * in a writable condition, and only a readable state is reported
+ * present (see TcpWatchProc() below). In that case, signal back
+ * to the caller the writable state, which is really an error
+ * condition. As an extra check on that assumption, check for
+ * a non-zero value of errno before reporting an artificial
+ * writable state.
+ */
+ if (errno == 0) {
+ return;
+ }
+ newmask = TCL_WRITABLE;
+ }
+ Tcl_NotifyChannel(statePtr->channel, newmask);
+}
+
+static void
TcpWatchProc(
ClientData instanceData, /* The socket state. */
int mask) /* Events of interest; an OR-ed combination of
@@ -859,13 +955,35 @@ TcpWatchProc(
return;
}
- if (statePtr->flags & TCP_ASYNC_CONNECT) {
+ if (statePtr->flags & TCP_ASYNC_PENDING) {
/* Async sockets use a FileHandler internally while connecting, so we
* need to cache this request until the connection has succeeded. */
statePtr->filehandlers = mask;
} else if (mask) {
- Tcl_CreateFileHandler(statePtr->fds.fd, mask,
- (Tcl_FileProc *) Tcl_NotifyChannel, statePtr->channel);
+
+ /*
+ * Whether it is a bug or feature or otherwise, it is a fact
+ * of life that on at least some Linux kernels select() fails
+ * to report that a socket file descriptor is writable when
+ * the other end of the socket is closed. This is in contrast
+ * to the guarantees Tcl makes that its channels become
+ * writable and fire writable events on an error conditon.
+ * This has caused a leak of file descriptors in a state of
+ * background flushing. See Tcl ticket 1758a0b603.
+ *
+ * As a workaround, when our caller indicates an interest in
+ * writable notifications, we must tell the notifier built
+ * around select() that we are interested in the readable state
+ * of the file descriptor as well, as that is the only reliable
+ * means to get notified of error conditions. Then it is the
+ * task of WrapNotify() above to untangle the meaning of these
+ * channel states and report the chan events as best it can.
+ * We save a copy of the mask passed in to assist with that.
+ */
+
+ statePtr->interest = mask;
+ Tcl_CreateFileHandler(statePtr->fds.fd, mask|TCL_READABLE,
+ (Tcl_FileProc *) WrapNotify, statePtr);
} else {
Tcl_DeleteFileHandler(statePtr->fds.fd);
}
@@ -907,7 +1025,7 @@ TcpGetHandleProc(
*
* TcpAsyncCallback --
*
- * Called by the event handler that CreateClientSocket sets up
+ * Called by the event handler that TcpConnect sets up
* internally for [socket -async] to get notified when the
* asyncronous connection attempt has succeeded or failed.
*
@@ -920,13 +1038,13 @@ TcpAsyncCallback(
* TCL_READABLE, TCL_WRITABLE and
* TCL_EXCEPTION. */
{
- CreateClientSocket(NULL, clientData);
+ TcpConnect(NULL, clientData);
}
/*
*----------------------------------------------------------------------
*
- * CreateClientSocket --
+ * TcpConnect --
*
* This function opens a new socket in client mode.
*
@@ -954,33 +1072,32 @@ TcpAsyncCallback(
*/
static int
-CreateClientSocket(
+TcpConnect(
Tcl_Interp *interp, /* For error reporting; can be NULL. */
- TcpState *state)
+ TcpState *statePtr)
{
socklen_t optlen;
- int async_callback = (state->addr != NULL);
- int status;
- int async = state->flags & TCP_ASYNC_CONNECT;
+ int async_callback = statePtr->flags & TCP_ASYNC_PENDING;
+ int ret = -1, error = errno;
+ int async = statePtr->flags & TCP_ASYNC_CONNECT;
if (async_callback) {
goto reenter;
}
- for (state->addr = state->addrlist; state->addr != NULL;
- state->addr = state->addr->ai_next) {
- status = -1;
+ for (statePtr->addr = statePtr->addrlist; statePtr->addr != NULL;
+ statePtr->addr = statePtr->addr->ai_next) {
- for (state->myaddr = state->myaddrlist; state->myaddr != NULL;
- state->myaddr = state->myaddr->ai_next) {
- int reuseaddr;
+ for (statePtr->myaddr = statePtr->myaddrlist; statePtr->myaddr != NULL;
+ statePtr->myaddr = statePtr->myaddr->ai_next) {
+ int reuseaddr = 1;
/*
* No need to try combinations of local and remote addresses of
* different families.
*/
- if (state->myaddr->ai_family != state->addr->ai_family) {
+ if (statePtr->myaddr->ai_family != statePtr->addr->ai_family) {
continue;
}
@@ -989,13 +1106,14 @@ CreateClientSocket(
* iteration.
*/
- if (state->fds.fd >= 0) {
- close(state->fds.fd);
- state->fds.fd = -1;
+ if (statePtr->fds.fd >= 0) {
+ close(statePtr->fds.fd);
+ statePtr->fds.fd = -1;
+ errno = 0;
}
- state->fds.fd = socket(state->addr->ai_family, SOCK_STREAM, 0);
- if (state->fds.fd < 0) {
+ statePtr->fds.fd = socket(statePtr->addr->ai_family, SOCK_STREAM, 0);
+ if (statePtr->fds.fd < 0) {
continue;
}
@@ -1004,28 +1122,31 @@ CreateClientSocket(
* inherited by child processes.
*/
- fcntl(state->fds.fd, F_SETFD, FD_CLOEXEC);
+ fcntl(statePtr->fds.fd, F_SETFD, FD_CLOEXEC);
/*
* Set kernel space buffering
*/
- TclSockMinimumBuffers(INT2PTR(state->fds.fd), SOCKET_BUFSIZE);
+ TclSockMinimumBuffers(INT2PTR(statePtr->fds.fd), SOCKET_BUFSIZE);
if (async) {
- status = TclUnixSetBlockingMode(state->fds.fd,
- TCL_MODE_NONBLOCKING);
- if (status < 0) {
+ ret = TclUnixSetBlockingMode(statePtr->fds.fd,TCL_MODE_NONBLOCKING);
+ if (ret < 0) {
continue;
- }
- }
+ }
+ }
- reuseaddr = 1;
- (void) setsockopt(state->fds.fd, SOL_SOCKET, SO_REUSEADDR,
+ /* Gotta reset the error variable here, before we use it for the
+ * first time in this iteration. */
+ error = 0;
+
+ (void) setsockopt(statePtr->fds.fd, SOL_SOCKET, SO_REUSEADDR,
(char *) &reuseaddr, sizeof(reuseaddr));
- status = bind(state->fds.fd, state->myaddr->ai_addr,
- state->myaddr->ai_addrlen);
- if (status < 0) {
+ ret = bind(statePtr->fds.fd, statePtr->myaddr->ai_addr,
+ statePtr->myaddr->ai_addrlen);
+ if (ret < 0) {
+ error = errno;
continue;
}
@@ -1036,15 +1157,19 @@ CreateClientSocket(
* in being informed when the connect completes.
*/
- status = connect(state->fds.fd, state->addr->ai_addr,
- state->addr->ai_addrlen);
- if (status < 0 && errno == EINPROGRESS) {
- Tcl_CreateFileHandler(state->fds.fd,
- TCL_WRITABLE|TCL_EXCEPTION, TcpAsyncCallback, state);
+ ret = connect(statePtr->fds.fd, statePtr->addr->ai_addr,
+ statePtr->addr->ai_addrlen);
+ if (ret < 0) error = errno;
+ if (ret < 0 && errno == EINPROGRESS) {
+ Tcl_CreateFileHandler(statePtr->fds.fd,
+ TCL_WRITABLE|TCL_EXCEPTION, TcpAsyncCallback, statePtr);
+ errno = EWOULDBLOCK;
+ SET_BITS(statePtr->flags, TCP_ASYNC_PENDING);
return TCL_OK;
reenter:
- Tcl_DeleteFileHandler(state->fds.fd);
+ CLEAR_BITS(statePtr->flags, TCP_ASYNC_PENDING);
+ Tcl_DeleteFileHandler(statePtr->fds.fd);
/*
* Read the error state from the socket to see if the async
@@ -1054,26 +1179,31 @@ CreateClientSocket(
*/
optlen = sizeof(int);
- getsockopt(state->fds.fd, SOL_SOCKET, SO_ERROR,
- (char *) &status, &optlen);
- state->status = status;
+
+ getsockopt(statePtr->fds.fd, SOL_SOCKET, SO_ERROR,
+ (char *) &error, &optlen);
+ errno = error;
}
- if (status == 0) {
- CLEAR_BITS(state->flags, TCP_ASYNC_CONNECT);
+ if (error == 0) {
goto out;
}
}
}
out:
-
+ statePtr->connectError = error;
+ CLEAR_BITS(statePtr->flags, TCP_ASYNC_CONNECT);
if (async_callback) {
/*
* An asynchonous connection has finally succeeded or failed.
*/
- TcpWatchProc(state, state->filehandlers);
- TclUnixSetBlockingMode(state->fds.fd, state->cachedBlocking);
+ TcpWatchProc(statePtr, statePtr->filehandlers);
+ TclUnixSetBlockingMode(statePtr->fds.fd, statePtr->cachedBlocking);
+
+ if (error != 0) {
+ SET_BITS(statePtr->flags, TCP_ASYNC_FAILED);
+ }
/*
* We need to forward the writable event that brought us here, bcasue
@@ -1084,8 +1214,11 @@ out:
* the event mechanism one roundtrip through select().
*/
- Tcl_NotifyChannel(state->channel, TCL_WRITABLE);
- } else if (status != 0) {
+ if (statePtr->cachedBlocking == TCL_MODE_NONBLOCKING) {
+ Tcl_NotifyChannel(statePtr->channel, TCL_WRITABLE);
+ }
+ }
+ if (error != 0) {
/*
* Failure for either a synchronous connection, or an async one that
* failed before it could enter background mode, e.g. because an
@@ -1093,6 +1226,7 @@ out:
*/
if (interp != NULL) {
+ errno = error;
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"couldn't open socket: %s", Tcl_PosixError(interp)));
}
@@ -1129,7 +1263,7 @@ Tcl_OpenTcpClient(
* connect. Otherwise we do a blocking
* connect. */
{
- TcpState *state;
+ TcpState *statePtr;
const char *errorMsg = NULL;
struct addrinfo *addrlist = NULL, *myaddrlist = NULL;
char channelName[SOCK_CHAN_LENGTH];
@@ -1154,32 +1288,32 @@ Tcl_OpenTcpClient(
/*
* Allocate a new TcpState for this socket.
*/
- state = ckalloc(sizeof(TcpState));
- memset(state, 0, sizeof(TcpState));
- state->flags = async ? TCP_ASYNC_CONNECT : 0;
- state->cachedBlocking = TCL_MODE_BLOCKING;
- state->addrlist = addrlist;
- state->myaddrlist = myaddrlist;
- state->fds.fd = -1;
+ statePtr = ckalloc(sizeof(TcpState));
+ memset(statePtr, 0, sizeof(TcpState));
+ statePtr->flags = async ? TCP_ASYNC_CONNECT : 0;
+ statePtr->cachedBlocking = TCL_MODE_BLOCKING;
+ statePtr->addrlist = addrlist;
+ statePtr->myaddrlist = myaddrlist;
+ statePtr->fds.fd = -1;
/*
* Create a new client socket and wrap it in a channel.
*/
- if (CreateClientSocket(interp, state) != TCL_OK) {
- TcpCloseProc(state, NULL);
+ if (TcpConnect(interp, statePtr) != TCL_OK) {
+ TcpCloseProc(statePtr, NULL);
return NULL;
}
- sprintf(channelName, SOCK_TEMPLATE, (long) state);
+ sprintf(channelName, SOCK_TEMPLATE, (long) statePtr);
- state->channel = Tcl_CreateChannel(&tcpChannelType, channelName, state,
+ statePtr->channel = Tcl_CreateChannel(&tcpChannelType, channelName, statePtr,
(TCL_READABLE | TCL_WRITABLE));
- if (Tcl_SetChannelOption(interp, state->channel, "-translation",
+ if (Tcl_SetChannelOption(interp, statePtr->channel, "-translation",
"auto crlf") == TCL_ERROR) {
- Tcl_Close(NULL, state->channel);
+ Tcl_Close(NULL, statePtr->channel);
return NULL;
}
- return state->channel;
+ return statePtr->channel;
}
/*
@@ -1357,6 +1491,7 @@ Tcl_OpenTcpServer(
my_errno = errno;
}
close(sock);
+ sock = -1;
continue;
}
if (port == 0 && chosenport == 0) {
@@ -1379,6 +1514,7 @@ Tcl_OpenTcpServer(
my_errno = errno;
}
close(sock);
+ sock = -1;
continue;
}
if (statePtr == NULL) {
diff --git a/unix/tclUnixTest.c b/unix/tclUnixTest.c
index 46fc972..4b0f369 100644
--- a/unix/tclUnixTest.c
+++ b/unix/tclUnixTest.c
@@ -67,6 +67,7 @@ static Tcl_CmdProc TestchmodCmd;
static Tcl_CmdProc TestfilehandlerCmd;
static Tcl_CmdProc TestfilewaitCmd;
static Tcl_CmdProc TestfindexecutableCmd;
+static Tcl_ObjCmdProc TestforkObjCmd;
static Tcl_CmdProc TestgetdefencdirCmd;
static Tcl_CmdProc TestgetopenfileCmd;
static Tcl_CmdProc TestgotsigCmd;
@@ -103,6 +104,8 @@ TclplatformtestInit(
NULL, NULL);
Tcl_CreateCommand(interp, "testfindexecutable", TestfindexecutableCmd,
NULL, NULL);
+ Tcl_CreateObjCommand(interp, "testfork", TestforkObjCmd,
+ NULL, NULL);
Tcl_CreateCommand(interp, "testgetopenfile", TestgetopenfileCmd,
NULL, NULL);
Tcl_CreateCommand(interp, "testgetdefenc", TestgetdefencdirCmd,
@@ -200,7 +203,7 @@ TestfilehandlerCmd(
return TCL_ERROR;
}
sprintf(buf, "%d %d", pipePtr->readCount, pipePtr->writeCount);
- Tcl_SetResult(interp, buf, TCL_VOLATILE);
+ Tcl_AppendResult(interp, buf, NULL);
} else if (strcmp(argv[1], "create") == 0) {
if (argc != 5) {
Tcl_AppendResult(interp, "wrong # arguments: should be \"",
@@ -217,8 +220,8 @@ TestfilehandlerCmd(
fcntl(GetFd(pipePtr->readFile), F_SETFL, O_NONBLOCK);
fcntl(GetFd(pipePtr->writeFile), F_SETFL, O_NONBLOCK);
#else
- Tcl_SetResult(interp, "can't make pipes non-blocking",
- TCL_STATIC);
+ Tcl_AppendResult(interp, "can't make pipes non-blocking",
+ NULL);
return TCL_ERROR;
#endif
}
@@ -281,7 +284,7 @@ TestfilehandlerCmd(
memset(buffer, 'b', 10);
TclFormatInt(buf, write(GetFd(pipePtr->writeFile), buffer, 10));
- Tcl_SetResult(interp, buf, TCL_VOLATILE);
+ Tcl_AppendResult(interp, buf, NULL);
} else if (strcmp(argv[1], "oneevent") == 0) {
Tcl_DoOneEvent(TCL_FILE_EVENTS|TCL_DONT_WAIT);
} else if (strcmp(argv[1], "wait") == 0) {
@@ -390,7 +393,7 @@ TestfilewaitCmd(
if (Tcl_GetChannelHandle(channel,
(mask & TCL_READABLE) ? TCL_READABLE : TCL_WRITABLE,
(ClientData*) &data) != TCL_OK) {
- Tcl_SetResult(interp, "couldn't get channel file", TCL_STATIC);
+ Tcl_AppendResult(interp, "couldn't get channel file", NULL);
return TCL_ERROR;
}
fd = PTR2INT(data);
@@ -526,6 +529,51 @@ TestsetdefencdirCmd(
Tcl_SetDefaultEncodingDir(argv[1]);
return TCL_OK;
}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestforkObjCmd --
+ *
+ * This function implements the "testfork" command. It is used to
+ * fork the Tcl process for specific test cases.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TestforkObjCmd(
+ ClientData clientData, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const *objv) /* Argument strings. */
+{
+ pid_t pid;
+
+ if (objc != 1) {
+ Tcl_WrongNumArgs(interp, 1, objv, "");
+ return TCL_ERROR;
+ }
+ pid = fork();
+ if (pid == -1) {
+ Tcl_AppendResult(interp,
+ "Cannot fork", NULL);
+ return TCL_ERROR;
+ }
+ /* Only needed when pthread_atfork is not present,
+ * should not hurt otherwise. */
+ if (pid==0) {
+ Tcl_InitNotifier();
+ }
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(pid));
+ return TCL_OK;
+}
/*
*----------------------------------------------------------------------
diff --git a/unix/tclUnixThrd.c b/unix/tclUnixThrd.c
index 789dbb6..d34bc88 100644
--- a/unix/tclUnixThrd.c
+++ b/unix/tclUnixThrd.c
@@ -659,6 +659,7 @@ TclpReaddir(
return TclOSreaddir(dir);
}
+#undef TclpInetNtoa
char *
TclpInetNtoa(
struct in_addr addr)
@@ -726,6 +727,7 @@ TclpFreeAllocCache(
*/
TclFreeAllocCache(ptr);
+ pthread_setspecific(key, NULL);
} else if (initialized) {
/*
diff --git a/unix/tclUnixTime.c b/unix/tclUnixTime.c
index c7921fe..926e8f4 100644
--- a/unix/tclUnixTime.c
+++ b/unix/tclUnixTime.c
@@ -503,7 +503,7 @@ SetTZIfNecessary(void)
if (lastTZ == NULL) {
Tcl_CreateExitHandler(CleanupMemory, NULL);
} else {
- Tcl_Free(lastTZ);
+ ckfree(lastTZ);
}
lastTZ = ckalloc(strlen(newTZ) + 1);
strcpy(lastTZ, newTZ);
diff --git a/unix/tclXtNotify.c b/unix/tclXtNotify.c
index e289e8c..a5d92d6 100644
--- a/unix/tclXtNotify.c
+++ b/unix/tclXtNotify.c
@@ -77,10 +77,10 @@ static int initialized = 0;
*/
static int FileHandlerEventProc(Tcl_Event *evPtr, int flags);
-static void FileProc(ClientData clientData, int *source,
+static void FileProc(XtPointer clientData, int *source,
XtInputId *id);
static void NotifierExitHandler(ClientData clientData);
-static void TimerProc(ClientData clientData, XtIntervalId *id);
+static void TimerProc(XtPointer clientData, XtIntervalId *id);
static void CreateFileHandler(int fd, int mask,
Tcl_FileProc *proc, ClientData clientData);
static void DeleteFileHandler(int fd);
@@ -181,7 +181,7 @@ TclSetAppContext(
void
InitNotifier(void)
{
- Tcl_NotifierProcs notifier;
+ Tcl_NotifierProcs np;
/*
* Only reinitialize if we are not in exit handling. The notifier can get
@@ -193,11 +193,15 @@ InitNotifier(void)
return;
}
- notifier.createFileHandlerProc = CreateFileHandler;
- notifier.deleteFileHandlerProc = DeleteFileHandler;
- notifier.setTimerProc = SetTimer;
- notifier.waitForEventProc = WaitForEvent;
- Tcl_SetNotifier(&notifier);
+ np.createFileHandlerProc = CreateFileHandler;
+ np.deleteFileHandlerProc = DeleteFileHandler;
+ np.setTimerProc = SetTimer;
+ np.waitForEventProc = WaitForEvent;
+ np.initNotifierProc = Tcl_InitNotifier;
+ np.finalizeNotifierProc = Tcl_FinalizeNotifier;
+ np.alertNotifierProc = Tcl_AlertNotifier;
+ np.serviceModeHookProc = Tcl_ServiceModeHook;
+ Tcl_SetNotifier(&np);
/*
* DO NOT create the application context yet; doing so would prevent
@@ -205,7 +209,7 @@ InitNotifier(void)
*/
initialized = 1;
- memset(&notifier, 0, sizeof(notifier));
+ memset(&np, 0, sizeof(np));
Tcl_CreateExitHandler(NotifierExitHandler, NULL);
}
@@ -301,7 +305,7 @@ SetTimer(
static void
TimerProc(
- ClientData clientData, /* Not used. */
+ XtPointer clientData, /* Not used. */
XtIntervalId *id)
{
if (*id != notifier.currentTimeout) {
@@ -488,7 +492,7 @@ DeleteFileHandler(
static void
FileProc(
- ClientData clientData,
+ XtPointer clientData,
int *fd,
XtInputId *id)
{
diff --git a/unix/tclooConfig.sh b/unix/tclooConfig.sh
index 721825b..08cc4c5 100644
--- a/unix/tclooConfig.sh
+++ b/unix/tclooConfig.sh
@@ -16,4 +16,4 @@ TCLOO_STUB_LIB_SPEC=""
TCLOO_INCLUDE_SPEC=""
TCLOO_PRIVATE_INCLUDE_SPEC=""
TCLOO_CFLAGS=""
-TCLOO_VERSION=1.0
+TCLOO_VERSION=1.0.1