summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjan.nijtmans <nijtmans@users.sourceforge.net>2012-03-30 14:44:03 (GMT)
committerjan.nijtmans <nijtmans@users.sourceforge.net>2012-03-30 14:44:03 (GMT)
commitf3146e6826308cf112fccc9ac29ab18bca2a6071 (patch)
tree3a9aaf5da71029699163071fe0dae4b19e775887
parent3a73c145323d7a85af7f9e5ad7de9e601cbaf903 (diff)
downloadtcl-f3146e6826308cf112fccc9ac29ab18bca2a6071.zip
tcl-f3146e6826308cf112fccc9ac29ab18bca2a6071.tar.gz
tcl-f3146e6826308cf112fccc9ac29ab18bca2a6071.tar.bz2
[Bug 3508771] load tclreg.dll in cygwin tclsh
Implement TclWinGetTclInstance, TclpGetTZName, and various others for Cygwin
-rw-r--r--ChangeLog7
-rw-r--r--generic/tclInt.decls10
-rw-r--r--generic/tclIntPlatDecls.h22
-rw-r--r--generic/tclStubInit.c49
-rw-r--r--win/tclWinError.c32
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 <nijtmans@users.sf.net>
+
+ * 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 <nijtmans@users.sf.net>
* 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 <windows.h> 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 <windows.h>
+# 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]);
}
}