From f3146e6826308cf112fccc9ac29ab18bca2a6071 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 30 Mar 2012 14:44:03 +0000 Subject: [Bug 3508771] load tclreg.dll in cygwin tclsh Implement TclWinGetTclInstance, TclpGetTZName, and various others for Cygwin --- ChangeLog | 7 +++++++ generic/tclInt.decls | 10 +++++----- generic/tclIntPlatDecls.h | 22 ++++++++++----------- generic/tclStubInit.c | 49 +++++++++++++++++++++++++++-------------------- win/tclWinError.c | 32 ++++++++++++++++++------------- 5 files changed, 69 insertions(+), 51 deletions(-) diff --git a/ChangeLog b/ChangeLog index ebf83f7..63b2747 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2012-03-30 Jan Nijtmans + + * generic/tclInt.decls: [Bug 3508771] load tclreg.dll in cygwin tclsh + * generic/tclIntPlatDecls.h: Implement TclWinGetTclInstance, TclpGetTZName, + * generic/tclStubInit.c: and various more win32-specific internal functions for + Cygwin, so win32 extensions using those can be loaded in the cygwin version of tclsh. + 2012-03-29 Jan Nijtmans * unix/tcl.m4: [Bug 3511806] Compiler checks too early diff --git a/generic/tclInt.decls b/generic/tclInt.decls index 36198a4..b5fd668 100644 --- a/generic/tclInt.decls +++ b/generic/tclInt.decls @@ -835,7 +835,7 @@ declare 2 win { } declare 3 win { int TclWinGetSockOpt(SOCKET s, int level, int optname, - char FAR *optval, int FAR *optlen) + char *optval, int *optlen) } declare 4 win { HINSTANCE TclWinGetTclInstance(void) @@ -849,7 +849,7 @@ declare 6 win { } declare 7 win { int TclWinSetSockOpt(SOCKET s, int level, int optname, - CONST char FAR *optval, int optlen) + CONST char *optval, int optlen) } declare 8 win { unsigned long TclpGetPid(Tcl_Pid pid) @@ -958,7 +958,7 @@ declare 3 unix { } # On non-cygwin, this is actually a reference to TclpCreateProcess declare 4 unix { - int TclWinGetTclInstance(void) + void *TclWinGetTclInstance(void) } # Signature changed in 8.1: # declare 5 unix { @@ -971,7 +971,7 @@ declare 6 unix { } # On non-cygwin, this is actually a reference to TclpOpenFile declare 7 unix { - int TclWinSetSockOpt(int s, int level, int optname, + int TclWinSetSockOpt(void *s, int level, int optname, CONST char *optval, int optlen) } declare 8 unix { @@ -1019,7 +1019,7 @@ declare 19 unix { void TclMacOSXNotifierAddRunLoopMode(CONST void *runLoopMode) } declare 20 unix { - void TclWinAddProcess(void *hProcess, unsigned long id) + void TclWinAddProcess(void *hProcess, unsigned int id) } declare 22 unix { TclFile TclpCreateTempFile(CONST char *contents) diff --git a/generic/tclIntPlatDecls.h b/generic/tclIntPlatDecls.h index b46b859..3a4123b 100644 --- a/generic/tclIntPlatDecls.h +++ b/generic/tclIntPlatDecls.h @@ -50,12 +50,12 @@ EXTERN Tcl_Channel TclpCreateCommandChannel _ANSI_ARGS_(( EXTERN int TclpCreatePipe _ANSI_ARGS_((TclFile *readPipe, TclFile *writePipe)); /* 4 */ -EXTERN int TclWinGetTclInstance _ANSI_ARGS_((void)); +EXTERN void * TclWinGetTclInstance _ANSI_ARGS_((void)); /* Slot 5 is reserved */ /* 6 */ EXTERN unsigned short TclWinNToHS _ANSI_ARGS_((unsigned short ns)); /* 7 */ -EXTERN int TclWinSetSockOpt _ANSI_ARGS_((int s, int level, +EXTERN int TclWinSetSockOpt _ANSI_ARGS_((void *s, int level, int optname, CONST char *optval, int optlen)); /* 8 */ EXTERN int TclUnixWaitForFile _ANSI_ARGS_((int fd, int mask, @@ -88,7 +88,7 @@ EXTERN void TclMacOSXNotifierAddRunLoopMode _ANSI_ARGS_(( CONST void *runLoopMode)); /* 20 */ EXTERN void TclWinAddProcess _ANSI_ARGS_((void *hProcess, - unsigned long id)); + unsigned int id)); /* Slot 21 is reserved */ /* 22 */ EXTERN TclFile TclpCreateTempFile _ANSI_ARGS_((CONST char *contents)); @@ -122,8 +122,7 @@ EXTERN struct servent * TclWinGetServByName _ANSI_ARGS_((CONST char *nm, CONST char *proto)); /* 3 */ EXTERN int TclWinGetSockOpt _ANSI_ARGS_((SOCKET s, int level, - int optname, char FAR *optval, - int FAR *optlen)); + int optname, char *optval, int *optlen)); /* 4 */ EXTERN HINSTANCE TclWinGetTclInstance _ANSI_ARGS_((void)); /* Slot 5 is reserved */ @@ -131,8 +130,7 @@ EXTERN HINSTANCE TclWinGetTclInstance _ANSI_ARGS_((void)); EXTERN u_short TclWinNToHS _ANSI_ARGS_((u_short ns)); /* 7 */ EXTERN int TclWinSetSockOpt _ANSI_ARGS_((SOCKET s, int level, - int optname, CONST char FAR *optval, - int optlen)); + int optname, CONST char *optval, int optlen)); /* 8 */ EXTERN unsigned long TclpGetPid _ANSI_ARGS_((Tcl_Pid pid)); /* 9 */ @@ -266,10 +264,10 @@ typedef struct TclIntPlatStubs { void (*tclWinConvertWSAError) _ANSI_ARGS_((unsigned int errCode)); /* 1 */ Tcl_Channel (*tclpCreateCommandChannel) _ANSI_ARGS_((TclFile readFile, TclFile writeFile, TclFile errorFile, int numPids, Tcl_Pid *pidPtr)); /* 2 */ int (*tclpCreatePipe) _ANSI_ARGS_((TclFile *readPipe, TclFile *writePipe)); /* 3 */ - int (*tclWinGetTclInstance) _ANSI_ARGS_((void)); /* 4 */ + void * (*tclWinGetTclInstance) _ANSI_ARGS_((void)); /* 4 */ void *reserved5; unsigned short (*tclWinNToHS) _ANSI_ARGS_((unsigned short ns)); /* 6 */ - int (*tclWinSetSockOpt) _ANSI_ARGS_((int s, int level, int optname, CONST char *optval, int optlen)); /* 7 */ + int (*tclWinSetSockOpt) _ANSI_ARGS_((void *s, int level, int optname, CONST char *optval, int optlen)); /* 7 */ int (*tclUnixWaitForFile) _ANSI_ARGS_((int fd, int mask, int timeout)); /* 8 */ int (*tclWinGetPlatformId) _ANSI_ARGS_((void)); /* 9 */ Tcl_DirEntry * (*tclpReaddir) _ANSI_ARGS_((DIR *dir)); /* 10 */ @@ -282,7 +280,7 @@ typedef struct TclIntPlatStubs { void *reserved17; int (*tclMacOSXMatchType) _ANSI_ARGS_((Tcl_Interp *interp, CONST char *pathName, CONST char *fileName, Tcl_StatBuf *statBufPtr, Tcl_GlobTypeData *types)); /* 18 */ void (*tclMacOSXNotifierAddRunLoopMode) _ANSI_ARGS_((CONST void *runLoopMode)); /* 19 */ - void (*tclWinAddProcess) _ANSI_ARGS_((void *hProcess, unsigned long id)); /* 20 */ + void (*tclWinAddProcess) _ANSI_ARGS_((void *hProcess, unsigned int id)); /* 20 */ void *reserved21; TclFile (*tclpCreateTempFile) _ANSI_ARGS_((CONST char *contents)); /* 22 */ char * (*tclpGetTZName) _ANSI_ARGS_((int isdst)); /* 23 */ @@ -299,11 +297,11 @@ typedef struct TclIntPlatStubs { void (*tclWinConvertError) _ANSI_ARGS_((DWORD errCode)); /* 0 */ void (*tclWinConvertWSAError) _ANSI_ARGS_((DWORD errCode)); /* 1 */ struct servent * (*tclWinGetServByName) _ANSI_ARGS_((CONST char *nm, CONST char *proto)); /* 2 */ - int (*tclWinGetSockOpt) _ANSI_ARGS_((SOCKET s, int level, int optname, char FAR *optval, int FAR *optlen)); /* 3 */ + int (*tclWinGetSockOpt) _ANSI_ARGS_((SOCKET s, int level, int optname, char *optval, int *optlen)); /* 3 */ HINSTANCE (*tclWinGetTclInstance) _ANSI_ARGS_((void)); /* 4 */ void *reserved5; u_short (*tclWinNToHS) _ANSI_ARGS_((u_short ns)); /* 6 */ - int (*tclWinSetSockOpt) _ANSI_ARGS_((SOCKET s, int level, int optname, CONST char FAR *optval, int optlen)); /* 7 */ + int (*tclWinSetSockOpt) _ANSI_ARGS_((SOCKET s, int level, int optname, CONST char *optval, int optlen)); /* 7 */ unsigned long (*tclpGetPid) _ANSI_ARGS_((Tcl_Pid pid)); /* 8 */ int (*tclWinGetPlatformId) _ANSI_ARGS_((void)); /* 9 */ void *reserved10; diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index 347bdcb..8c497288 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -57,21 +57,31 @@ Tcl_NotifierProcs tclOriginalNotifier = { #ifdef __CYGWIN__ +/* Trick, so we don't have to include here, which + * - b.t.w. - lacks this function anyway */ +#define GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS 0x00000004 +int __stdcall GetModuleHandleExW(unsigned int, const char *, void *); + #define TclWinGetPlatformId winGetPlatformId #define Tcl_WinUtfToTChar winUtfToTChar #define Tcl_WinTCharToUtf winTCharToUtf #define TclWinGetTclInstance winGetTclInstance #define TclWinNToHS winNToHS #define TclWinSetSockOpt winSetSockOpt -#define TclWinAddProcess winAddProcess #define TclpGetTZName pGetTZName #define TclWinNoBackslash winNoBackslash -#define TclWinSetInterfaces (void (*) _ANSI_ARGS_((int))) doNothing +#define TclWinSetInterfaces (void (*) (int)) doNothing +#define TclWinAddProcess (void (*) (void *, unsigned int)) doNothing #define TclWinFlushDirtyChannels doNothing #define TclWinResetInterfaces doNothing static Tcl_Encoding winTCharEncoding; +typedef struct ThreadSpecificData { + char tzName[64]; /* Time zone name */ +} ThreadSpecificData; +static Tcl_ThreadDataKey dataKey; + static int TclWinGetPlatformId() { @@ -80,38 +90,35 @@ TclWinGetPlatformId() return 2; /* VER_PLATFORM_WIN32_NT */; } -static int TclWinGetTclInstance() +static void *TclWinGetTclInstance() { - Tcl_Panic("TclWinGetTclInstance not yet implemented for CYGWIN"); - return 0; + void *hInstance = NULL; + GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, + (const char *)&winTCharEncoding, &hInstance); + return hInstance; } static unsigned short TclWinNToHS(unsigned short ns) { - Tcl_Panic("TclWinNToHS not yet implemented for CYGWIN"); - return (unsigned short) -1; + return ntohs(ns); } + static int -TclWinSetSockOpt(int s, int level, int optname, +TclWinSetSockOpt(void *s, int level, int optname, const char *optval, int optlen) { - Tcl_Panic("TclWinSetSockOpt not yet implemented for CYGWIN"); - return -1; -} - -static void -TclWinAddProcess(void *hProcess, unsigned long id) -{ - Tcl_Panic("TclWinAddProcess not yet implemented for CYGWIN"); + return setsockopt((int) s, level, optname, optval, optlen); } static char * TclpGetTZName(int isdst) { - /* TODO: implementation */ - Tcl_Panic("TclpGetTZName not yet implemented for CYGWIN"); - return 0; + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + const char *zone = getenv("TZ"); + Tcl_ExternalToUtf(NULL, NULL, zone, strlen(zone), 0, NULL, + tsdPtr->tzName, sizeof(tsdPtr->tzName), NULL, NULL, NULL); + return tsdPtr->tzName; } static char * @@ -175,9 +182,9 @@ Tcl_WinTCharToUtf( # define TclWinConvertError (void (*) _ANSI_ARGS_((unsigned int))) TclGetAndDetachPids # define TclWinConvertWSAError (void (*) _ANSI_ARGS_((unsigned int))) TclpCloseFile # define TclWinGetPlatformId (int (*)()) TclpCreateTempFile -# define TclWinGetTclInstance (int (*)()) TclpCreateProcess +# define TclWinGetTclInstance (void *(*)()) TclpCreateProcess # define TclWinNToHS (unsigned short (*) _ANSI_ARGS_((unsigned short ns))) TclpMakeFile -# define TclWinSetSockOpt (int (*) _ANSI_ARGS_((int, int, int, const char *, int))) TclpOpenFile +# define TclWinSetSockOpt (int (*) _ANSI_ARGS_((void *, int, int, const char *, int))) TclpOpenFile # define TclWinAddProcess 0 # define TclpGetTZName 0 # define TclWinNoBackslash 0 diff --git a/win/tclWinError.c b/win/tclWinError.c index b49271e..d3126b1 100644 --- a/win/tclWinError.c +++ b/win/tclWinError.c @@ -13,14 +13,6 @@ #include "tclInt.h" #include "tclPort.h" -#ifndef WSAEWOULDBLOCK -# define WSAEWOULDBLOCK 10035L -#endif - -#ifndef __WIN32__ -# define DWORD unsigned int -#endif - /* * The following table contains the mapping from Win32 errors to errno errors. */ @@ -341,6 +333,11 @@ static CONST int wsaErrorTable[] = { EREMOTE /* WSAEREMOTE */ }; +#ifdef __CYGWIN__ +# include +# define DWORD unsigned int +#endif + /* *---------------------------------------------------------------------- * @@ -362,7 +359,12 @@ TclWinConvertError( DWORD errCode) /* Win32 error code. */ { if (errCode >= sizeof(errorTable)/sizeof(errorTable[0])) { - Tcl_SetErrno(EINVAL); + errCode -= WSAEWOULDBLOCK; + if (errCode >= sizeof(wsaErrorTable)/sizeof(wsaErrorTable[0])) { + Tcl_SetErrno(errorTable[1]); + } else { + Tcl_SetErrno(wsaErrorTable[errCode]); + } } else { Tcl_SetErrno(errorTable[errCode]); } @@ -388,11 +390,15 @@ void TclWinConvertWSAError( DWORD errCode) /* Win32 error code. */ { - errCode -= WSAEWOULDBLOCK; - if (errCode >= sizeof(wsaErrorTable)/sizeof(wsaErrorTable[0])) { - Tcl_SetErrno(EINVAL); + if (errCode >= sizeof(errorTable)/sizeof(errorTable[0])) { + errCode -= WSAEWOULDBLOCK; + if (errCode >= sizeof(wsaErrorTable)/sizeof(wsaErrorTable[0])) { + Tcl_SetErrno(errorTable[1]); + } else { + Tcl_SetErrno(wsaErrorTable[errCode]); + } } else { - Tcl_SetErrno(wsaErrorTable[errCode]); + Tcl_SetErrno(errorTable[errCode]); } } -- cgit v0.12