From 37c0b648759bb24ebf17831abc35533f356be7c4 Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Thu, 6 Sep 2001 02:54:56 +0000 Subject: [PATCH] Below is the patch against current cvs for libpgtcl and two additional files win32.mak and libpgtcl.def. This patch allows to compile libpgtcl.dll on Windows with tcl > 8.0. I've tested it on WinNT (VC6.0), SUSE Linux (7.0) and Solaris 2.6 with tcl 8.3.3. Mikhail Terekhov --- src/interfaces/libpgtcl.def | 8 ++ src/interfaces/libpgtcl/pgtclCmds.c | 10 +- src/interfaces/libpgtcl/pgtclCmds.h | 6 +- src/interfaces/libpgtcl/pgtclId.c | 23 ++-- src/interfaces/libpq/fe-exec.c | 16 ++- src/interfaces/libpq/libpq-fe.h | 3 +- src/interfaces/libpq/libpqdll.def | 2 +- src/interfaces/win32.mak | 201 ++++++++++++++++++++++++++++ 8 files changed, 255 insertions(+), 14 deletions(-) create mode 100644 src/interfaces/libpgtcl.def create mode 100644 src/interfaces/win32.mak diff --git a/src/interfaces/libpgtcl.def b/src/interfaces/libpgtcl.def new file mode 100644 index 0000000000..0ecc5ea031 --- /dev/null +++ b/src/interfaces/libpgtcl.def @@ -0,0 +1,8 @@ +;libpgtcl.def +; The LIBRARY entry must be same as the name of your DLL, the name of +; our DLL is libpgtcl.dll +LIBRARY libpgtcl +EXPORTS + + Pgtcl_Init + Pgtcl_SafeInit diff --git a/src/interfaces/libpgtcl/pgtclCmds.c b/src/interfaces/libpgtcl/pgtclCmds.c index a87cb1842c..8fef8732fd 100644 --- a/src/interfaces/libpgtcl/pgtclCmds.c +++ b/src/interfaces/libpgtcl/pgtclCmds.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtclCmds.c,v 1.56 2001/08/10 22:50:10 tgl Exp $ + * $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtclCmds.c,v 1.57 2001/09/06 02:54:56 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -403,6 +403,8 @@ Pg_connect(ClientData cData, Tcl_Interp *interp, int argc, char *argv[]) int Pg_disconnect(ClientData cData, Tcl_Interp *interp, int argc, char *argv[]) { + Pg_ConnectionId *connid; + PGconn *conn; Tcl_Channel conn_chan; if (argc != 2) @@ -419,6 +421,12 @@ Pg_disconnect(ClientData cData, Tcl_Interp *interp, int argc, char *argv[]) return TCL_ERROR; } +#if TCL_MAJOR_VERSION >= 8 + conn = PgGetConnectionId(interp, argv[1], &connid); + if (connid->notifier_channel != NULL) + Tcl_UnregisterChannel(interp, connid->notifier_channel); +#endif + return Tcl_UnregisterChannel(interp, conn_chan); } diff --git a/src/interfaces/libpgtcl/pgtclCmds.h b/src/interfaces/libpgtcl/pgtclCmds.h index 69ae93015e..6b40ea63c6 100644 --- a/src/interfaces/libpgtcl/pgtclCmds.h +++ b/src/interfaces/libpgtcl/pgtclCmds.h @@ -6,7 +6,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: pgtclCmds.h,v 1.21 2001/03/22 04:01:24 momjian Exp $ + * $Id: pgtclCmds.h,v 1.22 2001/09/06 02:54:56 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -64,7 +64,11 @@ typedef struct Pg_ConnectionId_s Pg_TclNotifies *notify_list;/* head of list of notify info */ int notifier_running; /* notify event source is live */ +#if TCL_MAJOR_VERSION >= 8 + Tcl_Channel notifier_channel;/* Tcl_Channel on which notifier is listening */ +#else int notifier_socket;/* PQsocket on which notifier is listening */ +#endif } Pg_ConnectionId; /* Values of res_copyStatus */ diff --git a/src/interfaces/libpgtcl/pgtclId.c b/src/interfaces/libpgtcl/pgtclId.c index f4acde2fc4..af58f66247 100644 --- a/src/interfaces/libpgtcl/pgtclId.c +++ b/src/interfaces/libpgtcl/pgtclId.c @@ -13,7 +13,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtclId.c,v 1.25 2001/02/10 02:31:29 tgl Exp $ + * $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtclId.c,v 1.26 2001/09/06 02:54:56 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -174,10 +174,16 @@ PgSetConnectionId(Tcl_Interp *interp, PGconn *conn) connid->results[i] = NULL; connid->notify_list = NULL; connid->notifier_running = 0; - connid->notifier_socket = -1; sprintf(connid->id, "pgsql%d", PQsocket(conn)); +#if TCL_MAJOR_VERSION >= 8 + connid->notifier_channel = Tcl_MakeTcpClientChannel((ClientData) PQsocket(conn)); + Tcl_RegisterChannel(interp, connid->notifier_channel); +#else + connid->notifier_socket = -1; +#endif + #if TCL_MAJOR_VERSION == 7 && TCL_MINOR_VERSION == 5 /* Original signature (only seen in Tcl 7.5) */ conn_chan = Tcl_CreateChannel(&Pg_ConnType, connid->id, NULL, NULL, (ClientData) connid); @@ -581,7 +587,7 @@ PgNotifyTransferEvents(Pg_ConnectionId * connid) event->info = *notify; event->connid = connid; Tcl_QueueEvent((Tcl_Event *) event, TCL_QUEUE_TAIL); - free(notify); + PQfreeNotify(notify); } /* @@ -688,18 +694,17 @@ PgStartNotifyEventSource(Pg_ConnectionId * connid) if (pqsock >= 0) { #if TCL_MAJOR_VERSION >= 8 - /* In Tcl 8, Tcl_CreateFileHandler takes a socket directly. */ - Tcl_CreateFileHandler(pqsock, TCL_READABLE, - Pg_Notify_FileHandler, (ClientData) connid); + Tcl_CreateChannelHandler(connid->notifier_channel, TCL_READABLE, + Pg_Notify_FileHandler, (ClientData) connid); #else /* In Tcl 7.5 and 7.6, we need to gin up a Tcl_File. */ Tcl_File tclfile = Tcl_GetFile((ClientData) pqsock, TCL_UNIX_FD); Tcl_CreateFileHandler(tclfile, TCL_READABLE, Pg_Notify_FileHandler, (ClientData) connid); + connid->notifier_socket = pqsock; #endif connid->notifier_running = 1; - connid->notifier_socket = pqsock; } } } @@ -711,8 +716,8 @@ PgStopNotifyEventSource(Pg_ConnectionId * connid) if (connid->notifier_running) { #if TCL_MAJOR_VERSION >= 8 - /* In Tcl 8, Tcl_DeleteFileHandler takes a socket directly. */ - Tcl_DeleteFileHandler(connid->notifier_socket); + Tcl_DeleteChannelHandler(connid->notifier_channel, + Pg_Notify_FileHandler, (ClientData) connid); #else /* In Tcl 7.5 and 7.6, we need to gin up a Tcl_File. */ Tcl_File tclfile = Tcl_GetFile((ClientData) connid->notifier_socket, diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c index d02b74490e..4b67bdcf52 100644 --- a/src/interfaces/libpq/fe-exec.c +++ b/src/interfaces/libpq/fe-exec.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.108 2001/08/21 20:39:53 momjian Exp $ + * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.109 2001/09/06 02:54:56 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -1345,6 +1345,20 @@ PQnotifies(PGconn *conn) return event; } +/* + * PQfreeNotify - free's the memory associated with a PGnotify + * + * This function is needed on Windows when using libpq.dll and + * for example libpgtcl.dll: All memory allocated inside a dll + * should be freed in the context of the same dll. + * + */ +void +PQfreeNotify(PGnotify *notify) +{ + free(notify); +} + /* * PQgetline - gets a newline-terminated string from the backend. * diff --git a/src/interfaces/libpq/libpq-fe.h b/src/interfaces/libpq/libpq-fe.h index 79166533e9..5faa576c08 100644 --- a/src/interfaces/libpq/libpq-fe.h +++ b/src/interfaces/libpq/libpq-fe.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: libpq-fe.h,v 1.72 2001/08/21 20:39:54 momjian Exp $ + * $Id: libpq-fe.h,v 1.73 2001/09/06 02:54:56 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -254,6 +254,7 @@ extern "C" /* Simple synchronous query */ extern PGresult *PQexec(PGconn *conn, const char *query); extern PGnotify *PQnotifies(PGconn *conn); + extern void PQfreeNotify(PGnotify *notify); /* Interface for multiple-result or asynchronous queries */ extern int PQsendQuery(PGconn *conn, const char *query); diff --git a/src/interfaces/libpq/libpqdll.def b/src/interfaces/libpq/libpqdll.def index a8b24c96be..059707f87e 100644 --- a/src/interfaces/libpq/libpqdll.def +++ b/src/interfaces/libpq/libpqdll.def @@ -87,4 +87,4 @@ EXPORTS PQresetStart @ 84 PQsetClientEncoding @ 85 PQsetnonblocking @ 86 - + PQfreeNotify @ 87 diff --git a/src/interfaces/win32.mak b/src/interfaces/win32.mak new file mode 100644 index 0000000000..bbd11b2c33 --- /dev/null +++ b/src/interfaces/win32.mak @@ -0,0 +1,201 @@ +# Microsoft Developer Studio Generated NMAKE File, Based on libpgtcl_REL7_1_STABLE.dsp +!IF "$(CFG)" == "" +CFG=libpgtcl - Win32 Release +!MESSAGE No configuration specified. Defaulting to libpgtcl - Win32 Release. +!ENDIF + +!IF "$(CFG)" != "libpgtcl - Win32 Release" && "$(CFG)" != "libpgtcl - Win32 Debug" +!MESSAGE Invalid configuration "$(CFG)" specified. +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "libpgtcl.mak" CFG="libpgtcl - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "libpgtcl - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "libpgtcl - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE +!ERROR An invalid configuration is specified. +!ENDIF + +!IF "$(OS)" == "Windows_NT" +NULL= +!ELSE +NULL=nul +!ENDIF + +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +TCLBASE=\usr\local\tcltk833 +PGINCLUDE=/I ..\..\include /I ..\libpq /I $(TCLBASE)\include + +!IF "$(CFG)" == "libpgtcl - Win32 Release" + +OUTDIR=.\Release +INTDIR=.\Release +# Begin Custom Macros +OutDir=.\Release +# End Custom Macros + +ALL : "$(OUTDIR)\libpgtcl.dll" "$(OUTDIR)\libpgtcl.bsc" + + +CLEAN : + -@erase "$(INTDIR)\pgtcl.obj" + -@erase "$(INTDIR)\pgtcl.sbr" + -@erase "$(INTDIR)\pgtclCmds.obj" + -@erase "$(INTDIR)\pgtclCmds.sbr" + -@erase "$(INTDIR)\pgtclId.obj" + -@erase "$(INTDIR)\pgtclId.sbr" + -@erase "$(INTDIR)\vc60.idb" + -@erase "$(OUTDIR)\libpgtcl.dll" + -@erase "$(OUTDIR)\libpgtcl.exp" + -@erase "$(OUTDIR)\libpgtcl.lib" + -@erase "$(OUTDIR)\libpgtcl.bsc" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP_PROJ=/nologo /MT /W3 /GX /O2 $(PGINCLUDE) /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\libpgtcl.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c +MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 +BSC32=bscmake.exe +BSC32_FLAGS=/nologo /o"$(OUTDIR)\libpgtcl.bsc" +BSC32_SBRS= \ + "$(INTDIR)\pgtcl.sbr" \ + "$(INTDIR)\pgtclCmds.sbr" \ + "$(INTDIR)\pgtclId.sbr" + +"$(OUTDIR)\libpgtcl.bsc" : "$(OUTDIR)" $(BSC32_SBRS) + $(BSC32) @<< + $(BSC32_FLAGS) $(BSC32_SBRS) +<< + +LINK32=link.exe +LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib tcl83.lib libpq.lib /nologo /dll /incremental:no /pdb:"$(OUTDIR)\libpgtcl.pdb" /machine:I386 /def:".\libpgtcl.def" /out:"$(OUTDIR)\libpgtcl.dll" /implib:"$(OUTDIR)\libpgtcl.lib" /libpath:"$(TCLBASE)\lib" /libpath:"..\libpq\Release" +DEF_FILE= \ + ".\libpgtcl.def" +LINK32_OBJS= \ + "$(INTDIR)\pgtcl.obj" \ + "$(INTDIR)\pgtclCmds.obj" \ + "$(INTDIR)\pgtclId.obj" + +"$(OUTDIR)\libpgtcl.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "libpgtcl - Win32 Debug" + +OUTDIR=.\Debug +INTDIR=.\Debug +# Begin Custom Macros +OutDir=.\Debug +# End Custom Macros + +ALL : "$(OUTDIR)\libpgtcl.dll" "$(OUTDIR)\libpgtcl.bsc" + + +CLEAN : + -@erase "$(INTDIR)\pgtcl.obj" + -@erase "$(INTDIR)\pgtcl.sbr" + -@erase "$(INTDIR)\pgtclCmds.obj" + -@erase "$(INTDIR)\pgtclCmds.sbr" + -@erase "$(INTDIR)\pgtclId.obj" + -@erase "$(INTDIR)\pgtclId.sbr" + -@erase "$(INTDIR)\vc60.idb" + -@erase "$(INTDIR)\vc60.pdb" + -@erase "$(OUTDIR)\libpgtcl.dll" + -@erase "$(OUTDIR)\libpgtcl.exp" + -@erase "$(OUTDIR)\libpgtcl.ilk" + -@erase "$(OUTDIR)\libpgtcl.lib" + -@erase "$(OUTDIR)\libpgtcl.pdb" + -@erase "$(OUTDIR)\libpgtcl.bsc" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP_PROJ=/nologo /MTd /W3 /Gm /GX /ZI /Od $(PGINCLUDE) /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\libpgtcl.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c +MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 +BSC32=bscmake.exe +BSC32_FLAGS=/nologo /o"$(OUTDIR)\libpgtcl.bsc" +BSC32_SBRS= \ + "$(INTDIR)\pgtcl.sbr" \ + "$(INTDIR)\pgtclCmds.sbr" \ + "$(INTDIR)\pgtclId.sbr" + +"$(OUTDIR)\libpgtcl.bsc" : "$(OUTDIR)" $(BSC32_SBRS) + $(BSC32) @<< + $(BSC32_FLAGS) $(BSC32_SBRS) +<< + +LINK32=link.exe +LINK32_FLAGS=tcl83.lib libpq.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /incremental:yes /pdb:"$(OUTDIR)\libpgtcl.pdb" /debug /machine:I386 /def:".\libpgtcl.def" /out:"$(OUTDIR)\libpgtcl.dll" /implib:"$(OUTDIR)\libpgtcl.lib" /pdbtype:sept /libpath:"$(TCLBASE)\lib" /libpath:"..\libpq\Debug" +DEF_FILE= \ + ".\libpgtcl.def" +LINK32_OBJS= \ + "$(INTDIR)\pgtcl.obj" \ + "$(INTDIR)\pgtclCmds.obj" \ + "$(INTDIR)\pgtclId.obj" + +"$(OUTDIR)\libpgtcl.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ENDIF + +.c{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.c{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +!IF "$(CFG)" == "libpgtcl - Win32 Release" || "$(CFG)" == "libpgtcl - Win32 Debug" +SOURCE=pgtcl.c + +"$(INTDIR)\pgtcl.obj" "$(INTDIR)\pgtcl.sbr" : $(SOURCE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +SOURCE=pgtclCmds.c + +"$(INTDIR)\pgtclCmds.obj" "$(INTDIR)\pgtclCmds.sbr" : $(SOURCE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +SOURCE=pgtclId.c + +"$(INTDIR)\pgtclId.obj" "$(INTDIR)\pgtclId.sbr" : $(SOURCE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + + +!ENDIF +