diff options
Diffstat (limited to 'win')
-rwxr-xr-x | win/configure | 2 | ||||
-rw-r--r-- | win/makefile.bc | 594 | ||||
-rw-r--r-- | win/nmakehlp.c | 24 | ||||
-rw-r--r-- | win/rules.vc | 15 | ||||
-rw-r--r-- | win/tcl.dsp | 20 | ||||
-rw-r--r-- | win/tcl.m4 | 2 | ||||
-rw-r--r-- | win/tclWinSock.c | 593 | ||||
-rw-r--r-- | win/tclWinTime.c | 8 |
8 files changed, 422 insertions, 836 deletions
diff --git a/win/configure b/win/configure index 73d6d9f..147252c 100755 --- a/win/configure +++ b/win/configure @@ -4165,7 +4165,7 @@ $as_echo "using shared flags" >&6; } CFLAGS_DEBUG=-g CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer" - CFLAGS_WARNING="-Wall -Wsign-compare -Wdeclaration-after-statement" + CFLAGS_WARNING="-Wall -Wwrite-strings -Wsign-compare -Wdeclaration-after-statement" LDFLAGS_DEBUG= LDFLAGS_OPTIMIZE= diff --git a/win/makefile.bc b/win/makefile.bc deleted file mode 100644 index bee61d7..0000000 --- a/win/makefile.bc +++ /dev/null @@ -1,594 +0,0 @@ -#
-# Makefile for Borland C++ 5.5 (or C++ Builder 5), adapted from the makefile
-# for Visual C++ that came with tcl 8.3.3
-#
-# See the file "license.terms" for information on usage and redistribution
-# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-#
-# Copyright (c) 1995-1996 Sun Microsystems, Inc.
-# Copyright (c) 1998-1999 by Scriptics Corporation.
-
-# TIP #59 information.
-#
-# This makefile does not set the following configuration cpp
-# defines. Behind the defines are the makefile variables listed to set
-# to -D... when that feature is enabled.
-#
-# - TCL_CFG_PROFILED PROFDEFINES
-# - TCL_CFG_OPTIMIZED OPTDEFINES
-# - TCL_CFG_DO64BIT SIXFOURDEFINES
-
-# Have a look at the complete description on how to build and test Tcl with
-# the current Borland compilers at www.ratiosoft.com/tcl/borland.
-#
-# Usage:
-# - Adapt the paths below to match your compiler's location
-# - Make sure the compiler's bin directory is on your path
-# - Open a console
-# - To make a debug version enter
-# make -fmakefile.bc -DNODEBUG=0 xxx
-# where 'xxx' is the target you want (e.g. 'all', 'test', ...)
-# Please note: I omitted the 'd' suffix for debug versions because Tcl
-# will always call tclpip83.dll and not tclpip83d.dll, causing an error.
-# ^
-# Besides, the debug version goes into a separate directory, so there
-# should be no problem having DLLs and EXEs with the same name.
-# If you prefer your debug version having the 'd' suffix just uncomment
-# the line
-# #DBGX = d
-#
-# - To make a 'normal' version enter
-# make -fmakefile.bc xxx
-# where 'xxx' is the target you want (e.g. 'all', 'test', ...)
-#
-# DISCLAIMER:
-# This makefile has an experimental status - that is those targets which
-# have been modified do in fact compile and link with Borland's C++
-# Builder 5 and with the free Borland compiler (Borland C++ 5.5).
-# However the author assumes no responsiblity for any effect which the use of
-# this makefile or of the resulting programs might have on your system.
-#
-# Not yet modified:
-# - The 'plug-in-DLL' and the associated shell.
-#
-# Suggestions and / or improvements are always welcome.
-#
-# May 2001, H. Giese (hgiese@ratiosoft.com)
-#
-
-# Does not depend on the presence of any environment variables in
-# order to compile tcl; all needed information is derived from
-# location of the compiler directories.
-
-#
-# Project directories
-#
-# ROOT = top of source tree
-#
-# TOOLS32 = location of Borland development tools.
-#
-# INSTALLDIR = where the install-targets should copy the binaries and
-# support files
-#
-
-ROOT = ..
-INSTALLDIR = c:\program files\tcl
-
-# If you have C++ Builder 5 or the free Borland C++ 5.5 compiler
-# adapt the following paths as appropriate for your system
-TOOLS32 = c:\dev\bcc55
-TOOLS32_rc = c:\dev\bcc55
-#TOOLS32 = c:\bc55
-#TOOLS32_rc = c:\bc55
-
-cc32 = "$(TOOLS32)\bin\bcc32.exe"
-link32 = "$(TOOLS32)\bin\ilink32.exe"
-lib32 = "$(TOOLS32)\bin\tlib.exe"
-rc32 = "$(TOOLS32_rc)\bin\brcc32.exe"
-include32 = -I"$(TOOLS32)\include"
-libpath32 = -L"$(TOOLS32)\lib"
-
-# Uncomment the following line to compile with thread support
-#THREADDEFINES = -DTCL_THREADS=1
-
-# Allow definition of NDEBUG via command line
-# Set NODEBUG to 0 to compile with symbols
-!if !defined(NODEBUG)
-NODEBUG = 1
-!endif
-
-# CFG_ENCODING=encoding
-# name of encoding for configuration information. Defaults
-# to cp1252
-!if !defined(CFG_ENCODING)
-CFG_ENCODING = \"cp1252\"
-!endif
-
-# The following defines can be used to control the amount of debugging
-# code that is added to the compilation.
-#
-# -DTCL_MEM_DEBUG Enables the debugging memory allocator.
-# -DTCL_COMPILE_DEBUG Enables byte compilation logging.
-# -DTCL_COMPILE_STATS Enables byte compilation statistics gathering.
-# -DUSE_TCLALLOC=0 Disables the Tcl memory allocator in favor
-# of the native malloc implementation. This is
-# needed when using Purify.
-#
-#DEBUGDEFINES = -DTCL_MEM_DEBUG -DTCL_COMPILE_DEBUG -DTCL_COMPILE_STATS
-#DEBUGDEFINES = -DUSE_TCLALLOC=0
-
-######################################################################
-# Do not modify below this line
-######################################################################
-
-NAMEPREFIX = tcl
-STUBPREFIX = $(NAMEPREFIX)stub
-DOTVERSION = 8.7
-VERSION = 87
-
-DDEVERSION = 14
-DDEDOTVERSION = 1.4
-
-REGVERSION = 13
-REGDOTVERSION = 1.3
-
-BINROOT = ..
-!IF "$(NODEBUG)" == "1"
-TMPDIRNAME = Release
-DBGX =
-SYMDEFINES = -DNDEBUG
-!ELSE
-TMPDIRNAME = Debug
-#DBGX = d
-DBGX =
-SYMDEFINES = -DTCL_CFG_DEBUG
-!ENDIF
-TMPDIR = $(BINROOT)\$(TMPDIRNAME)
-OUTDIRNAME = $(TMPDIRNAME)
-OUTDIR = $(TMPDIR)
-
-TCLLIB = $(OUTDIR)\$(NAMEPREFIX)$(VERSION)$(DBGX).lib
-TCLDLLNAME = $(NAMEPREFIX)$(VERSION)$(DBGX).dll
-TCLDLL = $(OUTDIR)\$(TCLDLLNAME)
-
-TCLSTUBLIBNAME = $(STUBPREFIX)$(VERSION)$(DBGX).lib
-TCLSTUBLIB = $(OUTDIR)\$(TCLSTUBLIBNAME)
-
-TCLPLUGINLIB = $(OUTDIR)\$(NAMEPREFIX)$(VERSION)p$(DBGX).lib
-TCLPLUGINDLLNAME = $(NAMEPREFIX)$(VERSION)p$(DBGX).dll
-TCLPLUGINDLL = $(OUTDIR)\$(TCLPLUGINDLLNAME)
-TCLSH = $(OUTDIR)\$(NAMEPREFIX)sh$(VERSION)$(DBGX).exe
-TCLSHP = $(OUTDIR)\$(NAMEPREFIX)shp$(VERSION)$(DBGX).exe
-TCLREGDLLNAME = $(NAMEPREFIX)reg$(REGVERSION)$(DBGX).dll
-TCLREGDLL = $(OUTDIR)\$(TCLREGDLLNAME)
-TCLDDEDLLNAME = $(NAMEPREFIX)dde$(DDEVERSION)$(DBGX).dll
-TCLDDEDLL = $(OUTDIR)\$(TCLDDEDLLNAME)
-TCLTEST = $(OUTDIR)\$(NAMEPREFIX)test.exe
-CAT32 = $(TMPDIR)\cat32.exe
-RMDIR = .\rmd.bat
-MKDIR = .\mkd.bat
-RM = del
-
-LIB_INSTALL_DIR = $(INSTALLDIR)\lib
-BIN_INSTALL_DIR = $(INSTALLDIR)\bin
-SCRIPT_INSTALL_DIR = $(INSTALLDIR)\lib\tcl$(DOTVERSION)
-INCLUDE_INSTALL_DIR = $(INSTALLDIR)\include
-
-TCLSHOBJS = \
- $(TMPDIR)\tclAppInit.obj
-
-TCLTESTOBJS = \
- $(TMPDIR)\tclTest.obj \
- $(TMPDIR)\tclTestObj.obj \
- $(TMPDIR)\tclTestProcBodyObj.obj \
- $(TMPDIR)\tclThreadTest.obj \
- $(TMPDIR)\tclWinTest.obj \
- $(TMPDIR)\testMain.obj
-
-TCLOBJS = \
- $(TMPDIR)\regcomp.obj \
- $(TMPDIR)\regexec.obj \
- $(TMPDIR)\regfree.obj \
- $(TMPDIR)\regerror.obj \
- $(TMPDIR)\tclAlloc.obj \
- $(TMPDIR)\tclAsync.obj \
- $(TMPDIR)\tclBasic.obj \
- $(TMPDIR)\tclBinary.obj \
- $(TMPDIR)\tclCkalloc.obj \
- $(TMPDIR)\tclClock.obj \
- $(TMPDIR)\tclCmdAH.obj \
- $(TMPDIR)\tclCmdIL.obj \
- $(TMPDIR)\tclCmdMZ.obj \
- $(TMPDIR)\tclCompCmds.obj \
- $(TMPDIR)\tclCompCmdsGR.obj \
- $(TMPDIR)\tclCompCmdsSZ.obj \
- $(TMPDIR)\tclCompExpr.obj \
- $(TMPDIR)\tclCompile.obj \
- $(TMPDIR)\tclConfig.obj \
- $(TMPDIR)\tclDate.obj \
- $(TMPDIR)\tclDictObj.obj \
- $(TMPDIR)\tclDisassemble.obj \
- $(TMPDIR)\tclEncoding.obj \
- $(TMPDIR)\tclEnsemble.obj \
- $(TMPDIR)\tclEnv.obj \
- $(TMPDIR)\tclEvent.obj \
- $(TMPDIR)\tclExecute.obj \
- $(TMPDIR)\tclFCmd.obj \
- $(TMPDIR)\tclFileName.obj \
- $(TMPDIR)\tclGet.obj \
- $(TMPDIR)\tclHash.obj \
- $(TMPDIR)\tclHistory.obj \
- $(TMPDIR)\tclIndexObj.obj \
- $(TMPDIR)\tclInterp.obj \
- $(TMPDIR)\tclIO.obj \
- $(TMPDIR)\tclIOCmd.obj \
- $(TMPDIR)\tclIOGT.obj \
- $(TMPDIR)\tclIOSock.obj \
- $(TMPDIR)\tclIOUtil.obj \
- $(TMPDIR)\tclLink.obj \
- $(TMPDIR)\tclLiteral.obj \
- $(TMPDIR)\tclListObj.obj \
- $(TMPDIR)\tclLoad.obj \
- $(TMPDIR)\tclMain.obj \
- $(TMPDIR)\tclNamesp.obj \
- $(TMPDIR)\tclNotify.obj \
- $(TMPDIR)\tclOO.obj \
- $(TMPDIR)\tclOOBasic.obj \
- $(TMPDIR)\tclOOCall.obj \
- $(TMPDIR)\tclOODefineCmds.obj \
- $(TMPDIR)\tclOOInfo.obj \
- $(TMPDIR)\tclOOMethod.obj \
- $(TMPDIR)\tclOOStubInit.obj \
- $(TMPDIR)\tclObj.obj \
- $(TMPDIR)\tclOptimize.obj \
- $(TMPDIR)\tclPanic.obj \
- $(TMPDIR)\tclParse.obj \
- $(TMPDIR)\tclPipe.obj \
- $(TMPDIR)\tclPkg.obj \
- $(TMPDIR)\tclPkgConfig.obj \
- $(TMPDIR)\tclPosixStr.obj \
- $(TMPDIR)\tclPreserve.obj \
- $(TMPDIR)\tclProc.obj \
- $(TMPDIR)\tclRegexp.obj \
- $(TMPDIR)\tclResolve.obj \
- $(TMPDIR)\tclResult.obj \
- $(TMPDIR)\tclScan.obj \
- $(TMPDIR)\tclStringObj.obj \
- $(TMPDIR)\tclStubInit.obj \
- $(TMPDIR)\tclThread.obj \
- $(TMPDIR)\tclThreadJoin.obj \
- $(TMPDIR)\tclTimer.obj \
- $(TMPDIR)\tclTrace.obj \
- $(TMPDIR)\tclUtf.obj \
- $(TMPDIR)\tclUtil.obj \
- $(TMPDIR)\tclVar.obj \
- $(TMPDIR)\tclWin32Dll.obj \
- $(TMPDIR)\tclWinChan.obj \
- $(TMPDIR)\tclWinConsole.obj \
- $(TMPDIR)\tclWinSerial.obj \
- $(TMPDIR)\tclWinError.obj \
- $(TMPDIR)\tclWinFCmd.obj \
- $(TMPDIR)\tclWinFile.obj \
- $(TMPDIR)\tclWinInit.obj \
- $(TMPDIR)\tclWinLoad.obj \
- $(TMPDIR)\tclWinNotify.obj \
- $(TMPDIR)\tclWinPipe.obj \
- $(TMPDIR)\tclWinSock.obj \
- $(TMPDIR)\tclWinThrd.obj \
- $(TMPDIR)\tclWinTime.obj \
- $(TMPDIR)\tclZlib.obj
-
-TCLSTUBOBJS = \
- $(TMPDIR)\tclStubLib.obj \
- $(TMPDIR)\tclTomMathStubLib.obj \
- $(TMPDIR)\tclOOStubLib.obj
-
-WINDIR = $(ROOT)\win
-GENERICDIR = $(ROOT)\generic
-
-TCL_INCLUDES = -I"$(WINDIR)" -I"$(GENERICDIR)"
-TCL_DEFINES = $(DEBUGDEFINES) $(THREADDEFINES) $(SYMDEFINES) \
- $(PROFDEFINES) $(OPTDEFINES) $(SIXFOURDEFINES) \
- -DTCL_CFGVAL_ENCODING=${CFG_ENCODING}
-### TODO: Add -DHAVE_ZLIB=1
-
-######################################################################
-# Compiler flags
-######################################################################
-
-!IF "$(NODEBUG)" == "1"
-# these macros cause maximum optimization and no symbols
-cdebug = -v- -vi- -O2 -D_DEBUG
-!ELSE
-# these macros enable debugging
-cdebug = -k -Od -r- -v -vi- -y
-!ENDIF
-
-SYSDEFINES = _MT;NO_STRICT;_NO_VCL
-
-# declarations common to all compiler options
-cbase = -c -q -3 -a4 -g0 -tWM -Ve -Vx -X-
-WARNINGS = -w-rch -w-pch -w-par -w-dup -w-pro -w-dpu
-
-ccons = -tWC
-
-INCLUDEPATH = $(include32) $(TCL_INCLUDES)
-
-CFLAGS = $(cdebug) $(cbase) $(INCLUDEPATH) $(WARNINGS) -D$(SYSDEFINES)
-TCL_CFLAGS = $(CFLAGS) $(TCL_DEFINES)
-CONS_CFLAGS = $(CFLAGS) $(TCL_DEFINES) $(ccons)
-
-######################################################################
-# Linker flags
-######################################################################
-
-!IF "$(NODEBUG)" == "1"
-ldebug =
-!ELSE
-ldebug = -v
-!ENDIF
-
-# declarations common to all linker options
-LNFLAGS = -D"" -Gn -I$(TMPDIR) -x $(ldebug) $(libpath32)
-# -Gi: create lib file (is -Gl in doc)
-# -aa: Windows app, -ap: Windows console app
-LNFLAGS_DLL = -ap -Gi -Tpd
-LNFLAGS_CONS = -ap -Tpe
-
-LNLIBS = import32 cw32mt
-
-
-######################################################################
-# Project specific targets
-######################################################################
-
-release: setup $(TCLSH) dlls
-dlls: setup $(TCLREGDLL) $(TCLDDEDLL)
-all: setup $(TCLSH) dlls $(CAT32)
-tcltest: setup $(TCLTEST) dlls $(CAT32)
-plugin: setup $(TCLPLUGINDLL) $(TCLSHP)
-install: install-binaries install-libraries
-
-test: setup $(TCLTEST) dlls $(CAT32)
- set TCL_LIBRARY=$(ROOT)/library
- $(TCLTEST) $(ROOT)/tests/all.tcl
-
-setup:
- @if not exist $(OUT_DIR)\nul mkdir $(OUT_DIR) &\
- echo *** Created directory '$(OUT_DIR)'
- @if not exist $(TMP_DIR)\nul mkdir $(TMP_DIR) &\
- echo *** Created directory '$(TMP_DIR)'
-
-
-$(TCLLIB): $(TCLDLL)
-
-$(TCLDLL): $(TCLOBJS) $(TMPDIR)\$(NAMEPREFIX).res
- $(link32) $(ldebug) $(LNFLAGS) $(LNFLAGS_DLL) $(TOOLS32)\lib\c0d32 @&&!
- $(TCLOBJS), $@, -x, $(LNLIBS),, $(TMPDIR)\$(NAMEPREFIX).res
-!
-
-$(TCLSTUBLIB): $(TCLSTUBOBJS)
- $(lib32) /u $@ $(TCLSTUBOBJS)
-
-$(TCLPLUGINLIB): $(TCLPLUGINDLL)
-
-$(TCLPLUGINDLL): $(TCLOBJS) $(TMPDIR)\tcl.res
- $(link32) $(ldebug) $(dlllflags) \
- -out:$@ $(TMPDIR)\tcl.res $(guilibsdll) @&&!
-$(TCLOBJS)
-!
-
-$(TCLSH): $(TCLSHOBJS) $(TCLLIB) $(TMPDIR)\$(NAMEPREFIX)sh.res
- $(link32) $(ldebug) -S:2400000 $(LNFLAGS) $(LNFLAGS_CONS) $(TOOLS32)\lib\c0x32 @&&!
- $(TCLSHOBJS), $@, -x, $(LNLIBS) $(TCLLIB),, $(TMPDIR)\$(NAMEPREFIX)sh.res
-!
-
-$(TCLSHP): $(TCLSHOBJS) $(TCLPLUGINLIB) $(TMPDIR)\tclsh.res
- $(link32) $(ldebug) $(conlflags) $(TMPDIR)\tclsh.res -stack:2300000 \
- -out:$@ $(conlibsdll) $(TCLPLUGINLIB) $(TCLSHOBJS)
-
-$(TCLTEST): $(TCLTESTOBJS) $(TCLLIB) $(TMPDIR)\$(NAMEPREFIX)sh.res
- $(link32) $(ldebug) -S:2400000 $(LNFLAGS) $(LNFLAGS_CONS) $(TOOLS32)\lib\c0x32 @&&!
- $(TCLTESTOBJS), $@, -x, $(LNLIBS) $(TCLLIB),, $(TMPDIR)\$(NAMEPREFIX)sh.res
-!
-
-$(TCLDDEDLL): $(TMPDIR)\tclWinDde.obj $(TCLSTUBLIB)
- $(link32) $(ldebug) $(LNFLAGS) $(LNFLAGS_DLL) $(TOOLS32)\lib\c0d32 \
- $(TMPDIR)\tclWinDde.obj, $@, -x, $(LNLIBS) $(TCLSTUBLIB),, \
- $(TMPDIR)\$(NAMEPREFIX).res
-
-$(TCLREGDLL): $(TMPDIR)\tclWinReg.obj $(TCLSTUBLIB)
- $(link32) $(ldebug) $(LNFLAGS) $(LNFLAGS_DLL) $(TOOLS32)\lib\c0d32 \
- $(TMPDIR)\tclWinReg.obj, $@, -x, $(LNLIBS) $(TCLSTUBLIB),, \
- $(TMPDIR)\$(NAMEPREFIX).res
-
-$(CAT32): $(WINDIR)\cat.c
- $(cc32) $(CONS_CFLAGS) -o$(TMPDIR)\cat.obj $?
- $(link32) $(ldebug) $(LNFLAGS) $(LNFLAGS_CONS) $(TOOLS32)\lib\c0x32 \
- $(TMPDIR)\cat.obj, $@, -x, $(LNLIBS),,
-
-install-binaries: $(TCLSH)
- $(MKDIR) "$(BIN_INSTALL_DIR)"
- $(MKDIR) "$(LIB_INSTALL_DIR)"
- @echo Installing $(TCLDLLNAME)
- @copy "$(TCLDLL)" "$(BIN_INSTALL_DIR)"
- @copy "$(TCLLIB)" "$(LIB_INSTALL_DIR)"
- @echo Installing "$(TCLSH)"
- @copy "$(TCLSH)" "$(BIN_INSTALL_DIR)"
- @echo Installing $(TCLSTUBLIBNAME)
- @copy "$(TCLSTUBLIB)" "$(LIB_INSTALL_DIR)"
- @echo Installing $(WINDIR)\tclooConfig.sh
- @copy "$(WINDIR)\tclooConfig.sh" "$(LIB_INSTALL_DIR)"
-
-install-libraries:
- -@$(MKDIR) "$(LIB_INSTALL_DIR)"
- -@$(MKDIR) "$(INCLUDE_INSTALL_DIR)"
- -@$(MKDIR) "$(SCRIPT_INSTALL_DIR)"
- @echo Installing http1.0
- -@$(MKDIR) "$(SCRIPT_INSTALL_DIR)\http1.0"
- -@copy "$(ROOT)\library\http1.0\http.tcl" "$(SCRIPT_INSTALL_DIR)\http1.0"
- -@copy "$(ROOT)\library\http1.0\pkgIndex.tcl" "$(SCRIPT_INSTALL_DIR)\http1.0"
- @echo Installing http2.8
- -@$(MKDIR) "$(SCRIPT_INSTALL_DIR)\http2.8"
- -@copy "$(ROOT)\library\http\http.tcl" "$(SCRIPT_INSTALL_DIR)\http2.8"
- -@copy "$(ROOT)\library\http\pkgIndex.tcl" "$(SCRIPT_INSTALL_DIR)\http2.8"
- @echo Installing opt0.4
- -@$(MKDIR) "$(SCRIPT_INSTALL_DIR)\opt0.4"
- -@copy "$(ROOT)\library\opt\optparse.tcl" "$(SCRIPT_INSTALL_DIR)\opt0.4"
- -@copy "$(ROOT)\library\opt\pkgIndex.tcl" "$(SCRIPT_INSTALL_DIR)\opt0.4"
- @echo Installing msgcat1.5
- -@$(MKDIR) "$(SCRIPT_INSTALL_DIR)\msgcat1.5"
- -@copy "$(ROOT)\library\msgcat\msgcat.tcl" "$(SCRIPT_INSTALL_DIR)\msgcat1.5"
- -@copy "$(ROOT)\library\msgcat\pkgIndex.tcl" "$(SCRIPT_INSTALL_DIR)\msgcat1.5"
- @echo Installing tcltest2.3
- -@$(MKDIR) "$(SCRIPT_INSTALL_DIR)\tcltest2.3"
- -@copy "$(ROOT)\library\tcltest\tcltest.tcl" "$(SCRIPT_INSTALL_DIR)\tcltest2.3"
- -@copy "$(ROOT)\library\tcltest\pkgIndex.tcl" "$(SCRIPT_INSTALL_DIR)\tcltest2.3"
- @echo Installing platform1.0
- -@$(MKDIR) "$(SCRIPT_INSTALL_DIR)\platform1.0"
- -@copy "$(ROOT)\library\platform\platform.tcl" "$(SCRIPT_INSTALL_DIR)\platform1.0"
- -@copy "$(ROOT)\library\platform\shell.tcl" "$(SCRIPT_INSTALL_DIR)\platform1.0"
- -@copy "$(ROOT)\library\platform\pkgIndex.tcl" "$(SCRIPT_INSTALL_DIR)\platform1.0"
- @echo Installing $(TCLDDEDLLNAME)
- -@$(MKDIR) "$(SCRIPT_INSTALL_DIR)\dde1.3"
- -@copy "$(TCLDDEDLL)" "$(SCRIPT_INSTALL_DIR)\dde1.3"
- -@copy "$(ROOT)\library\dde\pkgIndex.tcl" "$(SCRIPT_INSTALL_DIR)\dde1.3"
- @echo Installing $(TCLREGDLLNAME)
- -@$(MKDIR) "$(SCRIPT_INSTALL_DIR)\reg1.2"
- -@copy "$(TCLREGDLL)" "$(SCRIPT_INSTALL_DIR)\reg1.3"
- -@copy "$(ROOT)\library\reg\pkgIndex.tcl" "$(SCRIPT_INSTALL_DIR)\reg1.2"
- @echo Installing encoding files
- -@$(MKDIR) "$(SCRIPT_INSTALL_DIR)\encoding"
- -@copy "$(ROOT)\library\encoding\*.enc" "$(SCRIPT_INSTALL_DIR)\encoding"
- @echo Installing library files
- -@copy "$(GENERICDIR)\tcl.h" "$(INCLUDE_INSTALL_DIR)"
- -@copy "$(GENERICDIR)\tclDecls.h" "$(INCLUDE_INSTALL_DIR)"
- -@copy "$(GENERICDIR)\tclOO.h" "$(INCLUDE_INSTALL_DIR)"
- -@copy "$(GENERICDIR)\tclOODecls.h" "$(INCLUDE_INSTALL_DIR)"
- -@copy "$(GENERICDIR)\tclPlatDecls.h" "$(INCLUDE_INSTALL_DIR)"
- -@copy "$(ROOT)\library\history.tcl" "$(SCRIPT_INSTALL_DIR)"
- -@copy "$(ROOT)\library\init.tcl" "$(SCRIPT_INSTALL_DIR)"
- -@copy "$(ROOT)\library\parray.tcl" "$(SCRIPT_INSTALL_DIR)"
- -@copy "$(ROOT)\library\safe.tcl" "$(SCRIPT_INSTALL_DIR)"
- -@copy "$(ROOT)\library\tclIndex" "$(SCRIPT_INSTALL_DIR)"
- -@copy "$(ROOT)\library\package.tcl" "$(SCRIPT_INSTALL_DIR)"
- -@copy "$(ROOT)\library\word.tcl" "$(SCRIPT_INSTALL_DIR)"
- -@copy "$(ROOT)\library\auto.tcl" "$(SCRIPT_INSTALL_DIR)"
-
-#
-# Regenerate the stubs files.
-#
-
-genstubs:
- tclsh$(VERSION) $(ROOT)\tools\genStubs.tcl $(GENERICDIR) \
- $(GENERICDIR)\tcl.decls $(GENERICDIR)\tclInt.decls
-
-#
-# Special case object file targets
-#
-$(TMPDIR)\tclWinInit.obj: $(WINDIR)\tclWinInit.c
- $(cc32) -DBUILD_tcl $(TCL_CFLAGS) -o$(TMPDIR)\$@ $?
-
-$(TMPDIR)\testMain.obj: $(WINDIR)\tclAppInit.c
- $(cc32) $(TCL_CFLAGS) -DTCL_TEST -o$(TMPDIR)\testMain.obj $?
-
-$(TMPDIR)\tclTest.obj: $(GENERICDIR)\tclTest.c
- $(cc32) $(TCL_CFLAGS) -o$(TMPDIR)\$@ $?
-
-$(TMPDIR)\tclTestObj.obj: $(GENERICDIR)\tclTestObj.c
- $(cc32) $(TCL_CFLAGS) -o$(TMPDIR)\$@ $?
-
-$(TMPDIR)\tclWinTest.obj: $(WINDIR)\tclWinTest.c
- $(cc32) $(TCL_CFLAGS) -o$(TMPDIR)\$@ $?
-
-$(TMP_DIR)\tclPkgConfig.obj: $(GENERICDIR)\tclPkgConfig.c
- $(cc32) $(TCL_CFLAGS) \
- -DCFG_INSTALL_EXEC_PREFIX=\"$(INSTALL_EXEC_PREFIX)\" \
- -DCFG_INSTALL_PREFIX=\"$(INSTALL_PREFIX)\" \
- -DCFG_RUNTIME_EXEC_PREFIX=\"$(RUNTIME_EXEC_PREFIX)\" \
- -DCFG_RUNTIME_PREFIX=\"$(RUNTIME_PREFIX)\" \
- -o$(TMPDIR)\$@ $?
-
-$(TMPDIR)\tclAppInit.obj : $(WINDIR)\tclAppInit.c
- $(cc32) $(TCL_CFLAGS) -o$(TMPDIR)\$@ $?
-
-# The following objects should be built using the stub interfaces
-
-# tclWinReg: Produces errors in ANSI mode
-$(TMPDIR)\tclWinReg.obj : $(WINDIR)\tclWinReg.c
- $(cc32) $(TCL_CFLAGS) -DUSE_TCL_STUBS -o$(TMPDIR)\$@ $?
-
-# tclWinDde: Produces errors in ANSI mode
-$(TMPDIR)\tclWinDde.obj : $(WINDIR)\tclWinDde.c
- $(cc32) $(TCL_CFLAGS) -DUSE_TCL_STUBS -o$(TMPDIR)\$@ $?
-
-
-# The following objects are part of the stub library and should not
-# be built as DLL objects but none of the symbols should be exported
-
-$(TMPDIR)\tclStubLib.obj : $(GENERICDIR)\tclStubLib.c
- $(cc32) $(TCL_CFLAGS) -DSTATIC_BUILD -o$(TMPDIR)\$@ $?
-
-$(TMPDIR)\tclTomMathStubLib.obj : $(GENERICDIR)\tclTomMathStubLib.c
- $(cc32) $(TCL_CFLAGS) -DSTATIC_BUILD -o$(TMPDIR)\$@ $?
-
-$(TMPDIR)\tclOOStubLib.obj : $(GENERICDIR)\tclOOStubLib.c
- $(cc32) $(TCL_CFLAGS) -DSTATIC_BUILD -o$(TMPDIR)\$@ $?
-
-
-# Dedependency rules
-
-$(GENERICDIR)\regcomp.c: \
- $(GENERICDIR)\regguts.h \
- $(GENERICDIR)\regc_lex.c \
- $(GENERICDIR)\regc_color.c \
- $(GENERICDIR)\regc_nfa.c \
- $(GENERICDIR)\regc_cvec.c \
- $(GENERICDIR)\regc_locale.c
-
-$(GENERICDIR)\regcustom.h: \
- $(GENERICDIR)\tclInt.h \
- $(GENERICDIR)\tclPort.h \
- $(GENERICDIR)\regex.h
-
-$(GENERICDIR)\regexec.c: \
- $(GENERICDIR)\rege_dfa.c \
- $(GENERICDIR)\regguts.h
-
-$(GENERICDIR)\regerror.c: $(GENERICDIR)\regguts.h
-$(GENERICDIR)\regfree.c: $(GENERICDIR)\regguts.h
-$(GENERICDIR)\regfronts.c: $(GENERICDIR)\regguts.h
-$(GENERICDIR)\regguts.h: $(GENERICDIR)\regcustom.h
-
-#
-# Implicit rules
-#
-
-{$(WINDIR)}.c{$(TMPDIR)}.obj:
- $(cc32) -DBUILD_tcl $(TCL_CFLAGS) -o$@ $<
-
-{$(GENERICDIR)}.c{$(TMPDIR)}.obj:
- $(cc32) -DBUILD_tcl $(TCL_CFLAGS) -o$@ $<
-
-{$(ROOT)\compat}.c{$(TMPDIR)}.obj:
- $(cc32) -DBUILD_tcl $(TCL_CFLAGS) -o$@ $<
-
-{$(WINDIR)}.rc{$(TMPDIR)}.res:
- $(rc32) $(INCLUDEPATH) -D$(USERDEFINES);$(SYSDEFINES) -fo$@ $<
-
-clean:
- -@$(RM) $(OUTDIR)\*.exp
- -@$(RM) $(OUTDIR)\*.lib
- -@$(RM) $(OUTDIR)\*.dll
- -@$(RM) $(OUTDIR)\*.exe
- -@$(RM) $(OUTDIR)\*.pdb
- -@$(RM) $(TMPDIR)\*.pch
- -@$(RM) $(TMPDIR)\*.obj
- -@$(RM) $(TMPDIR)\*.res
- -@$(RM) $(TMPDIR)\*.exe
- -@$(RMDIR) $(OUTDIR)
- -@$(RMDIR) $(TMPDIR)
-
-# Local Variables:
-# mode: makefile
-# End:
diff --git a/win/nmakehlp.c b/win/nmakehlp.c index 84cf75c..22b7b06 100644 --- a/win/nmakehlp.c +++ b/win/nmakehlp.c @@ -43,7 +43,7 @@ /* protos */ static int CheckForCompilerFeature(const char *option); -static int CheckForLinkerFeature(const char *option); +static int CheckForLinkerFeature(const char **options, int count); static int IsIn(const char *string, const char *substring); static int SubstituteFile(const char *substs, const char *filename); static int QualifyPath(const char *path); @@ -102,16 +102,16 @@ main( } return CheckForCompilerFeature(argv[2]); case 'l': - if (argc != 3) { + if (argc < 3) { chars = snprintf(msg, sizeof(msg) - 1, - "usage: %s -l <linker option>\n" + "usage: %s -l <linker option> ?<mandatory option> ...?\n" "Tests for whether link.exe supports an option\n" "exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]); WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars, &dwWritten, NULL); return 2; } - return CheckForLinkerFeature(argv[2]); + return CheckForLinkerFeature(&argv[2], argc-2); case 'f': if (argc == 2) { chars = snprintf(msg, sizeof(msg) - 1, @@ -313,7 +313,8 @@ CheckForCompilerFeature( static int CheckForLinkerFeature( - const char *option) + const char **options, + int count) { STARTUPINFO si; PROCESS_INFORMATION pi; @@ -322,7 +323,8 @@ CheckForLinkerFeature( char msg[300]; BOOL ok; HANDLE hProcess, h, pipeThreads[2]; - char cmdline[100]; + int i; + char cmdline[255]; hProcess = GetCurrentProcess(); @@ -368,7 +370,11 @@ CheckForLinkerFeature( * Append our option for testing. */ - lstrcat(cmdline, option); + for (i = 0; i < count; i++) { + lstrcat(cmdline, " \""); + lstrcat(cmdline, options[i]); + lstrcat(cmdline, "\""); + } ok = CreateProcess( NULL, /* Module name. */ @@ -433,7 +439,9 @@ CheckForLinkerFeature( return !(strstr(Out.buffer, "LNK1117") != NULL || strstr(Err.buffer, "LNK1117") != NULL || strstr(Out.buffer, "LNK4044") != NULL || - strstr(Err.buffer, "LNK4044") != NULL); + strstr(Err.buffer, "LNK4044") != NULL || + strstr(Out.buffer, "LNK4224") != NULL || + strstr(Err.buffer, "LNK4224") != NULL); } static DWORD WINAPI diff --git a/win/rules.vc b/win/rules.vc index e12854d..4a3ae26 100644 --- a/win/rules.vc +++ b/win/rules.vc @@ -188,9 +188,14 @@ COMPILERFLAGS = $(COMPILERFLAGS) -QIA64_Bx !endif
!endif
+# Prevents "LNK1561: entry point must be defined" error compiling from VS-IDE:
+!ifndef LINKER_TESTFLAGS
+LINKER_TESTFLAGS = /DLL /NOENTRY /OUT:nmhlp-out.txt
+!endif
+
!if "$(MACHINE)" == "IX86"
### test for -align:4096, when align:512 will do.
-!if [nmakehlp -l -opt:nowin98]
+!if [nmakehlp -l -opt:nowin98 $(LINKER_TESTFLAGS)]
!message *** Linker has 'Win98 alignment problem'
ALIGN98_HACK = 1
!else
@@ -203,7 +208,7 @@ ALIGN98_HACK = 0 LINKERFLAGS =
-!if [nmakehlp -l -ltcg]
+!if [nmakehlp -l -ltcg $(LINKER_TESTFLAGS)]
LINKERFLAGS =-ltcg
!endif
@@ -417,7 +422,7 @@ TCL_NO_DEPRECATED = 0 !if [nmakehlp -f $(CHECKS) "fullwarn"]
!message *** Doing full warnings check
WARNINGS = -W4
-!if [nmakehlp -l -warn:3]
+!if [nmakehlp -l -warn:3 $(LINKER_TESTFLAGS)]
LINKERFLAGS = $(LINKERFLAGS) -warn:3
!endif
!else
@@ -430,7 +435,7 @@ WARNINGS = $(WARNINGS) -Wp64 !endif
!if $(PGO) > 1
-!if [nmakehlp -l -ltcg:pgoptimize]
+!if [nmakehlp -l -ltcg:pgoptimize $(LINKER_TESTFLAGS)]
LINKERFLAGS = $(LINKERFLAGS:-ltcg=) -ltcg:pgoptimize
!else
MSG=^
@@ -438,7 +443,7 @@ This compiler does not support profile guided optimization. !error $(MSG)
!endif
!elseif $(PGO) > 0
-!if [nmakehlp -l -ltcg:pginstrument]
+!if [nmakehlp -l -ltcg:pginstrument $(LINKER_TESTFLAGS)]
LINKERFLAGS = $(LINKERFLAGS:-ltcg=) -ltcg:pginstrument
!else
MSG=^
diff --git a/win/tcl.dsp b/win/tcl.dsp index 9ea990b..48eae9d 100644 --- a/win/tcl.dsp +++ b/win/tcl.dsp @@ -36,7 +36,7 @@ CFG=tcl - Win32 Debug Static # PROP BASE Intermediate_Dir "Release\tcl_Dynamic"
# PROP BASE Cmd_Line "nmake -nologo -f makefile.vc OPTS=none MSVCDIR=IDE"
# PROP BASE Rebuild_Opt "-a"
-# PROP BASE Target_File "Release\tclsh85.exe"
+# PROP BASE Target_File "Release\tclsh87.exe"
# PROP BASE Bsc_Name ""
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
@@ -45,7 +45,7 @@ CFG=tcl - Win32 Debug Static # PROP Intermediate_Dir "Release\tcl_Dynamic"
# PROP Cmd_Line "nmake -nologo -f makefile.vc OPTS=threads MSVCDIR=IDE"
# PROP Rebuild_Opt "clean release"
-# PROP Target_File "Release\tclsh85t.exe"
+# PROP Target_File "Release\tclsh87t.exe"
# PROP Bsc_Name ""
# PROP Target_Dir ""
@@ -57,7 +57,7 @@ CFG=tcl - Win32 Debug Static # PROP BASE Intermediate_Dir "Debug\tcl_Dynamic"
# PROP BASE Cmd_Line "nmake -nologo -f makefile.vc OPTS=symbols MSVCDIR=IDE"
# PROP BASE Rebuild_Opt "-a"
-# PROP BASE Target_File "Debug\tclsh85g.exe"
+# PROP BASE Target_File "Debug\tclsh87g.exe"
# PROP BASE Bsc_Name ""
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
@@ -66,7 +66,7 @@ CFG=tcl - Win32 Debug Static # PROP Intermediate_Dir "Debug\tcl_Dynamic"
# PROP Cmd_Line "nmake -nologo -f makefile.vc OPTS=threads,symbols MSVCDIR=IDE"
# PROP Rebuild_Opt "clean release"
-# PROP Target_File "Debug\tclsh85tg.exe"
+# PROP Target_File "Debug\tclsh87tg.exe"
# PROP Bsc_Name ""
# PROP Target_Dir ""
@@ -78,7 +78,7 @@ CFG=tcl - Win32 Debug Static # PROP BASE Intermediate_Dir "Debug\tcl_Static"
# PROP BASE Cmd_Line "nmake -nologo -f makefile.vc OPTS=symbols,static MSVCDIR=IDE"
# PROP BASE Rebuild_Opt "-a"
-# PROP BASE Target_File "Debug\tclsh85sg.exe"
+# PROP BASE Target_File "Debug\tclsh87sg.exe"
# PROP BASE Bsc_Name ""
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
@@ -87,7 +87,7 @@ CFG=tcl - Win32 Debug Static # PROP Intermediate_Dir "Debug\tcl_Static"
# PROP Cmd_Line "nmake -nologo -f makefile.vc OPTS=symbols,static MSVCDIR=IDE"
# PROP Rebuild_Opt "-a"
-# PROP Target_File "Debug\tclsh85sg.exe"
+# PROP Target_File "Debug\tclsh87sg.exe"
# PROP Bsc_Name ""
# PROP Target_Dir ""
@@ -99,7 +99,7 @@ CFG=tcl - Win32 Debug Static # PROP BASE Intermediate_Dir "Release\tcl_Static"
# PROP BASE Cmd_Line "nmake -nologo -f makefile.vc OPTS=static MSVCDIR=IDE"
# PROP BASE Rebuild_Opt "-a"
-# PROP BASE Target_File "Release\tclsh85s.exe"
+# PROP BASE Target_File "Release\tclsh87s.exe"
# PROP BASE Bsc_Name ""
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
@@ -108,7 +108,7 @@ CFG=tcl - Win32 Debug Static # PROP Intermediate_Dir "Release\tcl_Static"
# PROP Cmd_Line "nmake -nologo -f makefile.vc OPTS=static MSVCDIR=IDE"
# PROP Rebuild_Opt "-a"
-# PROP Target_File "Release\tclsh85s.exe"
+# PROP Target_File "Release\tclsh87s.exe"
# PROP Bsc_Name ""
# PROP Target_Dir ""
@@ -1428,10 +1428,6 @@ SOURCE=.\configure.ac # End Source File
# Begin Source File
-SOURCE=.\makefile.bc
-# End Source File
-# Begin Source File
-
SOURCE=.\Makefile.in
# End Source File
# Begin Source File
@@ -727,7 +727,7 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [ CFLAGS_DEBUG=-g CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer" - CFLAGS_WARNING="-Wall -Wsign-compare -Wdeclaration-after-statement" + CFLAGS_WARNING="-Wall -Wwrite-strings -Wsign-compare -Wdeclaration-after-statement" LDFLAGS_DEBUG= LDFLAGS_OPTIMIZE= diff --git a/win/tclWinSock.c b/win/tclWinSock.c index 8545cdd..01cefb5 100644 --- a/win/tclWinSock.c +++ b/win/tclWinSock.c @@ -297,17 +297,25 @@ static ProcessGlobalValue hostName = * Address print debug functions */ #if 0 -void printaddrinfo(struct addrinfo *ai, char *prefix) +void +printaddrinfo( + struct addrinfo *ai, + char *prefix) { char host[NI_MAXHOST], port[NI_MAXSERV]; + getnameinfo(ai->ai_addr, ai->ai_addrlen, - host, sizeof(host), - port, sizeof(port), - NI_NUMERICHOST|NI_NUMERICSERV); + host, sizeof(host), port, sizeof(port), + NI_NUMERICHOST|NI_NUMERICSERV); } -void printaddrinfolist(struct addrinfo *addrlist, char *prefix) + +void +printaddrinfolist( + struct addrinfo *addrlist, + char *prefix) { struct addrinfo *ai; + for (ai = addrlist; ai != NULL; ai = ai->ai_next) { printaddrinfo(ai, prefix); } @@ -524,9 +532,9 @@ TcpBlockModeProc( TcpState *statePtr = instanceData; if (mode == TCL_MODE_NONBLOCKING) { - statePtr->flags |= TCP_NONBLOCKING; + SET_BITS(statePtr->flags, TCP_NONBLOCKING); } else { - statePtr->flags &= ~(TCP_NONBLOCKING); + CLEAR_BITS(statePtr->flags, TCP_NONBLOCKING); } return 0; } @@ -536,29 +544,28 @@ TcpBlockModeProc( * * WaitForConnect -- * - * 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'. + * 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. + * * 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. + * * 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. + * 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. + * Processes socket events off the system queue. May process + * asynchroneous connect. * *---------------------------------------------------------------------- */ @@ -566,17 +573,16 @@ TcpBlockModeProc( static int WaitForConnect( TcpState *statePtr, /* State of the socket. */ - int *errorCodePtr) /* Where to store errors? - * A passed null-pointer activates background mode. - */ + int *errorCodePtr) /* Where to store errors? A passed + * null-pointer activates background mode. */ { int result; int oldMode; ThreadSpecificData *tsdPtr; /* - * Check if an async connect failed already and error reporting is demanded, - * return the error ENOTCONN + * Check if an async connect failed already and error reporting is + * demanded, return the error ENOTCONN. */ if (errorCodePtr != NULL && (statePtr->flags & TCP_ASYNC_FAILED)) { @@ -603,36 +609,51 @@ WaitForConnect( */ while (1) { + /* + * Get the statePtr lock. + */ - /* get statePtr lock */ tsdPtr = TclThreadDataKeyGet(&dataKey); WaitForSingleObject(tsdPtr->socketListLock, INFINITE); - /* Check for connect event */ + /* + * Check for connect event. + */ + if (statePtr->readyEvents & FD_CONNECT) { + /* + * Consume the connect event. + */ - /* Consume the connect event */ - statePtr->readyEvents &= ~(FD_CONNECT); + CLEAR_BITS(statePtr->readyEvents, FD_CONNECT); /* - * For blocking sockets and foreground processing - * disable async connect as we continue now synchoneously + * For blocking sockets and foreground processing, disable async + * connect as we continue now synchoneously. */ - if ( errorCodePtr != NULL && - ! (statePtr->flags & TCP_NONBLOCKING) ) { + + if (errorCodePtr != NULL && + !(statePtr->flags & TCP_NONBLOCKING)) { CLEAR_BITS(statePtr->flags, TCP_ASYNC_CONNECT); } - /* Free list lock */ + /* + * Free list lock. + */ + SetEvent(tsdPtr->socketListLock); /* - * Continue connect. - * If switched to synchroneous connect, the connect is terminated. + * Continue connect. If switched to synchroneous connect, the + * connect is terminated. */ + result = TcpConnect(NULL, statePtr); - /* Restore event service mode */ + /* + * Restore event service mode. + */ + (void) Tcl_SetServiceMode(oldMode); /* @@ -641,10 +662,11 @@ WaitForConnect( if (result == TCL_OK) { /* - * Check for async connect restart - * (not possible for foreground blocking operation) + * Check for async connect restart (not possible for + * foreground blocking operation) */ - if ( statePtr->flags & TCP_ASYNC_PENDING ) { + + if (statePtr->flags & TCP_ASYNC_PENDING) { if (errorCodePtr != NULL) { *errorCodePtr = EWOULDBLOCK; } @@ -654,8 +676,8 @@ WaitForConnect( } /* - * Connect finally failed. - * For foreground operation return ENOTCONN. + * Connect finally failed. For foreground operation return + * ENOTCONN. */ if (errorCodePtr != NULL) { @@ -664,7 +686,10 @@ WaitForConnect( return -1; } - /* Free list lock */ + /* + * Free list lock. + */ + SetEvent(tsdPtr->socketListLock); /* @@ -672,13 +697,13 @@ WaitForConnect( * event */ - if ( errorCodePtr == NULL ) { + if (errorCodePtr == NULL) { return -1; } /* - * A non blocking socket waiting for an asyncronous connect - * returns directly the error EWOULDBLOCK + * A non blocking socket waiting for an asyncronous connect returns + * directly the error EWOULDBLOCK. */ if (statePtr->flags & TCP_NONBLOCKING) { @@ -770,16 +795,20 @@ TcpInputProc( while (1) { SendMessage(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM) UNSELECT, (LPARAM) statePtr); - /* single fd operation: this proc is only called for a connected socket. */ + /* + * Single fd operation: this proc is only called for a connected + * socket. + */ + bytesRead = recv(statePtr->sockets->fd, buf, bufSize, 0); - statePtr->readyEvents &= ~(FD_READ); + CLEAR_BITS(statePtr->readyEvents, FD_READ); /* * Check for end-of-file condition or successful read. */ if (bytesRead == 0) { - statePtr->flags |= SOCKET_EOF; + SET_BITS(statePtr->flags, SOCKET_EOF); } if (bytesRead != SOCKET_ERROR) { break; @@ -791,7 +820,7 @@ TcpInputProc( */ if (statePtr->readyEvents & FD_CLOSE) { - statePtr->flags |= SOCKET_EOF; + SET_BITS(statePtr->flags, SOCKET_EOF); bytesRead = 0; break; } @@ -804,7 +833,7 @@ TcpInputProc( */ if (error == WSAECONNRESET) { - statePtr->flags |= SOCKET_EOF; + SET_BITS(statePtr->flags, SOCKET_EOF); bytesRead = 0; break; } @@ -892,7 +921,11 @@ TcpOutputProc( SendMessage(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM) UNSELECT, (LPARAM) statePtr); - /* single fd operation: this proc is only called for a connected socket. */ + /* + * Single fd operation: this proc is only called for a connected + * socket. + */ + written = send(statePtr->sockets->fd, buf, toWrite, 0); if (written != SOCKET_ERROR) { /* @@ -917,7 +950,7 @@ TcpOutputProc( error = WSAGetLastError(); if (error == WSAEWOULDBLOCK) { - statePtr->readyEvents &= ~(FD_WRITE); + CLEAR_BITS(statePtr->readyEvents, FD_WRITE); if (statePtr->flags & TCP_NONBLOCKING) { *errorCodePtr = EWOULDBLOCK; written = -1; @@ -941,7 +974,8 @@ TcpOutputProc( } } - SendMessage(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM)SELECT, (LPARAM)statePtr); + SendMessage(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM)SELECT, + (LPARAM)statePtr); return written; } @@ -988,10 +1022,10 @@ TcpCloseProc( * background. */ - while ( statePtr->sockets != NULL ) { + while (statePtr->sockets != NULL) { TcpFdList *thisfd = statePtr->sockets; - statePtr->sockets = thisfd->next; + statePtr->sockets = thisfd->next; if (closesocket(thisfd->fd) == SOCKET_ERROR) { TclWinConvertError((DWORD) WSAGetLastError()); errorCode = Tcl_GetErrno(); @@ -1009,18 +1043,25 @@ TcpCloseProc( /* * Clear an eventual tsd info list pointer. + * * This may be called, if an async socket connect fails or is closed * between connect and thread action callback. */ + if (tsdPtr->pendingTcpState != NULL && tsdPtr->pendingTcpState == statePtr) { + /* + * Get infoPtr lock, because this concerns the notifier thread. + */ - /* get infoPtr lock, because this concerns the notifier thread */ WaitForSingleObject(tsdPtr->socketListLock, INFINITE); tsdPtr->pendingTcpState = NULL; - /* Free list lock */ + /* + * Free list lock. + */ + SetEvent(tsdPtr->socketListLock); } @@ -1081,8 +1122,11 @@ TcpClose2Proc( return TCL_ERROR; } - /* single fd operation: Tcl_OpenTcpServer() does not set TCL_READABLE or - * TCL_WRITABLE so this should never be called for a server socket. */ + /* + * Single fd operation: Tcl_OpenTcpServer() does not set TCL_READABLE or + * TCL_WRITABLE so this should never be called for a server socket. + */ + if (shutdown(statePtr->sockets->fd, sd) == SOCKET_ERROR) { TclWinConvertError((DWORD) WSAGetLastError()); errorCode = Tcl_GetErrno(); @@ -1134,7 +1178,7 @@ TcpSetOptionProc( } #ifdef TCL_FEATURE_KEEPALIVE_NAGLE - #error "TCL_FEATURE_KEEPALIVE_NAGLE not reviewed for whether to treat statePtr->sockets as single fd or list" +#error "TCL_FEATURE_KEEPALIVE_NAGLE not reviewed for whether to treat statePtr->sockets as single fd or list" sock = statePtr->sockets->fd; if (!strcasecmp(optionName, "-keepalive")) { @@ -1243,8 +1287,11 @@ TcpGetOptionProc( /* * Go one step in async connect - * If any error is thrown save it as backround error to report eventually below + * + * If any error is thrown save it as backround error to report eventually + * below. */ + WaitForConnect(statePtr, NULL); sock = statePtr->sockets->fd; @@ -1254,31 +1301,26 @@ TcpGetOptionProc( if ((len > 1) && (optionName[1] == 'e') && (strncmp(optionName, "-error", len) == 0)) { - /* - * Do not return any errors if async connect is running - */ - if ( ! (statePtr->flags & TCP_ASYNC_PENDING) ) { - - - if ( statePtr->flags & TCP_ASYNC_FAILED ) { + * Do not return any errors if async connect is running. + */ + if (!(statePtr->flags & TCP_ASYNC_PENDING)) { + if (statePtr->flags & TCP_ASYNC_FAILED) { /* * In case of a failed async connect, eventually report the - * connect error only once. - * Do not report the system error, as this comes again and again. + * connect error only once. Do not report the system error, + * as this comes again and again. */ - if ( statePtr->connectError != 0 ) { + if (statePtr->connectError != 0) { Tcl_DStringAppend(dsPtr, Tcl_ErrnoMsg(statePtr->connectError), -1); statePtr->connectError = 0; } - } else { - /* - * Report an eventual last error of the socket system + * Report an eventual last error of the socket system. */ int optlen; @@ -1286,24 +1328,30 @@ TcpGetOptionProc( DWORD err; /* - * Populater the err Variable with a possix error + * Populate the err variable with a POSIX error */ + optlen = sizeof(int); ret = getsockopt(sock, SOL_SOCKET, SO_ERROR, (char *)&err, &optlen); + /* - * The error was not returned directly but should be - * taken from WSA + * The error was not returned directly but should be taken + * from WSA. */ + if (ret == SOCKET_ERROR) { err = WSAGetLastError(); } + /* - * Return error message + * Return error message. */ + if (err) { TclWinConvertError(err); - Tcl_DStringAppend(dsPtr, Tcl_ErrnoMsg(Tcl_GetErrno()), -1); + Tcl_DStringAppend(dsPtr, Tcl_ErrnoMsg(Tcl_GetErrno()), + -1); } } } @@ -1312,14 +1360,14 @@ TcpGetOptionProc( if ((len > 1) && (optionName[1] == 'c') && (strncmp(optionName, "-connecting", len) == 0)) { - Tcl_DStringAppend(dsPtr, (statePtr->flags & TCP_ASYNC_PENDING) ? "1" : "0", -1); return TCL_OK; } - if (interp != NULL && Tcl_GetVar2(interp, SUPPRESS_RDNS_VAR, NULL, 0) != NULL) { + if (interp != NULL + && Tcl_GetVar2(interp, SUPPRESS_RDNS_VAR, NULL, 0) != NULL) { reverseDNS = NI_NUMERICHOST; } @@ -1328,20 +1376,23 @@ TcpGetOptionProc( address peername; socklen_t size = sizeof(peername); - if ( (statePtr->flags & TCP_ASYNC_PENDING) ) { + if (statePtr->flags & TCP_ASYNC_PENDING) { /* * In async connect output an empty string */ + if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-peername"); Tcl_DStringAppendElement(dsPtr, ""); } else { return TCL_OK; } - } else if ( getpeername(sock, (LPSOCKADDR) &(peername.sa), &size) == 0) { + } else if (getpeername(sock, (LPSOCKADDR) &(peername.sa), + &size) == 0) { /* * Peername fetch succeeded - output list */ + if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-peername"); Tcl_DStringStartSublist(dsPtr); @@ -1390,11 +1441,12 @@ TcpGetOptionProc( Tcl_DStringAppendElement(dsPtr, "-sockname"); Tcl_DStringStartSublist(dsPtr); } - if ( (statePtr->flags & TCP_ASYNC_PENDING ) ) { + if (statePtr->flags & TCP_ASYNC_PENDING) { /* * In async connect output an empty string */ - found = 1; + + found = 1; } else { for (fds = statePtr->sockets; fds != NULL; fds = fds->next) { sock = fds->fd; @@ -1408,9 +1460,11 @@ TcpGetOptionProc( Tcl_DStringAppendElement(dsPtr, host); /* - * We don't want to resolve INADDR_ANY and sin6addr_any; they - * can sometimes cause problems (and never have a name). + * We don't want to resolve INADDR_ANY and sin6addr_any; + * they can sometimes cause problems (and never have a + * name). */ + flags |= NI_NUMERICSERV; if (sockname.sa.sa_family == AF_INET) { if (sockname.sa4.sin_addr.s_addr == INADDR_ANY) { @@ -1494,7 +1548,8 @@ TcpGetOptionProc( return Tcl_BadChannelOption(interp, optionName, "connecting peername sockname keepalive nagle"); #else - return Tcl_BadChannelOption(interp, optionName, "connecting peername sockname"); + return Tcl_BadChannelOption(interp, optionName, + "connecting peername sockname"); #endif /*TCL_FEATURE_KEEPALIVE_NAGLE*/ } @@ -1536,10 +1591,10 @@ TcpWatchProc( if (!statePtr->acceptProc) { statePtr->watchEvents = 0; if (mask & TCL_READABLE) { - statePtr->watchEvents |= (FD_READ|FD_CLOSE); + SET_BITS(statePtr->watchEvents, FD_READ | FD_CLOSE); } if (mask & TCL_WRITABLE) { - statePtr->watchEvents |= (FD_WRITE|FD_CLOSE); + SET_BITS(statePtr->watchEvents, FD_WRITE | FD_CLOSE); } /* @@ -1630,13 +1685,13 @@ TcpConnect( TcpState *statePtr) { DWORD error; - /* - * We are started with async connect and the connect notification - * was not jet received - */ int async_connect = statePtr->flags & TCP_ASYNC_CONNECT; - /* We were called by the event procedure and continue our loop */ + /* We are started with async connect and the + * connect notification was not yet + * received. */ int async_callback = statePtr->flags & TCP_ASYNC_PENDING; + /* We were called by the event procedure and + * continue our loop. */ ThreadSpecificData *tsdPtr = TclThreadDataKeyGet(&dataKey); if (async_callback) { @@ -1644,11 +1699,10 @@ TcpConnect( } for (statePtr->addr = statePtr->addrlist; statePtr->addr != NULL; - statePtr->addr = statePtr->addr->ai_next) { - - for (statePtr->myaddr = statePtr->myaddrlist; statePtr->myaddr != NULL; - statePtr->myaddr = statePtr->myaddr->ai_next) { - + statePtr->addr = statePtr->addr->ai_next) { + for (statePtr->myaddr = statePtr->myaddrlist; + statePtr->myaddr != NULL; + statePtr->myaddr = statePtr->myaddr->ai_next) { /* * No need to try combinations of local and remote addresses * of different families. @@ -1662,25 +1716,37 @@ TcpConnect( * Close the socket if it is still open from the last unsuccessful * iteration. */ + if (statePtr->sockets->fd != INVALID_SOCKET) { closesocket(statePtr->sockets->fd); } - /* get statePtr lock */ + /* + * Get statePtr lock. + */ + WaitForSingleObject(tsdPtr->socketListLock, INFINITE); /* * Reset last error from last try */ + statePtr->notifierConnectError = 0; Tcl_SetErrno(0); - statePtr->sockets->fd = socket(statePtr->myaddr->ai_family, SOCK_STREAM, 0); + statePtr->sockets->fd = socket(statePtr->myaddr->ai_family, + SOCK_STREAM, 0); + + /* + * Free list lock. + */ - /* Free list lock */ SetEvent(tsdPtr->socketListLock); - /* continue on socket creation error */ + /* + * Continue on socket creation error. + */ + if (statePtr->sockets->fd == INVALID_SOCKET) { TclWinConvertError((DWORD) WSAGetLastError()); continue; @@ -1691,31 +1757,39 @@ TcpConnect( * processes by default. Turn off the inherit bit. */ - SetHandleInformation((HANDLE) statePtr->sockets->fd, HANDLE_FLAG_INHERIT, 0); + SetHandleInformation((HANDLE) statePtr->sockets->fd, + HANDLE_FLAG_INHERIT, 0); /* * Set kernel space buffering */ - TclSockMinimumBuffers((void *) statePtr->sockets->fd, TCP_BUFFER_SIZE); + TclSockMinimumBuffers((void *) statePtr->sockets->fd, + TCP_BUFFER_SIZE); /* * Try to bind to a local port. */ if (bind(statePtr->sockets->fd, statePtr->myaddr->ai_addr, - statePtr->myaddr->ai_addrlen) == SOCKET_ERROR) { + statePtr->myaddr->ai_addrlen) == SOCKET_ERROR) { TclWinConvertError((DWORD) WSAGetLastError()); continue; } + /* * For asyncroneous connect set the socket in nonblocking mode * and activate connect notification */ + if (async_connect) { TcpState *statePtr2; int in_socket_list = 0; - /* get statePtr lock */ + + /* + * Get statePtr lock. + */ + WaitForSingleObject(tsdPtr->socketListLock, INFINITE); /* @@ -1725,8 +1799,8 @@ TcpConnect( * It is set after this call by TcpThreadActionProc and is set * on a second round. * - * If not, we buffer my statePtr in the tsd memory so it is not - * lost by the event procedure + * If not, we buffer my statePtr in the tsd memory so it is + * not lost by the event procedure */ for (statePtr2 = tsdPtr->socketList; statePtr2 != NULL; @@ -1739,19 +1813,26 @@ TcpConnect( if (!in_socket_list) { tsdPtr->pendingTcpState = statePtr; } + /* * Set connect mask to connect events - * This is activated by a SOCKET_SELECT message to the notifier - * thread. + * + * This is activated by a SOCKET_SELECT message to the + * notifier thread. */ - statePtr->selectEvents |= FD_CONNECT; + + SET_BITS(statePtr->selectEvents, FD_CONNECT); /* - * Free list lock + * Free list lock. */ + SetEvent(tsdPtr->socketListLock); - /* activate accept notification */ + /* + * Activate accept notification. + */ + SendMessage(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM) SELECT, (LPARAM) statePtr); } @@ -1769,12 +1850,11 @@ TcpConnect( if (async_connect && error == WSAEWOULDBLOCK) { /* * Asynchroneous connect - */ - - /* + * * Remember that we jump back behind this next round */ - statePtr->flags |= TCP_ASYNC_PENDING; + + SET_BITS(statePtr->flags, TCP_ASYNC_PENDING); return TCL_OK; reenter: @@ -1784,21 +1864,39 @@ TcpConnect( * * Clear the reenter flag */ - statePtr->flags &= ~(TCP_ASYNC_PENDING); - /* get statePtr lock */ + + CLEAR_BITS(statePtr->flags, TCP_ASYNC_PENDING); + + /* + * Get statePtr lock. + */ + WaitForSingleObject(tsdPtr->socketListLock, INFINITE); - /* Get signaled connect error */ + + /* + * Get signaled connect error. + */ + TclWinConvertError((DWORD) statePtr->notifierConnectError); - /* Clear eventual connect flag */ - statePtr->selectEvents &= ~(FD_CONNECT); - /* Free list lock */ + + /* + * Clear eventual connect flag. + */ + + CLEAR_BITS(statePtr->selectEvents, FD_CONNECT); + + /* + * Free list lock. + */ + SetEvent(tsdPtr->socketListLock); } /* - * Clear the tsd socket list pointer if we did not wait for - * the FD_CONNECT asyncroneously + * Clear the tsd socket list pointer if we did not wait for the + * FD_CONNECT asynchronously. */ + tsdPtr->pendingTcpState = NULL; if (Tcl_GetErrno() == 0) { @@ -1807,7 +1905,7 @@ TcpConnect( } } -out: + out: /* * Socket connected or connection failed */ @@ -1818,13 +1916,13 @@ out: CLEAR_BITS(statePtr->flags, TCP_ASYNC_CONNECT); - if ( Tcl_GetErrno() == 0 ) { + if (Tcl_GetErrno() == 0) { /* * Succesfully connected - */ - /* + * * Set up the select mask for read/write events. */ + statePtr->selectEvents = FD_READ | FD_WRITE | FD_CLOSE; /* @@ -1837,30 +1935,52 @@ out: } else { /* * Connect failed - */ - - /* + * * For async connect schedule a writable event to report the fail. */ + if (async_callback) { /* * Set up the select mask for read/write events. */ + statePtr->selectEvents = FD_WRITE|FD_READ; - /* get statePtr lock */ + + /* + * Get statePtr lock. + */ + WaitForSingleObject(tsdPtr->socketListLock, INFINITE); - /* Signal ready readable and writable events */ - statePtr->readyEvents |= FD_WRITE | FD_READ; - /* Flag error to event routine */ - statePtr->flags |= TCP_ASYNC_FAILED; - /* Save connect error to be reported by 'fconfigure -error' */ + + /* + * Signal ready readable and writable events. + */ + + SET_BITS(statePtr->readyEvents, FD_WRITE | FD_READ); + + /* + * Flag error to event routine. + */ + + SET_BITS(statePtr->flags, TCP_ASYNC_FAILED); + + /* + * Save connect error to be reported by 'fconfigure -error'. + */ + statePtr->connectError = Tcl_GetErrno(); - /* Free list lock */ + + /* + * Free list lock. + */ + SetEvent(tsdPtr->socketListLock); } + /* * Error message on syncroneous connect */ + if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't open socket: %s", Tcl_PosixError(interp))); @@ -1873,7 +1993,7 @@ out: /* *---------------------------------------------------------------------- * - * Tcl_OpenTcpClient, TclOpenTcpClientEx -- + * Tcl_OpenTcpClient, Tcl_OpenTcpClientEx -- * * Opens a TCP client socket and creates a channel around it. * @@ -1903,11 +2023,11 @@ Tcl_OpenTcpClient( TclFormatInt(service, port); TclFormatInt(myservice, myport); - return TclOpenTcpClientEx(interp, service, host, myaddr, myservice, async!=0); + return Tcl_OpenTcpClientEx(interp, service, host, myaddr, myservice, async!=0); } Tcl_Channel -TclOpenTcpClientEx( +Tcl_OpenTcpClientEx( Tcl_Interp *interp, /* For error reporting; can be NULL. */ const char *service, /* Port number to open. */ const char *host, /* Host on which to open port. */ @@ -1957,7 +2077,7 @@ TclOpenTcpClientEx( statePtr->addrlist = addrlist; statePtr->myaddrlist = myaddrlist; if (flags&1) { - statePtr->flags |= TCP_ASYNC_CONNECT; + SET_BITS(statePtr->flags, TCP_ASYNC_CONNECT); } /* @@ -2027,7 +2147,8 @@ Tcl_MakeTcpClientChannel( */ statePtr->selectEvents = FD_READ | FD_CLOSE | FD_WRITE; - SendMessage(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM)SELECT, (LPARAM)statePtr); + SendMessage(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM)SELECT, + (LPARAM)statePtr); sprintf(channelName, SOCK_TEMPLATE, statePtr); statePtr->channel = Tcl_CreateChannel(&tcpChannelType, channelName, @@ -2059,6 +2180,8 @@ Tcl_OpenTcpServerEx( const char *service, /* Port number to open. */ const char *myHost, /* Name of local host. */ unsigned int flags, /* Flags. */ + int backlog, /* Length of OS listen backlog queue, or -1 + * for default. */ Tcl_TcpAcceptProc *acceptProc, /* Callback for accepting connections from new * clients. */ @@ -2097,7 +2220,8 @@ Tcl_OpenTcpServerEx( goto error; } - if (!TclCreateSocketAddress(interp, &addrlist, myHost, service, 1, &errorMsg)) { + if (!TclCreateSocketAddress(interp, &addrlist, myHost, service, 1, + &errorMsg)) { goto error; } @@ -2136,13 +2260,14 @@ Tcl_OpenTcpServerEx( } /* - * The SO_REUSEADDR option on Windows behaves like SO_REUSEPORT on unix - * systems. + * The SO_REUSEADDR option on Windows behaves like SO_REUSEPORT on + * unix systems. */ + if (flags & TCL_TCPSERVER_REUSEPORT) { optvalue = 1; (void) setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, - (char *) &optvalue, sizeof(optvalue)); + (char *) &optvalue, sizeof(optvalue)); } /* @@ -2153,8 +2278,8 @@ Tcl_OpenTcpServerEx( * place to look for bugs. */ - if (bind(sock, addrPtr->ai_addr, addrPtr->ai_addrlen) - == SOCKET_ERROR) { + if (bind(sock, addrPtr->ai_addr, + addrPtr->ai_addrlen) == SOCKET_ERROR) { TclWinConvertError((DWORD) WSAGetLastError()); closesocket(sock); continue; @@ -2179,7 +2304,10 @@ Tcl_OpenTcpServerEx( * different, and there may be differences between TCP/IP stacks). */ - if (listen(sock, SOMAXCONN) == SOCKET_ERROR) { + if (backlog < 0) { + backlog = SOMAXCONN; + } + if (listen(sock, backlog) == SOCKET_ERROR) { TclWinConvertError((DWORD) WSAGetLastError()); closesocket(sock); continue; @@ -2189,13 +2317,14 @@ Tcl_OpenTcpServerEx( /* * Add this socket to the global list of sockets. */ + statePtr = NewSocketInfo(sock); } else { - AddSocketInfoFd( statePtr, sock ); + AddSocketInfoFd(statePtr, sock); } } -error: + error: if (addrlist != NULL) { freeaddrinfo(addrlist); } @@ -2221,7 +2350,7 @@ error: ioctlsocket(sock, (long) FIONBIO, &flag); SendMessage(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM) SELECT, - (LPARAM) statePtr); + (LPARAM) statePtr); if (Tcl_SetChannelOption(interp, statePtr->channel, "-eofchar", "") == TCL_ERROR) { Tcl_Close(NULL, statePtr->channel); @@ -2583,9 +2712,8 @@ SocketCheckProc( statePtr = statePtr->nextPtr) { if ((statePtr->readyEvents & (statePtr->watchEvents | FD_CONNECT | FD_ACCEPT)) - && !(statePtr->flags & SOCKET_PENDING) - ) { - statePtr->flags |= SOCKET_PENDING; + && !(statePtr->flags & SOCKET_PENDING)) { + SET_BITS(statePtr->flags, SOCKET_PENDING); evPtr = ckalloc(sizeof(SocketEvent)); evPtr->header.proc = SocketEventProc; evPtr->socket = statePtr->sockets->fd; @@ -2660,29 +2788,26 @@ SocketEventProc( * Clear flag that (this) event is pending */ - statePtr->flags &= ~SOCKET_PENDING; + CLEAR_BITS(statePtr->flags, SOCKET_PENDING); /* * Continue async connect if pending and ready */ - if ( statePtr->readyEvents & FD_CONNECT ) { - if ( statePtr->flags & TCP_ASYNC_PENDING ) { - + if (statePtr->readyEvents & FD_CONNECT) { + if (statePtr->flags & TCP_ASYNC_PENDING) { /* * Do one step and save eventual connect error */ SetEvent(tsdPtr->socketListLock); WaitForConnect(statePtr,NULL); - } else { - /* * No async connect reenter pending. Just clear event. */ - statePtr->readyEvents &= ~(FD_CONNECT); + CLEAR_BITS(statePtr->readyEvents, FD_CONNECT); SetEvent(tsdPtr->socketListLock); } return 1; @@ -2691,20 +2816,23 @@ SocketEventProc( /* * Handle connection requests directly. */ + if (statePtr->readyEvents & FD_ACCEPT) { for (fds = statePtr->sockets; fds != NULL; fds = fds->next) { - /* - * Accept the incoming connection request. - */ - len = sizeof(address); + * Accept the incoming connection request. + */ + len = sizeof(address); newSocket = accept(fds->fd, &(addr.sa), &len); - /* On Tcl server sockets with multiple OS fds we loop over the fds trying - * an accept() on each, so we expect INVALID_SOCKET. There are also other - * network stack conditions that can result in FD_ACCEPT but a subsequent - * failure on accept() by the time we get around to it. + /* + * On Tcl server sockets with multiple OS fds we loop over the fds + * trying an accept() on each, so we expect INVALID_SOCKET. There + * are also other network stack conditions that can result in + * FD_ACCEPT but a subsequent failure on accept() by the time we + * get around to it. + * * Access to sockets (acceptEventCount, readyEvents) in socketList * is still protected by the lock (prevents reintroduction of * SF Tcl Bug 3056775. @@ -2716,35 +2844,40 @@ SocketEventProc( } /* - * It is possible that more than one FD_ACCEPT has been sent, so an extra - * count must be kept. Decrement the count, and reset the readyEvent bit - * if the count is no longer > 0. + * It is possible that more than one FD_ACCEPT has been sent, so + * an extra count must be kept. Decrement the count, and reset the + * readyEvent bit if the count is no longer > 0. */ + statePtr->acceptEventCount--; if (statePtr->acceptEventCount <= 0) { - statePtr->readyEvents &= ~(FD_ACCEPT); + CLEAR_BITS(statePtr->readyEvents, FD_ACCEPT); } SetEvent(tsdPtr->socketListLock); - /* Caution: TcpAccept() has the side-effect of evaluating the server - * accept script (via AcceptCallbackProc() in tclIOCmd.c), which can - * close the server socket and invalidate statePtr and fds. - * If TcpAccept() accepts a socket we must return immediately and let - * SocketCheckProc queue additional FD_ACCEPT events. + /* + * Caution: TcpAccept() has the side-effect of evaluating the + * server accept script (via AcceptCallbackProc() in tclIOCmd.c), + * which can close the server socket and invalidate statePtr and + * fds. If TcpAccept() accepts a socket we must return immediately + * and let SocketCheckProc queue additional FD_ACCEPT events. */ + TcpAccept(fds, newSocket, addr); return 1; } - /* Loop terminated with no sockets accepted; clear the ready mask so + /* + * Loop terminated with no sockets accepted; clear the ready mask so * we can detect the next connection request. Note that connection * requests are level triggered, so if there is a request already * pending, a new event will be generated. */ + statePtr->acceptEventCount = 0; - statePtr->readyEvents &= ~(FD_ACCEPT); + CLEAR_BITS(statePtr->readyEvents, FD_ACCEPT); SetEvent(tsdPtr->socketListLock); return 1; @@ -2773,16 +2906,15 @@ SocketEventProc( Tcl_Time blockTime = { 0, 0 }; Tcl_SetMaxBlockTime(&blockTime); - mask |= TCL_READABLE|TCL_WRITABLE; + SET_BITS(mask, TCL_READABLE | TCL_WRITABLE); } else if (events & FD_READ) { /* * Throw the readable event if an async connect failed. */ - if ( statePtr->flags & TCP_ASYNC_FAILED ) { - - mask |= TCL_READABLE; + if (statePtr->flags & TCP_ASYNC_FAILED) { + SET_BITS(mask, TCL_READABLE); } else { fd_set readFds; @@ -2805,9 +2937,9 @@ SocketEventProc( timeout.tv_sec = 0; if (select(0, &readFds, NULL, NULL, &timeout) != 0) { - mask |= TCL_READABLE; + SET_BITS(mask, TCL_READABLE); } else { - statePtr->readyEvents &= ~(FD_READ); + CLEAR_BITS(statePtr->readyEvents, FD_READ); SendMessage(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM) SELECT, (LPARAM) statePtr); } @@ -2819,7 +2951,7 @@ SocketEventProc( */ if (events & FD_WRITE) { - mask |= TCL_WRITABLE; + SET_BITS(mask, TCL_WRITABLE); } /* @@ -2856,13 +2988,19 @@ AddSocketInfoFd( { TcpFdList *fds = statePtr->sockets; - if ( fds == NULL ) { - /* Add the first FD */ + if (fds == NULL) { + /* + * Add the first FD. + */ + statePtr->sockets = ckalloc(sizeof(TcpFdList)); fds = statePtr->sockets; } else { - /* Find end of list and append FD */ - while ( fds->next != NULL ) { + /* + * Find end of list and append FD. + */ + + while (fds->next != NULL) { fds = fds->next; } @@ -2870,7 +3008,10 @@ AddSocketInfoFd( fds = fds->next; } - /* Populate new FD */ + /* + * Populate new FD. + */ + fds->fd = socket; fds->statePtr = statePtr; fds->next = NULL; @@ -2940,6 +3081,7 @@ WaitForSocketEvent( int result = 1; int oldMode; ThreadSpecificData *tsdPtr = TclThreadDataKeyGet(&dataKey); + /* * Be sure to disable event servicing so we are truly modal. */ @@ -2958,21 +3100,36 @@ WaitForSocketEvent( while (1) { int event_found; - /* get statePtr lock */ + /* + * Get statePtr lock. + */ + WaitForSingleObject(tsdPtr->socketListLock, INFINITE); - /* Check if event occured */ + /* + * Check if event occured. + */ + event_found = (statePtr->readyEvents & events); - /* Free list lock */ + /* + * Free list lock. + */ + SetEvent(tsdPtr->socketListLock); - /* exit loop if event occured */ + /* + * Exit loop if event occured. + */ + if (event_found) { break; } - /* Exit loop if event did not occur but this is a non-blocking channel */ + /* + * Exit loop if event did not occur but this is a non-blocking channel + */ + if (statePtr->flags & TCP_NONBLOCKING) { *errorCodePtr = EWOULDBLOCK; result = 0; @@ -3129,34 +3286,34 @@ SocketProc( for (statePtr = tsdPtr->socketList; statePtr != NULL; statePtr = statePtr->nextPtr) { - if ( FindFDInList(statePtr,socket) ) { + if (FindFDInList(statePtr, socket)) { info_found = 1; break; } } + /* - * Check if there is a pending info structure not jet in the - * list + * Check if there is a pending info structure not jet in the list. */ - if ( !info_found + + if (!info_found && tsdPtr->pendingTcpState != NULL - && FindFDInList(tsdPtr->pendingTcpState,socket) ) { + && FindFDInList(tsdPtr->pendingTcpState, socket)) { statePtr = tsdPtr->pendingTcpState; info_found = 1; } if (info_found) { - /* * Update the socket state. * * A count of FD_ACCEPTS is stored, so if an FD_CLOSE event - * happens, then clear the FD_ACCEPT count. Otherwise, - * increment the count if the current event is an FD_ACCEPT. + * happens, then clear the FD_ACCEPT count. Otherwise, increment + * the count if the current event is an FD_ACCEPT. */ if (event & FD_CLOSE) { statePtr->acceptEventCount = 0; - statePtr->readyEvents &= ~(FD_WRITE|FD_ACCEPT); + CLEAR_BITS(statePtr->readyEvents, FD_WRITE | FD_ACCEPT); } else if (event & FD_ACCEPT) { statePtr->acceptEventCount++; } @@ -3166,18 +3323,22 @@ SocketProc( * Remember any error that occurred so we can report * connection failures. */ + if (error != ERROR_SUCCESS) { statePtr->notifierConnectError = error; } } + /* * Inform main thread about signaled events */ - statePtr->readyEvents |= event; + + SET_BITS(statePtr->readyEvents, event); /* * Wake up the Main Thread. */ + SetEvent(tsdPtr->readyEvent); Tcl_ThreadAlert(tsdPtr->threadId); } @@ -3258,6 +3419,7 @@ FindFDInList( *---------------------------------------------------------------------- */ +#ifndef TCL_NO_DEPRECATED #undef TclWinGetSockOpt int TclWinGetSockOpt( @@ -3297,6 +3459,7 @@ TclWinGetServByName( { return getservbyname(name, proto); } +#endif /* TCL_NO_DEPRECATED */ /* *---------------------------------------------------------------------- diff --git a/win/tclWinTime.c b/win/tclWinTime.c index 81d9458..18702e7 100644 --- a/win/tclWinTime.c +++ b/win/tclWinTime.c @@ -27,6 +27,7 @@ * month, where index 1 is January. */ +#ifndef TCL_NO_DEPRECATED static const int normalDays[] = { -1, 30, 58, 89, 119, 150, 180, 211, 242, 272, 303, 333, 364 }; @@ -40,6 +41,7 @@ typedef struct { struct tm tm; /* time information */ } ThreadSpecificData; static Tcl_ThreadDataKey dataKey; +#endif /* TCL_NO_DEPRECATED */ /* * Data for managing high-resolution timers. @@ -113,7 +115,9 @@ static TimeInfo timeInfo = { * Declarations for functions defined later in this file. */ +#ifndef TCL_NO_DEPRECATED static struct tm * ComputeGMT(const time_t *tp); +#endif /* TCL_NO_DEPRECATED */ static void StopCalibration(ClientData clientData); static DWORD WINAPI CalibrationThread(LPVOID arg); static void UpdateTimeEachSecond(void); @@ -522,6 +526,7 @@ StopCalibration( *---------------------------------------------------------------------- */ +#ifndef TCL_NO_DEPRECATED struct tm * TclpGetDate( const time_t *t, @@ -724,6 +729,7 @@ ComputeGMT( return tmPtr; } +#endif /* TCL_NO_DEPRECATED */ /* *---------------------------------------------------------------------- @@ -1068,6 +1074,7 @@ AccumulateSample( *---------------------------------------------------------------------- */ +#ifndef TCL_NO_DEPRECATED struct tm * TclpGmtime( const time_t *timePtr) /* Pointer to the number of seconds since the @@ -1112,6 +1119,7 @@ TclpLocaltime( return localtime(timePtr); } +#endif /* TCL_NO_DEPRECATED */ /* *---------------------------------------------------------------------- |