Tcl Source Code

Artifact [7b381377e3]
Login

Artifact 7b381377e30b11a4599a34e0950c1ee9a13e46d4:

Attachment "tcl-8.3.5.patch" to ticket [622183ffff] added by kirben 2002-10-12 09:17:06.
diff -bur otcl-8.3.5/ChangeLog tcl-8.3.5/ChangeLog
--- otcl-8.3.5/ChangeLog	2002-10-11 21:50:00.000000000 +1000
+++ tcl-8.3.5/ChangeLog	2002-10-12 12:07:46.000000000 +1000
@@ -1,3 +1,77 @@
+2002-10-11  Mumit Khan <[email protected]>
+
+	* win/configure.in (SEH test): Define to be 1 instead of empty value.
+	(EXCEPTION_DISPOSITION): Add test.
+	* win/configure: Regenerate.
+
+	Adapt Mo DeJong's Tcl 8.4 CVS non-SEH compiler support patch for 
+	Tcl 8.3.4 branch.
+
+	* win/configure: Regen.
+	* win/configure.in: Add configure time test for SEH
+	support in the compiler.
+	* win/tclWin32Dll.c (ESP, EBP, TclpCheckStackSpace,
+	_except_checkstackspace_handler):
+	* win/tclWinChan.c (ESP, EBP, Tcl_MakeFileChannel,
+	_except_makefilechannel_handler):
+	* win/tclWinFCmd.c (ESP, EBP, DoRenameFile,
+	_except_dorenamefile_handler,
+	DoCopyFile, _except_docopyfile_handler):
+	Implement SEH support under gcc using inline asm.
+	Tcl and Tk should now compile with Mingw 1.1. [Patch 525746]
+
+	* win/tclWinFCmd.c (DoRenameFile, DoCopyFile): Handle
+	an SEH exception with EXCEPTION_EXECUTE_HANDLER instead
+	of restarting the faulting instruction with
+	EXCEPTION_CONTINUE_EXECUTION. Bug 466102 provides an
+	example of how restarting could send Tcl into an
+	infinite loop. [Patch 525746]
+
+2002-10-11  Mumit Khan  <[email protected]>
+
+	* win/tclWinFile.c (TclpMatchFilesTypes): Move the conversion to
+	POSIX to native format from here to ...
+	* generic/tclFileName.c (TclDoGlob): Here.
+
+2002-10-11  Mumit Khan  <[email protected]>
+
+	Added basic Cygwin support.
+
+	* win/tcl.m4 (SC_PATH_TCLCONFIG): Support one-tree build.
+	(SC_PATH_TKCONFIG): Likewise.
+	(SC_PROG_TCLSH): Likewise.
+	(SC_ENABLE_GCC): Choose gcc by default.
+	(SC_CONFIG_CFLAGS): Assume real Cygwin port and remove -mno-cygwin 
+	flags.  Add -mwin32 to extra_cflags and extra_ldflags.
+	Remove ``-e _WinMain@16'' from LDFLAGS_WINDOW.
+	* win/configure.in (TCL_*_LIB_SUFFIX): Use ${VER} instead of 
+	\${NODOT_VERSION}.
+	(TCL_LIB_FLAG, TCL_BUILD_LIB_SPEC, TCL_LIB_SPEC, SHLIB_SUFFIX, 
+	TCL_PACKAGE_PATH): Add missing variable decls.
+	* win/configure: Regenerate.
+
+	* generic/tclEnv.c (__cygwin_environ): Declare.
+	(TclCygwin32Putenv): New function.
+	(putenv): Use. 
+	* generic/tclFileName.c (Tcl_TranslateFileName): Convert POSIX 
+	to native format.
+	* win/tclWinFile.c (TclpMatchFilesTypes): Likewise.
+	* generic/tclPlatDecls.h (tchar.h): Do not include on Cygwin.
+	* win/tclWinPort.h (environ, putenv, timezone): Define for Cygwin.
+	(TclpSysAlloc, TclpSysFree, TclpSysRealloc): Use C runtime rather 
+	than Windows API.
+	* win/tclWin32Dll.c (TclpCheckStackSpace): Disable Win32 SEH for GCC.
+	* win/tclWinChan.c (Tcl_MakeFileChannel): Likewise.
+	* win/tclWinConsole.c (dos.h): Do not include on Cygwin.
+	* win/tclWinPipe.c (dos.h): Likewise.
+	* win/tclWinSerial.c (dos.h): Likewise.
+	* win/tclWinThrd.c (dos.h): Likewise.
+	(Tcl_CreateThread): Use Win32 instead of MSVCRT API on Cygwin.
+	(TclpThreadExit): Likewise.
+	* win/tclWinFCmd.c (DoRenameFile): Likewise.
+	(DoCopyFile): Likewise.
+	* win/tclWinFile.c (TclpReadLink): New function.
+
 2002-10-10  Daniel Steffen  <[email protected]>
 
 	* mac/tclMacFCmd.c: removed GenerateUniqueName(), use equivalent
diff -bur otcl-8.3.5/generic/tclEnv.c tcl-8.3.5/generic/tclEnv.c
--- otcl-8.3.5/generic/tclEnv.c	2002-10-11 21:50:04.000000000 +1000
+++ tcl-8.3.5/generic/tclEnv.c	2002-10-12 11:56:50.000000000 +1000
@@ -20,6 +20,23 @@
 
 TCL_DECLARE_MUTEX(envMutex)	/* To serialize access to environ */
 
+/* CYGNUS LOCAL */
+#if defined(__CYGWIN__) && defined(__WIN32__)
+
+/* Under cygwin, the environment is imported from the cygwin DLL.  */
+
+__declspec(dllimport) extern char **__cygwin_environ;
+
+#define environ (__cygwin_environ)
+
+/* We need to use a special putenv function to handle PATH.  */
+#ifndef USE_PUTENV
+#define USE_PUTENV
+#endif
+#define putenv TclCygwin32Putenv
+#endif
+/* END CYGNUS LOCAL */
+
 static int cacheSize = 0;	/* Number of env strings in environCache. */
 static char **environCache = NULL;
 				/* Array containing all of the environment
@@ -54,6 +71,11 @@
 			    CONST char *value));
 void			TclUnsetEnv _ANSI_ARGS_((CONST char *name));
 
+/* CYGNUS LOCAL */
+#if defined (__CYGWIN__) && defined(__WIN32__)
+static void		TclCygwin32Putenv _ANSI_ARGS_((CONST char *string));
+#endif
+/* END CYGNUS LOCAL */
 
 /*
  *----------------------------------------------------------------------
@@ -683,3 +705,88 @@
 #endif
     }
 }
+
+/* CYGNUS LOCAL */
+#if defined(__CYGWIN__) && defined(__WIN32__)
+
+#include "windows.h"
+
+/* When using cygwin, when an environment variable changes, we need
+   to synch with both the cygwin environment (in case the
+   application C code calls fork) and the Windows environment (in case
+   the application TCL code calls exec, which calls the Windows
+   CreateProcess function).  */
+
+static void
+TclCygwin32Putenv(str)
+     const char *str;
+{
+  char *name, *value;
+
+  /* Get the name and value, so that we can change the environment
+     variable for Windows.  */
+  name = (char *) alloca (strlen (str) + 1);
+  strcpy (name, str);
+  for (value = name; *value != '=' && *value != '\0'; ++value)
+    ;
+  if (*value == '\0')
+    {
+      /* Can't happen.  */
+      return;
+    }
+  *value = '\0';
+  ++value;
+  if (*value == '\0')
+    value = NULL;
+
+  /* Set the cygwin environment variable.  */
+#undef putenv
+  if (value == NULL)
+    unsetenv (name);
+  else
+    putenv(str);
+
+  /* Before changing the environment variable in Windows, if this is
+     PATH, we need to convert the value back to a Windows style path.
+
+     FIXME: The calling program may now it is running under windows,
+     and may have set the path to a Windows path, or, worse, appended
+     or prepended a Windows path to PATH.  */
+  if (strcmp (name, "PATH") != 0)
+    {
+      /* If this is Path, eliminate any PATH variable, to prevent any
+         confusion.  */
+      if (strcmp (name, "Path") == 0)
+	{
+	  SetEnvironmentVariable ("PATH", (char *) NULL);
+	  unsetenv ("PATH");
+	}
+
+      SetEnvironmentVariable (name, value);
+    }
+  else
+    {
+      char *buf;
+
+      /* Eliminate any Path variable, to prevent any confusion.  */
+      SetEnvironmentVariable ("Path", (char *) NULL);
+      unsetenv ("Path");
+
+      if (value == NULL)
+	buf = NULL;
+      else
+	{
+	  int size;
+
+	  size = cygwin_posix_to_win32_path_list_buf_size (value);
+	  buf = (char *) alloca (size + 1);
+	  cygwin_posix_to_win32_path_list (value, buf);
+	}
+
+      SetEnvironmentVariable (name, buf);
+    }
+}
+
+#endif /* __CYGWIN__ */
+/* END CYGNUS LOCAL */
+
diff -bur otcl-8.3.5/generic/tclFileName.c tcl-8.3.5/generic/tclFileName.c
--- otcl-8.3.5/generic/tclFileName.c	2002-10-11 21:50:04.000000000 +1000
+++ tcl-8.3.5/generic/tclFileName.c	2002-10-12 11:57:04.000000000 +1000
@@ -1011,6 +1011,10 @@
 				 * with name after tilde substitution. */
 {
     register char *p;
+#ifdef __CYGWIN__
+    extern int cygwin_conv_to_win32_path _ANSI_ARGS_((CONST char *, char *));
+    char winbuf[MAX_PATH];
+#endif /* __CYGWIN__ */
 
     /*
      * Handle tilde substitutions, if needed.
@@ -1049,6 +1053,17 @@
 	Tcl_JoinPath(1, (char **) &name, bufferPtr);
     }
 
+#ifdef __CYGWIN__
+    /* In the Cygwin world, call conv_to_win32_path in order to use
+       the mount table to translate the file name into something
+       Windows will understand.  Take care when converting empty strings! */
+    if (Tcl_DStringLength(bufferPtr)) {
+      cygwin_conv_to_win32_path(Tcl_DStringValue(bufferPtr), winbuf);
+      Tcl_DStringFree(bufferPtr);
+      Tcl_DStringAppend(bufferPtr, winbuf, -1);
+    }
+#endif /* __CYGWIN__ */
+
     /*
      * Convert forward slashes to backslashes in Windows paths because
      * some system interfaces don't accept forward slashes.
@@ -1908,6 +1923,23 @@
 	     * this is the first absolute element, or a later relative
 	     * element.  Add an extra slash if this is a UNC path.
 	     */
+#ifdef __CYGWIN__
+	    {
+
+	    extern int cygwin_conv_to_win32_path 
+	    	_ANSI_ARGS_((CONST char *, char *));
+	    char winbuf[MAX_PATH];
+
+	    /* In the Cygwin world, call conv_to_win32_path in order to use
+	       the mount table to translate the file name into something
+	       Windows will understand. */
+	    cygwin_conv_to_win32_path(Tcl_DStringValue(headPtr), winbuf);
+	    Tcl_DStringFree(headPtr);
+	    Tcl_DStringAppend(headPtr, winbuf, -1);
+
+	    }
+#endif /* __CYGWIN__ */
+
 
 	    if (*name == ':') {
 		Tcl_DStringAppend(headPtr, ":", 1);
diff -bur otcl-8.3.5/generic/tclPlatDecls.h tcl-8.3.5/generic/tclPlatDecls.h
--- otcl-8.3.5/generic/tclPlatDecls.h	2002-10-11 21:50:06.000000000 +1000
+++ tcl-8.3.5/generic/tclPlatDecls.h	2002-10-12 11:57:12.000000000 +1000
@@ -17,7 +17,7 @@
  *  of the core are matching against your project build for these
  *  public functions.  BE AWARE.
  */
-#if defined(__WIN32__) && !defined(_INC_TCHAR)
+#if (defined(__WIN32__) && !defined(__CYGWIN__)) && !defined(_INC_TCHAR)
 #include <tchar.h>
 #endif
 
diff -bur otcl-8.3.5/win/configure.in tcl-8.3.5/win/configure.in
--- otcl-8.3.5/win/configure.in	2002-10-11 21:50:18.000000000 +1000
+++ tcl-8.3.5/win/configure.in	2002-10-12 11:59:48.000000000 +1000
@@ -61,6 +61,57 @@
 
 AC_CYGWIN
 
+AC_CACHE_CHECK(for SEH support in compiler,
+    tcl_cv_seh,
+AC_TRY_RUN([
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef WIN32_LEAN_AND_MEAN
+
+int main(int argc, char** argv) {
+    int a, b = 0;
+    __try {
+        a = 666 / b;
+    }
+    __except (EXCEPTION_EXECUTE_HANDLER) {
+        return 0;
+    }
+    return 1;
+}
+],
+        tcl_cv_seh=yes,
+        tcl_cv_seh=no,
+        tcl_cv_seh=no)
+)
+if test "$tcl_cv_seh" = "no" ; then
+    AC_DEFINE(HAVE_NO_SEH,1,
+            [Defined when mingw does not support SEH])
+fi
+
+#
+# Check to see if the excpt.h include file provided contains the
+# definition for EXCEPTION_DISPOSITION; if not, which is the case
+# with Cygwin's version as of 2002-04-10, define it to be int, 
+# sufficient for getting the current code to work.
+#
+AC_CACHE_CHECK(for EXCEPTION_DISPOSITION support in include files,
+    tcl_cv_eh_disposition,
+AC_TRY_COMPILE([
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef WIN32_LEAN_AND_MEAN
+],
+[
+  EXCEPTION_DISPOSITION x;
+],
+        tcl_cv_eh_disposition=yes,
+        tcl_cv_eh_disposition=no)
+)
+if test "$tcl_cv_eh_disposition" = "no" ; then
+    AC_DEFINE(EXCEPTION_DISPOSITION, int,
+            [Defined when cygwin/mingw does not support EXCEPTION DISPOSITION])
+fi
+
 #--------------------------------------------------------------------
 # Determines the correct binary file extension (.o, .obj, .exe etc.)
 #--------------------------------------------------------------------
@@ -117,19 +168,18 @@
 # Perform final evaluations of variables with possible substitutions.
 #--------------------------------------------------------------------
 
-TCL_SHARED_LIB_SUFFIX="\${NODOT_VERSION}${DLLSUFFIX}"
-TCL_UNSHARED_LIB_SUFFIX="\${NODOT_VERSION}${LIBSUFFIX}"
-TCL_EXPORT_FILE_SUFFIX="\${NODOT_VERSION}${LIBSUFFIX}"
+TCL_SHARED_LIB_SUFFIX="${VER}${DLLSUFFIX}"
+TCL_UNSHARED_LIB_SUFFIX="${VER}${LIBSUFFIX}"
+TCL_EXPORT_FILE_SUFFIX="${VER}${LIBSUFFIX}"
 
 eval "TCL_SRC_DIR=\"`cd $srcdir/..; pwd`\""
 
 eval "TCL_DLL_FILE=tcl${VER}${DLLSUFFIX}"
 
 eval "TCL_LIB_FILE=${LIBPREFIX}tcl$VER${LIBSUFFIX}"
-# FIMXE: These variables decls are missing
-#TCL_LIB_FLAG
-#TCL_BUILD_LIB_SPEC
-#TCL_LIB_SPEC
+eval "TCL_LIB_FLAG=-ltcl${VER}${TCL_DBGX}"
+eval "TCL_BUILD_LIB_SPEC=\"-L`pwd` ${TCL_LIB_FLAG}\""
+eval "TCL_LIB_SPEC=\"-L${exec_prefix}/lib ${TCL_LIB_FLAG}\""
 
 eval "TCL_STUB_LIB_FILE=\"${LIBPREFIX}tclstub${VER}${LIBSUFFIX}\""
 eval "TCL_STUB_LIB_FLAG=\"-ltclstub${VER}${TCL_DBGX}\""
@@ -142,6 +192,7 @@
 eval "LIBPREFIX=${LIBPREFIX}"
 eval "LIBSUFFIX=${LIBSUFFIX}"
 eval "EXESUFFIX=${EXESUFFIX}"
+eval "SHLIB_SUFFIX=${DLLSUFFIX}"
 
 CFG_TCL_SHARED_LIB_SUFFIX=${TCL_SHARED_LIB_SUFFIX}
 CFG_TCL_UNSHARED_LIB_SUFFIX=${TCL_UNSHARED_LIB_SUFFIX}
@@ -166,6 +217,19 @@
     fi
 fi
 
+#--------------------------------------------------------------------
+#	The statements below define the symbol TCL_PACKAGE_PATH, which
+#	gives a list of directories that may contain packages.  The list
+#	consists of one directory for machine-dependent binaries and
+#	another for platform-independent scripts.
+#--------------------------------------------------------------------
+
+if test "$prefix" != "$exec_prefix"; then
+    TCL_PACKAGE_PATH="${exec_prefix}/lib ${prefix}/lib"
+else
+    TCL_PACKAGE_PATH="${prefix}/lib"
+fi
+
 AC_SUBST(TCL_VERSION)
 AC_SUBST(TCL_MAJOR_VERSION)
 AC_SUBST(TCL_MINOR_VERSION)
diff -bur otcl-8.3.5/win/tcl.m4 tcl-8.3.5/win/tcl.m4
--- otcl-8.3.5/win/tcl.m4	2002-10-11 21:50:18.000000000 +1000
+++ tcl-8.3.5/win/tcl.m4	2002-10-12 11:59:54.000000000 +1000
@@ -22,8 +22,10 @@
 
     if test -d ../../tcl8.3$1/win;  then
 	TCL_BIN_DIR_DEFAULT=../../tcl8.3$1/win
-    else
+    elif test -d ../../tcl8.3/win;  then
 	TCL_BIN_DIR_DEFAULT=../../tcl8.3/win
+    else
+	TCL_BIN_DIR_DEFAULT=../../tcl/win
     fi
     
     AC_ARG_WITH(tcl, [  --with-tcl=DIR          use Tcl 8.3 binaries from DIR],
@@ -60,8 +62,10 @@
 
     if test -d ../../tk8.3$1/win;  then
 	TK_BIN_DIR_DEFAULT=../../tk8.3$1/win
-    else
+    elif test -d ../../tk8.3/win;  then
 	TK_BIN_DIR_DEFAULT=../../tk8.3/win
+    else
+	TK_BIN_DIR_DEFAULT=../../tk/win
     fi
     
     AC_ARG_WITH(tk, [  --with-tk=DIR          use Tk 8.3 binaries from DIR],
@@ -173,7 +177,7 @@
 
 AC_DEFUN(SC_ENABLE_GCC, [
     AC_ARG_ENABLE(gcc, [  --enable-gcc            allow use of gcc if available [--disable-gcc]],
-	[ok=$enableval], [ok=no])
+	[ok=$enableval], [ok=yes])
     if test "$ok" = "yes"; then
 	# Quick hack to simulate a real cross check
 	# The right way to do this is to use AC_CHECK_TOOL
@@ -449,12 +453,30 @@
 	MAKE_EXE="\${CC} -o \[$]@"
 	LIBPREFIX="lib"
 
+	#if test "$ac_cv_cygwin" = "yes"; then
+	#    extra_cflags="-mno-cygwin"
+	#    extra_ldflags="-mno-cygwin"
+	#else
+	#    extra_cflags=""
+	#    extra_ldflags=""
+	#fi
+
 	if test "$ac_cv_cygwin" = "yes"; then
-	    extra_cflags="-mno-cygwin"
-	    extra_ldflags="-mno-cygwin"
+	  touch ac$$.c
+	  if ${CC} -c -mwin32 ac$$.c >/dev/null 2>&1; then
+	    case "$extra_cflags" in
+	      *-mwin32*) ;;
+	      *) extra_cflags="-mwin32 $extra_cflags" ;;
+	    esac
+	    case "$extra_ldflags" in
+	      *-mwin32*) ;;
+	      *) extra_ldflags="-mwin32 $extra_ldflags" ;;
+	    esac
+	  fi
+	  rm -f ac$$.o ac$$.c
 	else
-	    extra_cflags=""
-	    extra_ldflags=""
+	  extra_cflags=''
+	  extra_ldflags=''
 	fi
 
 	if test "${SHARED_BUILD}" = "0" ; then
@@ -507,14 +529,19 @@
 	# Specify linker flags depending on the type of app being 
 	# built -- Console vs. Window.
 	#
+	# ORIGINAL COMMENT:
 	# We need to pass -e _WinMain@16 so that ld will use
 	# WinMain() instead of main() as the entry point. We can't
 	# use autoconf to check for this case since it would need
 	# to run an executable and that does not work when
 	# cross compiling. Remove this -e workaround once we
 	# require a gcc that does not have this bug.
+	#
+	# MK NOTE: Tk should use a different mechanism. This causes 
+	# interesting problems, such as wish dying at startup.
 	LDFLAGS_CONSOLE="-mconsole ${extra_ldflags}"
-	LDFLAGS_WINDOW="-mwindows -e _WinMain@16 ${extra_ldflags}"
+	#LDFLAGS_WINDOW="-mwindows -e _WinMain@16 ${extra_ldflags}"
+	LDFLAGS_WINDOW="-mwindows ${extra_ldflags}"
     else
 	if test "${SHARED_BUILD}" = "0" ; then
 	    # static
@@ -688,7 +715,12 @@
     ])
 
     if test -f "$ac_cv_path_tclsh" ; then
-	TCLSH_PROG=$ac_cv_path_tclsh
+	TCLSH_PROG="$ac_cv_path_tclsh"
+	AC_MSG_RESULT($TCLSH_PROG)
+    elif test -f "$TCL_BIN_DIR/tclConfig.sh" ; then
+        # One-tree build.
+	ac_cv_path_tclsh="$TCL_BIN_DIR/tclsh"
+	TCLSH_PROG="$ac_cv_path_tclsh"
 	AC_MSG_RESULT($TCLSH_PROG)
     else
 	AC_MSG_ERROR(No tclsh found in PATH:  $search_path)
diff -bur otcl-8.3.5/win/tclWin32Dll.c tcl-8.3.5/win/tclWin32Dll.c
--- otcl-8.3.5/win/tclWin32Dll.c	2002-10-11 21:50:18.000000000 +1000
+++ tcl-8.3.5/win/tclWin32Dll.c	2002-10-12 12:00:08.000000000 +1000
@@ -37,6 +37,11 @@
 static HINSTANCE hInstance;	/* HINSTANCE of this DLL. */
 static int platformId;		/* Running under NT, or 95/98? */
 
+#ifdef HAVE_NO_SEH
+static void *ESP;
+static void *EBP;
+#endif /* HAVE_NO_SEH */
+
 /*
  * The following function tables are used to dispatch to either the
  * wide-character or multi-byte versions of the operating system calls,
@@ -338,6 +343,8 @@
 int
 TclpCheckStackSpace()
 {
+    int retval = 0;
+
     /*
      * We can recurse only if there is at least TCL_WIN_STACK_THRESHOLD
      * bytes of stack space left.  alloca() is cheap on windows; basically
@@ -345,14 +352,56 @@
      * exception if the stack pointer is set below the bottom of the stack.
      */
 
+#ifdef HAVE_NO_SEH
+    __asm__ __volatile__ (
+            "movl  %esp, _ESP" "\n\t"
+            "movl  %ebp, _EBP");
+
+    __asm__ __volatile__ (
+            "pushl $__except_checkstackspace_handler" "\n\t"
+            "pushl %fs:0" "\n\t"
+            "mov   %esp, %fs:0");
+#else
     __try {
+#endif /* HAVE_NO_SEH */
 	alloca(TCL_WIN_STACK_THRESHOLD);
-	return 1;
-    } __except (1) {}
+	retval = 1;
+#ifdef HAVE_NO_SEH
+    __asm__ __volatile__ (
+            "jmp   checkstackspace_pop" "\n"
+            "checkstackspace_reentry:" "\n\t"
+            "movl  _ESP, %esp" "\n\t"
+            "movl  _EBP, %ebp");
+
+    __asm__ __volatile__ (
+            "checkstackspace_pop:" "\n\t"
+            "mov   (%esp), %eax" "\n\t"
+            "mov   %eax, %fs:0" "\n\t"
+            "add   $8, %esp");
+#else
+    } __except (EXCEPTION_EXECUTE_HANDLER) {}
+#endif /* HAVE_NO_SEH */
 
-    return 0;
+    /*
+     * Avoid using control flow statements in the SEH guarded block!
+     */
+    return retval;
 }
-
+#ifdef HAVE_NO_SEH
+static
+__attribute__ ((cdecl))
+EXCEPTION_DISPOSITION
+_except_checkstackspace_handler(
+    struct _EXCEPTION_RECORD *ExceptionRecord,
+    void *EstablisherFrame,
+    struct _CONTEXT *ContextRecord,
+    void *DispatcherContext)
+{
+    __asm__ __volatile__ (
+            "jmp checkstackspace_reentry");
+    return 0; /* Function does not return */
+}
+#endif /* HAVE_NO_SEH */
 
 /*
  *----------------------------------------------------------------------
diff -bur otcl-8.3.5/win/tclWinChan.c tcl-8.3.5/win/tclWinChan.c
--- otcl-8.3.5/win/tclWinChan.c	2002-10-11 21:50:18.000000000 +1000
+++ tcl-8.3.5/win/tclWinChan.c	2002-10-12 12:00:14.000000000 +1000
@@ -118,6 +118,11 @@
     NULL,			/* handler proc. */
 };
 
+#ifdef HAVE_NO_SEH
+static void *ESP;
+static void *EBP;
+#endif /* HAVE_NO_SEH */
+
 
 /*
  *----------------------------------------------------------------------
@@ -969,8 +974,39 @@
 	 * of this duped handle which might throw EXCEPTION_INVALID_HANDLE.
 	 */
 
+#ifdef HAVE_NO_SEH
+        __asm__ __volatile__ (
+                "movl  %esp, _ESP" "\n\t"
+                "movl  %ebp, _EBP");
+
+        __asm__ __volatile__ (
+                "pushl $__except_makefilechannel_handler" "\n\t"
+                "pushl %fs:0" "\n\t"
+                "mov   %esp, %fs:0");
+
+        result = 0;
+#else
 	__try {
+#endif /* HAVE_NO_SEH */
 	    CloseHandle(dupedHandle);
+#ifdef HAVE_NO_SEH
+        __asm__ __volatile__ (
+                "jmp   makefilechannel_pop" "\n"
+                "makefilechannel_reentry:" "\n\t"
+                "movl  _ESP, %esp" "\n\t"
+                "movl  _EBP, %ebp");
+
+        result = 1;  /* True when exception was raised */
+
+        __asm__ __volatile__ (
+                "makefilechannel_pop:" "\n\t"
+                "mov   (%esp), %eax" "\n\t"
+                "mov   %eax, %fs:0" "\n\t"
+                "add   $8, %esp");
+
+        if (result)
+            return NULL;
+#else
 	}
 	__except (EXCEPTION_EXECUTE_HANDLER) {
 	    /*
@@ -980,6 +1016,7 @@
 
 	    return NULL;
 	}
+#endif /* HAVE_NO_SEH */
 
 	/* Fall through, the handle is valid. */
 
@@ -993,6 +1030,21 @@
 
     return channel;
 }
+#ifdef HAVE_NO_SEH
+static
+__attribute__ ((cdecl))
+EXCEPTION_DISPOSITION
+_except_makefilechannel_handler(
+    struct _EXCEPTION_RECORD *ExceptionRecord,
+    void *EstablisherFrame,
+    struct _CONTEXT *ContextRecord,
+    void *DispatcherContext)
+{
+    __asm__ __volatile__ (
+            "jmp makefilechannel_reentry");
+    return 0; /* Function does not return */
+}
+#endif
 
 /*
  *----------------------------------------------------------------------
diff -bur otcl-8.3.5/win/tclWinConsole.c tcl-8.3.5/win/tclWinConsole.c
--- otcl-8.3.5/win/tclWinConsole.c	2002-10-11 21:50:18.000000000 +1000
+++ tcl-8.3.5/win/tclWinConsole.c	2002-10-12 12:03:54.000000000 +1000
@@ -14,7 +14,9 @@
 
 #include "tclWinInt.h"
 
+#ifndef __CYGWIN__
 #include <dos.h>
+#endif
 #include <fcntl.h>
 #include <io.h>
 #include <sys/stat.h>
diff -bur otcl-8.3.5/win/tclWinFCmd.c tcl-8.3.5/win/tclWinFCmd.c
--- otcl-8.3.5/win/tclWinFCmd.c	2002-10-11 21:50:18.000000000 +1000
+++ tcl-8.3.5/win/tclWinFCmd.c	2002-10-12 12:00:26.000000000 +1000
@@ -73,6 +73,11 @@
 	{GetWinFileShortName, CannotSetAttribute},
 	{GetWinFileAttributes, SetWinFileAttributes}};
 
+#ifdef HAVE_NO_SEH
+static void *ESP;
+static void *EBP;
+#endif /* HAVE_NO_SEH */
+
 /*
  * Prototype for the TraverseWinTree callback function.
  */
@@ -174,6 +179,7 @@
 {    
     const TCHAR *nativeDst;
     DWORD srcAttr, dstAttr;
+    int retval = -1;
 
     nativeDst = (TCHAR *) Tcl_DStringValue(dstPtr);
 
@@ -182,11 +188,42 @@
      * char block device.
      */
 
+#ifdef HAVE_NO_SEH
+    __asm__ __volatile__ (
+            "movl  %esp, _ESP" "\n\t"
+            "movl  %ebp, _EBP");
+
+    __asm__ __volatile__ (
+            "pushl $__except_dorenamefile_handler" "\n\t"
+            "pushl %fs:0" "\n\t"
+            "mov   %esp, %fs:0");
+#else
     __try {
+#endif /* HAVE_NO_SEH */
 	if ((*tclWinProcs->moveFileProc)(nativeSrc, nativeDst) != FALSE) {
-	    return TCL_OK;
+	    retval = TCL_OK;
 	}
-    } __except (-1) {}
+#ifdef HAVE_NO_SEH
+    __asm__ __volatile__ (
+            "jmp   dorenamefile_pop" "\n"
+            "dorenamefile_reentry:" "\n\t"
+            "movl  _ESP, %esp" "\n\t"
+            "movl  _EBP, %ebp");
+
+    __asm__ __volatile__ (
+            "dorenamefile_pop:" "\n\t"
+            "mov   (%esp), %eax" "\n\t"
+            "mov   %eax, %fs:0" "\n\t"
+            "add   $8, %esp");
+#else
+    } __except (EXCEPTION_EXECUTE_HANDLER) {}
+#endif /* HAVE_NO_SEH */
+
+    /*
+     * Avoid using control flow statements in the SEH guarded block!
+     */
+    if (retval != -1)
+        return retval;
 
     TclWinConvertError(GetLastError());
 
@@ -402,6 +439,21 @@
     }
     return TCL_ERROR;
 }
+#ifdef HAVE_NO_SEH
+static
+__attribute__ ((cdecl))
+EXCEPTION_DISPOSITION
+_except_dorenamefile_handler(
+    struct _EXCEPTION_RECORD *ExceptionRecord,
+    void *EstablisherFrame,
+    struct _CONTEXT *ContextRecord,
+    void *DispatcherContext)
+{
+    __asm__ __volatile__ (
+            "jmp dorenamefile_reentry");
+    return 0; /* Function does not return */
+}
+#endif /* HAVE_NO_SEH */
 
 /*
  *---------------------------------------------------------------------------
@@ -452,6 +504,7 @@
     Tcl_DString *dstPtr)	/* Pathname of file to copy to (native). */
 {
     CONST TCHAR *nativeSrc, *nativeDst;
+    int retval = -1;
 
     nativeSrc = (TCHAR *) Tcl_DStringValue(srcPtr);
     nativeDst = (TCHAR *) Tcl_DStringValue(dstPtr);
@@ -461,11 +514,42 @@
      * block device.
      */
 
+#ifdef HAVE_NO_SEH
+    __asm__ __volatile__ (
+            "movl  %esp, _ESP" "\n\t"
+            "movl  %ebp, _EBP");
+
+    __asm__ __volatile__ (
+            "pushl $__except_docopyfile_handler" "\n\t"
+            "pushl %fs:0" "\n\t"
+            "mov   %esp, %fs:0");
+#else
     __try {
+#endif /* HAVE_NO_SEH */
 	if ((*tclWinProcs->copyFileProc)(nativeSrc, nativeDst, 0) != FALSE) {
-	    return TCL_OK;
+	    retval = TCL_OK;
 	}
-    } __except (-1) {}
+#ifdef HAVE_NO_SEH
+    __asm__ __volatile__ (
+            "jmp   docopyfile_pop" "\n"
+            "docopyfile_reentry:" "\n\t"
+            "movl  _ESP, %esp" "\n\t"
+            "movl  _EBP, %ebp");
+
+    __asm__ __volatile__ (
+            "docopyfile_pop:" "\n\t"
+            "mov   (%esp), %eax" "\n\t"
+            "mov   %eax, %fs:0" "\n\t"
+            "add   $8, %esp");
+#else
+    } __except (EXCEPTION_EXECUTE_HANDLER) {}
+#endif /* HAVE_NO_SEH */
+
+    /*
+     * Avoid using control flow statements in the SEH guarded block!
+     */
+    if (retval != -1)
+        return retval;
 
     TclWinConvertError(GetLastError());
     if (Tcl_GetErrno() == EBADF) {
@@ -503,6 +587,21 @@
     }
     return TCL_ERROR;
 }
+#ifdef HAVE_NO_SEH
+static
+__attribute__ ((cdecl))
+EXCEPTION_DISPOSITION
+_except_docopyfile_handler(
+    struct _EXCEPTION_RECORD *ExceptionRecord,
+    void *EstablisherFrame,
+    struct _CONTEXT *ContextRecord,
+    void *DispatcherContext)
+{
+    __asm__ __volatile__ (
+            "jmp docopyfile_reentry");
+    return 0; /* Function does not return */
+}
+#endif /* HAVE_NO_SEH */
 
 /*
  *---------------------------------------------------------------------------
diff -bur otcl-8.3.5/win/tclWinFile.c tcl-8.3.5/win/tclWinFile.c
--- otcl-8.3.5/win/tclWinFile.c	2002-10-11 21:50:18.000000000 +1000
+++ tcl-8.3.5/win/tclWinFile.c	2002-10-12 12:00:30.000000000 +1000
@@ -144,7 +144,6 @@
 	Tcl_DStringAppend(&dirString, ".\\", 2);
     } else {
 	char *p;
-
 	Tcl_DStringAppend(&dirString, Tcl_DStringValue(dirPtr),
 		Tcl_DStringLength(dirPtr));
 	for (p = Tcl_DStringValue(&dirString); *p != '\0'; p++) {
@@ -689,6 +688,51 @@
     return 0;
 }
 
+#ifdef __CYGWIN__
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TclpReadlink --
+ *
+ *	This function replaces the library version of readlink().
+ *
+ * Results:
+ *	The result is a pointer to a string specifying the contents
+ *	of the symbolic link given by 'path', or NULL if the symbolic
+ *	link could not be read.  Storage for the result string is
+ *	allocated in bufferPtr; the caller must call Tcl_DStringFree()
+ *	when the result is no longer needed.
+ *
+ * Side effects:
+ *	See readlink() documentation.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+char *
+TclpReadlink(path, linkPtr)
+    CONST char *path;		/* Path of file to readlink (UTF-8). */
+    Tcl_DString *linkPtr;	/* Uninitialized or free DString filled
+				 * with contents of link (UTF-8). */
+{
+    char link[MAXPATHLEN];
+    int length;
+    char *native;
+    Tcl_DString ds;
+
+    native = Tcl_UtfToExternalDString(NULL, path, -1, &ds);
+    length = readlink(native, link, sizeof(link));	/* INTL: Native. */
+    Tcl_DStringFree(&ds);
+    
+    if (length < 0) {
+	return NULL;
+    }
+
+    Tcl_ExternalToUtfDString(NULL, link, length, linkPtr);
+    return Tcl_DStringValue(linkPtr);
+}
+#endif /* __CYGWIN__ */
+ 
 /*
  *----------------------------------------------------------------------
  *
diff -bur otcl-8.3.5/win/tclWinPipe.c tcl-8.3.5/win/tclWinPipe.c
--- otcl-8.3.5/win/tclWinPipe.c	2002-10-11 21:50:18.000000000 +1000
+++ tcl-8.3.5/win/tclWinPipe.c	2002-10-12 12:03:30.000000000 +1000
@@ -14,7 +14,9 @@
 
 #include "tclWinInt.h"
 
+#ifndef __CYGWIN__
 #include <dos.h>
+#endif
 #include <fcntl.h>
 #include <io.h>
 #include <sys/stat.h>
diff -bur otcl-8.3.5/win/tclWinPort.h tcl-8.3.5/win/tclWinPort.h
--- otcl-8.3.5/win/tclWinPort.h	2002-10-11 21:50:18.000000000 +1000
+++ tcl-8.3.5/win/tclWinPort.h	2002-10-12 12:00:38.000000000 +1000
@@ -344,6 +344,14 @@
 #    endif
 #endif /* _MSC_VER || __MINGW32__ */
 
+#ifdef __CYGWIN__
+/* On Cygwin, the environment is imported from the Cygwin DLL.  */
+__declspec(dllimport) extern char **__cygwin_environ;
+#    define environ __cygwin_environ
+#    define putenv TclCygwinPutenv
+#    define timezone _timezone
+#endif /* __CYGWIN__ */
+
 /*
  *---------------------------------------------------------------------------
  * The following macros and declarations represent the interface between 
@@ -377,12 +385,18 @@
  * use by tclAlloc.c.
  */
 
-#define TclpSysAlloc(size, isBin)	((void*)HeapAlloc(GetProcessHeap(), \
+#ifdef __CYGWIN__
+#   define TclpSysAlloc(size, isBin)	malloc((size))
+#   define TclpSysFree(ptr)		free((ptr))
+#   define TclpSysRealloc(ptr, size)	realloc((ptr), (size))
+#else /* __CYGWIN__ */
+#   define TclpSysAlloc(size, isBin)	((void*)HeapAlloc(GetProcessHeap(), \
 					    (DWORD)0, (DWORD)size))
-#define TclpSysFree(ptr)		(HeapFree(GetProcessHeap(), \
+#   define TclpSysFree(ptr)		(HeapFree(GetProcessHeap(), \
 					    (DWORD)0, (HGLOBAL)ptr))
-#define TclpSysRealloc(ptr, size)	((void*)HeapReAlloc(GetProcessHeap(), \
+#   define TclpSysRealloc(ptr, size)	((void*)HeapReAlloc(GetProcessHeap(), \
 					    (DWORD)0, (LPVOID)ptr, (DWORD)size))
+#endif /* __CYGWIN__ */
 
 /*
  * The following defines map from standard socket names to our internal
diff -bur otcl-8.3.5/win/tclWinSerial.c tcl-8.3.5/win/tclWinSerial.c
--- otcl-8.3.5/win/tclWinSerial.c	2002-10-11 21:50:18.000000000 +1000
+++ tcl-8.3.5/win/tclWinSerial.c	2002-10-12 12:03:06.000000000 +1000
@@ -15,7 +15,9 @@
 
 #include "tclWinInt.h"
 
+#ifndef __CYGWIN__
 #include <dos.h>
+#endif
 #include <fcntl.h>
 #include <io.h>
 #include <sys/stat.h>
diff -bur otcl-8.3.5/win/tclWinThrd.c tcl-8.3.5/win/tclWinThrd.c
--- otcl-8.3.5/win/tclWinThrd.c	2002-10-11 21:50:18.000000000 +1000
+++ tcl-8.3.5/win/tclWinThrd.c	2002-10-12 12:02:40.000000000 +1000
@@ -14,7 +14,9 @@
 
 #include "tclWinInt.h"
 
+#ifndef __CYGWIN__
 #include <dos.h>
+#endif
 #include <fcntl.h>
 #include <io.h>
 #include <sys/stat.h>
@@ -125,8 +127,14 @@
 {
     HANDLE tHandle;
 
+#ifdef __CYGWIN__
+    tHandle = CreateThread(NULL, (DWORD) stackSize, 
+        (LPTHREAD_START_ROUTINE) proc, (LPVOID) clientData, 
+	(DWORD) 0, (LPWORD) idPtr);
+#else
     tHandle = (HANDLE) _beginthreadex(NULL, (unsigned) stackSize, proc,
 	clientData, 0, (unsigned *)idPtr);
+#endif /* __CYGWIN__ */
 
     if (tHandle == NULL) {
 	return TCL_ERROR;
@@ -160,7 +168,11 @@
 TclpThreadExit(status)
     int status;
 {
+#ifdef __CYGWIN__
+    ExitThread ((DWORD) status);
+#else
     _endthreadex((DWORD)status);
+#endif /* __CYGWIN__ */
 }