Thread

  1. pgsql/src/interfaces/libpq fe-connect.c win32.h

    Bruce Momjian - CVS <momjian@hub.org> — 2001-07-21T04:32:42Z

    CVSROOT:	/home/projects/pgsql/cvsroot
    Module name:	pgsql
    Changes by:	momjian@hub.org	01/07/21 00:32:42
    
    Modified files:
    	src/interfaces/libpq: fe-connect.c win32.h 
    
    Log message:
    	I downloaded new source for lib (only few hours old !!!), and made
    	changes on this new source to make non-blocking connection work. I
    	tested it, and PQSendQuery and PQGetResult are working fine.
    	
    	In win32.h I added one line:
    	#define snprintf _snprintf
    	
    	Darko Prenosil
    
    
    
  2. WIN32 errno patch

    Tom Lane <tgl@sss.pgh.pa.us> — 2001-07-21T20:45:54Z

    Upon review, I don't think these patches are very good at all.
    #defining errno as WSAGetLastError() is a fairly blunt instrument,
    and it breaks all the places that do actually need to use errno,
    such as PQoidValue, lo_import, lo_export.  I'm also concerned that
    PQrequestCancel may need to save/restore both errno and
    WSAGetLastError() in order to be safe for use in a signal handler.
    
    Is errno a plain variable on WIN32, or is it a macro?  If the former,
    we could hack around this problem by doing
    
    	#if WIN32
    	#undef errno
    	#endif
    
    	...
    
    	#if WIN32
    	#define errno WSAGetLastError()
    	#endif
    
    around the routines that need to access the real errno.  While ugly,
    this probably beats the alternative of ifdef'ing all the places that
    do need to access the WSA error code.
    
    			regards, tom lane
    
    
  3. Re: WIN32 errno patch

    Bruce Momjian <pgman@candle.pha.pa.us> — 2001-07-21T21:35:45Z

    > Upon review, I don't think these patches are very good at all.
    > #defining errno as WSAGetLastError() is a fairly blunt instrument,
    > and it breaks all the places that do actually need to use errno,
    > such as PQoidValue, lo_import, lo_export.  I'm also concerned that
    > PQrequestCancel may need to save/restore both errno and
    > WSAGetLastError() in order to be safe for use in a signal handler.
    > 
    > Is errno a plain variable on WIN32, or is it a macro?  If the former,
    > we could hack around this problem by doing
    > 
    > 	#if WIN32
    > 	#undef errno
    > 	#endif
    > 
    > 	...
    > 
    > 	#if WIN32
    > 	#define errno WSAGetLastError()
    > 	#endif
    > 
    > around the routines that need to access the real errno.  While ugly,
    > this probably beats the alternative of ifdef'ing all the places that
    > do need to access the WSA error code.
    
    At this point, I am just happy we have this WIN32 errno thing working. 
    We can now have people improve upon the implementation.
    
    I see the code in win32 you are complaining about:
    	
    	/*
    	 * assumes that errno is used for sockets only
    	 *
    	 */
    	
    	#undef errno
    	#undef EINTR
    	#undef EAGAIN   /* doesn't apply on sockets */
    	
    	#define errno WSAGetLastError()
    
    What we really need is for someone with Win32 access to figure out which
    errno tests are WSAGetLastError() calls and which are real errno calls. 
    
    My guess is that we should have two errno's.  One the normal errno that
    is the same on Win32 and Unix and a sockerrno that is conditionally
    defined:
    
    	#ifndef WIN32
    	#define sockerrno errno
    	#else
    	#define sockerrno WSAGetLastError()
    
    How does that work for folks?  Can someone do the legwork?
    
    See a later message on patches that reports problems with multibyte and
    Win32 in libpq.
    
    -- 
      Bruce Momjian                        |  http://candle.pha.pa.us
      pgman@candle.pha.pa.us               |  (610) 853-3000
      +  If your life is a hard drive,     |  830 Blythe Avenue
      +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
    
    
  4. Re: WIN32 errno patch

    Tom Lane <tgl@sss.pgh.pa.us> — 2001-07-21T22:09:28Z

    Bruce Momjian <pgman@candle.pha.pa.us> writes:
    > At this point, I am just happy we have this WIN32 errno thing working. 
    
    My point is that it isn't "working", it's broken.
    
    > My guess is that we should have two errno's.  One the normal errno that
    > is the same on Win32 and Unix and a sockerrno that is conditionally
    > defined:
    
    I don't really want to uglify the code by replacing most of the "errno"
    uses with "sockerrno".  People know what errno is, they don't know what
    "sockerrno" is, so we'd be reducing the readability of the code in order
    to cater to Windows cultural imperialism (usual M$ philosophy: embrace,
    extend, and make sure Windows-compatible code can't run anywhere else).
    
    Since there are only about three routines in libpq that need access to
    "regular" errno, it seems less invasive to #define errno for the rest
    of them, and do something special in just these places.
    
    			regards, tom lane
    
    
  5. Re: WIN32 errno patch

    Bruce Momjian <pgman@candle.pha.pa.us> — 2001-08-02T15:47:55Z

    Any idea where we are on this?
    
    
    > Bruce Momjian <pgman@candle.pha.pa.us> writes:
    > > At this point, I am just happy we have this WIN32 errno thing working. 
    > 
    > My point is that it isn't "working", it's broken.
    > 
    > > My guess is that we should have two errno's.  One the normal errno that
    > > is the same on Win32 and Unix and a sockerrno that is conditionally
    > > defined:
    > 
    > I don't really want to uglify the code by replacing most of the "errno"
    > uses with "sockerrno".  People know what errno is, they don't know what
    > "sockerrno" is, so we'd be reducing the readability of the code in order
    > to cater to Windows cultural imperialism (usual M$ philosophy: embrace,
    > extend, and make sure Windows-compatible code can't run anywhere else).
    > 
    > Since there are only about three routines in libpq that need access to
    > "regular" errno, it seems less invasive to #define errno for the rest
    > of them, and do something special in just these places.
    > 
    > 			regards, tom lane
    > 
    
    -- 
      Bruce Momjian                        |  http://candle.pha.pa.us
      pgman@candle.pha.pa.us               |  (610) 853-3000
      +  If your life is a hard drive,     |  830 Blythe Avenue
      +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
    
    
  6. Re: WIN32 errno patch

    Tom Lane <tgl@sss.pgh.pa.us> — 2001-08-02T16:11:01Z

    Bruce Momjian <pgman@candle.pha.pa.us> writes:
    > Any idea where we are on this?
    
    I'm planning to #undef errno around the three routines that need to get
    at plain errno.  Not done yet though...
    
    			regards, tom lane
    
    
  7. Re: Re: WIN32 errno patch

    Mikhail Terekhov <terekhov@emc.com> — 2001-08-09T19:08:12Z

    One can't just #undef errno on windows because it is defined as follows:
    
    
     #if defined(_MT) || defined(_DLL)
     extern int * __cdecl _errno(void);
     #define errno (*_errno())
     #else /* ndef _MT && ndef _DLL */
     extern int errno;
     #endif /* _MT || _DLL */
    
    So when building a dll or a multithreaded application it is not a plain 
    variable but call to the _errno() and after #undef errno one will lose 
    errno completely. For the same reason it is impossible to use something
    like 'errno=0;'.
    
    Mikhail Terekhov
    
    
    Tom Lane wrote:
    > 
    > Bruce Momjian <pgman@candle.pha.pa.us> writes:
    > > Any idea where we are on this?
    > 
    > I'm planning to #undef errno around the three routines that need to get
    > at plain errno.  Not done yet though...
    > 
    >                         regards, tom lane
    > 
    > ---------------------------(end of broadcast)---------------------------
    > TIP 2: you can get off all lists at once with the unregister command
    >     (send "unregister YourEmailAddressHere" to majordomo@postgresql.org)
    
    
  8. Re: Re: WIN32 errno patch

    Bruce Momjian <pgman@candle.pha.pa.us> — 2001-08-09T19:40:16Z

    Tom has applied these changes to the CVS snapshot.  Can you try it and
    let us know.
    
    > One can't just #undef errno on windows because it is defined as follows:
    > 
    > 
    >  #if defined(_MT) || defined(_DLL)
    >  extern int * __cdecl _errno(void);
    >  #define errno (*_errno())
    >  #else /* ndef _MT && ndef _DLL */
    >  extern int errno;
    >  #endif /* _MT || _DLL */
    > 
    > So when building a dll or a multithreaded application it is not a plain 
    > variable but call to the _errno() and after #undef errno one will lose 
    > errno completely. For the same reason it is impossible to use something
    > like 'errno=0;'.
    > 
    > Mikhail Terekhov
    > 
    > 
    > Tom Lane wrote:
    > > 
    > > Bruce Momjian <pgman@candle.pha.pa.us> writes:
    > > > Any idea where we are on this?
    > > 
    > > I'm planning to #undef errno around the three routines that need to get
    > > at plain errno.  Not done yet though...
    > > 
    > >                         regards, tom lane
    > > 
    > > ---------------------------(end of broadcast)---------------------------
    > > TIP 2: you can get off all lists at once with the unregister command
    > >     (send "unregister YourEmailAddressHere" to majordomo@postgresql.org)
    > 
    > ---------------------------(end of broadcast)---------------------------
    > TIP 2: you can get off all lists at once with the unregister command
    >     (send "unregister YourEmailAddressHere" to majordomo@postgresql.org)
    > 
    
    -- 
      Bruce Momjian                        |  http://candle.pha.pa.us
      pgman@candle.pha.pa.us               |  (610) 853-3000
      +  If your life is a hard drive,     |  830 Blythe Avenue
      +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
    
    
  9. Re: Re: WIN32 errno patch

    Tom Lane <tgl@sss.pgh.pa.us> — 2001-08-09T20:26:41Z

    Mikhail Terekhov <terekhov@emc.com> writes:
    > One can't just #undef errno on windows because it is defined as
    > follows:
    
    I was wondering if Windows might play any games with errno.  However,
    we've had at least one instance of "errno = 0;" in the libpq sources
    since 7.0 or before, and no one has complained that it doesn't build
    on Windows ... if errno is defined as a function call, that should
    yield a compile error, no?
    
    Also, the patch is already in place, and I have a report that it works.
    
    			regards, tom lane
    
    
  10. Re: WIN32 errno patch

    Ian Lance Taylor <ian@airs.com> — 2001-08-09T20:58:41Z

    Tom Lane <tgl@sss.pgh.pa.us> writes:
    
    > Mikhail Terekhov <terekhov@emc.com> writes:
    > > One can't just #undef errno on windows because it is defined as
    > > follows:
    > 
    > I was wondering if Windows might play any games with errno.  However,
    > we've had at least one instance of "errno = 0;" in the libpq sources
    > since 7.0 or before, and no one has complained that it doesn't build
    > on Windows ... if errno is defined as a function call, that should
    > yield a compile error, no?
    
    ANSI C requires that errno be a modifiable l-value.  I don't know of
    any system which breaks that rule.  In other words `errno = 0' is
    always OK on any system, assuming you have done `#include <errno.h>'.
    The statement may involve a function call, as in Mikhail's example:
     extern int * __cdecl _errno(void);
     #define errno (*_errno())
    
    I took a quick look at the current sources, and I have to admit that
    the `#undef errno' looks very dubious to me.  I see what the code is
    trying to do: win32.h #defines errno to simplify matters, but the
    simplification doesn't really work, so you have to #undef errno in a
    couple of places.  But this procedure can not work when errno is a
    macro already, as it is when compiling multi-threaded code on Windows.
    You wind up with the wrong value of errno after doing the #undef.
    
    So I think the current code is broken.  However, while I've done
    Windows development in the past, I don't have a Windows system now,
    and I haven't actually tested anything.
    
    I think the clean way to handle this is something along the lines of
    what the CVS client does.  On Unix, do this:
        #define SOCK_ERRNO errno
        #define SOCK_STRERROR strerror
    On Windows, do this:
        #define SOCK_ERRNO (WSAGetLastError ())
        #define SOCK_STRERROR sock_strerror
    (Then you have to write sock_strerror.)
    
    Then change any reference to errno after a socket call to use
    SOCK_ERRNO instead.
    
    Note that the current Postgres code appears broken in another way, as
    it passes WSAGetLastError() to strerror(), which doesn't work.
    However, I again have not tested anything here.
    
    Ian
    
    
  11. Re: WIN32 errno patch

    Tom Lane <tgl@sss.pgh.pa.us> — 2001-08-09T21:18:22Z

    Ian Lance Taylor <ian@airs.com> writes:
    > I think the clean way to handle this is something along the lines of
    > what the CVS client does.  On Unix, do this:
    >     #define SOCK_ERRNO errno
    >     #define SOCK_STRERROR strerror
    > On Windows, do this:
    >     #define SOCK_ERRNO (WSAGetLastError ())
    >     #define SOCK_STRERROR sock_strerror
    
    I've been trying to avoid uglifying the code like that, but perhaps
    we have no choice :-(.
    
    > (Then you have to write sock_strerror.)
    
    Surely Windows provides a suitable function?
    
    			regards, tom lane
    
    
  12. Re: Re: WIN32 errno patch

    Magnus Naeslund(f) <mag@fbab.net> — 2001-08-09T21:35:37Z

    From: "Ian Lance Taylor" <ian@airs.com>
    (snip)
    >     #define SOCK_STRERROR sock_strerror
    > (Then you have to write sock_strerror.)
    > 
    (snip)
    
    FormatMessage(...) is good for strerror(errno) emulation i think.
    bah.
    
    Magnus
    
    
    
  13. Re: Re: WIN32 errno patch

    Mikhail Terekhov <terekhov@emc.com> — 2001-08-09T22:34:23Z

    
    Tom Lane wrote:
    > 
    > Mikhail Terekhov <terekhov@emc.com> writes:
    > > One can't just #undef errno on windows because it is defined as
    > > follows:
    > 
    > I was wondering if Windows might play any games with errno.  However,
    > we've had at least one instance of "errno = 0;" in the libpq sources
    > since 7.0 or before, and no one has complained that it doesn't build
    > on Windows ... if errno is defined as a function call, that should
    > yield a compile error, no?
    > 
    
    It complains but only if you build a dll or multithreaded app.
    
    > Also, the patch is already in place, and I have a report that it works.
    > 
    
    It works only when compiling static apps I think.
    
    
    Regards,
    Mikhail Terekhov
    
    
  14. Re: Re: WIN32 errno patch

    Mikhail Terekhov <terekhov@emc.com> — 2001-08-09T22:42:23Z

    
    Bruce Momjian wrote:
    > 
    > Tom has applied these changes to the CVS snapshot.  Can you try it and
    > let us know.
    > 
    
    It does not even compile:
    
    Deleting intermediate files and output files for project 'libpqdll_current - Win32 Debug'.
    --------------------Configuration: libpqdll_current - Win32 Debug--------------------
    Compiling resources...
    Compiling...
    fe-auth.c
    c:\home\postgres\current\pgsql\src\interfaces\libpq\win32.h(34) : warning C4005: 'errno' : macro redefinition
            c:\program files\microsoft visual studio\vc98\include\stdlib.h(176) : see previous definition of 'errno'
    fe-connect.c
    c:\home\postgres\current\pgsql\src\interfaces\libpq\win32.h(34) : warning C4005: 'errno' : macro redefinition
            c:\program files\microsoft visual studio\vc98\include\stdlib.h(176) : see previous definition of 'errno'
    fe-exec.c
    c:\home\postgres\current\pgsql\src\interfaces\libpq\win32.h(34) : warning C4005: 'errno' : macro redefinition
            c:\program files\microsoft visual studio\vc98\include\stdlib.h(176) : see previous definition of 'errno'
    c:\home\postgres\current\pgsql\src\interfaces\libpq\fe-exec.c(2058) : error C2065: 'errno' : undeclared identifier
    fe-lobj.c
    c:\home\postgres\current\pgsql\src\interfaces\libpq\win32.h(34) : warning C4005: 'errno' : macro redefinition
            c:\program files\microsoft visual studio\vc98\include\stdlib.h(176) : see previous definition of 'errno'
    c:\home\postgres\current\pgsql\src\interfaces\libpq\fe-lobj.c(405) : error C2065: 'errno' : undeclared identifier
    fe-misc.c
    c:\home\postgres\current\pgsql\src\interfaces\libpq\win32.h(34) : warning C4005: 'errno' : macro redefinition
            c:\program files\microsoft visual studio\vc98\include\stdlib.h(176) : see previous definition of 'errno'
    c:\home\postgres\current\pgsql\src\interfaces\libpq\fe-misc.c(128) : warning C4018: '>' : signed/unsigned mismatch
    c:\home\postgres\current\pgsql\src\interfaces\libpq\fe-misc.c(219) : warning C4018: '>' : signed/unsigned mismatch
    fe-print.c
    c:\home\postgres\current\pgsql\src\interfaces\libpq\win32.h(34) : warning C4005: 'errno' : macro redefinition
            c:\program files\microsoft visual studio\vc98\include\stdlib.h(176) : see previous definition of 'errno'
    c:\home\postgres\current\pgsql\src\interfaces\libpq\fe-print.c(304) : warning C4090: 'function' : different 'const' qualifiers
    c:\home\postgres\current\pgsql\src\interfaces\libpq\fe-print.c(304) : warning C4022: 'free' : pointer mismatch for actual parameter 1
    libpqdll.c
    pqexpbuffer.c
    c:\home\postgres\current\pgsql\src\interfaces\libpq\win32.h(34) : warning C4005: 'errno' : macro redefinition
            c:\program files\microsoft visual studio\vc98\include\stdlib.h(176) : see previous definition of 'errno'
    c:\home\postgres\current\pgsql\src\interfaces\libpq\pqexpbuffer.c(195) : warning C4018: '<' : signed/unsigned mismatch
    c:\home\postgres\current\pgsql\src\interfaces\libpq\pqexpbuffer.c(244) : warning C4018: '<' : signed/unsigned mismatch
    pqsignal.c
    Error executing cl.exe.
    
    libpq.dll - 2 error(s), 13 warning(s)
    
    Regards,
    Mikhail Terekhov
    
    
  15. Re: WIN32 errno patch

    Ian Lance Taylor <ian@airs.com> — 2001-08-09T23:06:22Z

    Tom Lane <tgl@sss.pgh.pa.us> writes:
    
    > > (Then you have to write sock_strerror.)
    > 
    > Surely Windows provides a suitable function?
    
    Yes, but it doesn't have the same calling convention.
    
    Ian
    
    
  16. Re: Re: WIN32 errno patch

    Steve Howe <howe@carcass.dhs.org> — 2001-08-11T22:36:49Z

    "Mikhail Terekhov" <terekhov@emc.com> wrote in message
    news:3B7311CF.4D1CC8B2@emc.com...
    >
    >
    > Bruce Momjian wrote:
    > >
    > > Tom has applied these changes to the CVS snapshot.  Can you try it and
    > > let us know.
    > >
    >
    > It does not even compile:
    Same behaviour here. The last week's snapshots didn't compile on Windows, as
    I reported before...
    
    Best Regards,
    Steve Howe
    
    
    
    
  17. Re: Re: Re: WIN32 errno patch

    Tom Lane <tgl@sss.pgh.pa.us> — 2001-08-12T00:14:32Z

    >> It does not even compile:
    > Same behaviour here.
    
    When someone sends me a Windoze implementation of the proposed
    SOCK_STRERROR() macro, I'll see about fixing it.  Till then
    I can't do much.
    
    			regards, tom lane
    
    
  18. Re: WIN32 errno patch

    Mikhail Terekhov <terekhov@emc.com> — 2001-08-15T16:58:14Z

    
    Tom Lane wrote:
    > 
    > When someone sends me a Windoze implementation of the proposed
    > SOCK_STRERROR() macro, I'll see about fixing it.  Till then
    > I can't do much.
    > 
    >                         regards, tom lane
    > 
    
    Could you please review the following patch for libpq.
    I've implemented the SOCK_ERRNO macro only because
    both strerror and FormatMessage functions know nothing
    about sockets errors.
    I've compiled the current sources with this patch applied
    on windows and Solaris without problems and tested it through
    tcl interface only. It seems to work correctly - I could insert
    and select large strings (>10k).
    
    Regards
    Mikhail Terekhov
    
    
    Index: libpq/fe-connect.c
    ===================================================================
    RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v
    retrieving revision 1.172
    diff -C3 -r1.172 fe-connect.c
    *** libpq/fe-connect.c	2001/08/03 22:11:39	1.172
    --- libpq/fe-connect.c	2001/08/15 13:58:32
    ***************
    *** 711,717 ****
      	{
      		printfPQExpBuffer(&conn->errorMessage,
      						  libpq_gettext("could not set socket to non-blocking mode: %s\n"),
    ! 						  strerror(errno));
      		return 0;
      	}
      
    --- 711,717 ----
      	{
      		printfPQExpBuffer(&conn->errorMessage,
      						  libpq_gettext("could not set socket to non-blocking mode: %s\n"),
    ! 						  strerror(SOCK_ERRNO));
      		return 0;
      	}
      
    ***************
    *** 735,741 ****
      	{
      		printfPQExpBuffer(&conn->errorMessage,
      						  libpq_gettext("could not set socket to TCP no delay mode: %s\n"),
    ! 						  strerror(errno));
      		return 0;
      	}
      
    --- 735,741 ----
      	{
      		printfPQExpBuffer(&conn->errorMessage,
      						  libpq_gettext("could not set socket to TCP no delay mode: %s\n"),
    ! 						  strerror(SOCK_ERRNO));
      		return 0;
      	}
      
    ***************
    *** 890,896 ****
      	{
      		printfPQExpBuffer(&conn->errorMessage,
      						  libpq_gettext("could not create socket: %s\n"),
    ! 						  strerror(errno));
      		goto connect_errReturn;
      	}
      
    --- 890,896 ----
      	{
      		printfPQExpBuffer(&conn->errorMessage,
      						  libpq_gettext("could not create socket: %s\n"),
    ! 						  strerror(SOCK_ERRNO));
      		goto connect_errReturn;
      	}
      
    ***************
    *** 922,928 ****
      	 */
      	if (connect(conn->sock, &conn->raddr.sa, conn->raddr_len) < 0)
      	{
    ! 		if (errno == EINPROGRESS || errno == EWOULDBLOCK || errno == 0)
      		{
      			/*
      			 * This is fine - we're in non-blocking mode, and the
    --- 922,928 ----
      	 */
      	if (connect(conn->sock, &conn->raddr.sa, conn->raddr_len) < 0)
      	{
    ! 		if (SOCK_ERRNO == EINPROGRESS || SOCK_ERRNO == EWOULDBLOCK || errno == 0)
      		{
      			/*
      			 * This is fine - we're in non-blocking mode, and the
    ***************
    *** 933,939 ****
      		else
      		{
      			/* Something's gone wrong */
    ! 			connectFailureMessage(conn, errno);
      			goto connect_errReturn;
      		}
      	}
    --- 933,939 ----
      		else
      		{
      			/* Something's gone wrong */
    ! 			connectFailureMessage(conn, SOCK_ERRNO);
      			goto connect_errReturn;
      		}
      	}
    ***************
    *** 1212,1218 ****
      				{
      					printfPQExpBuffer(&conn->errorMessage,
      									  libpq_gettext("could not get socket error status: %s\n"),
    ! 									  strerror(errno));
      					goto error_return;
      				}
      				else if (optval != 0)
    --- 1212,1218 ----
      				{
      					printfPQExpBuffer(&conn->errorMessage,
      									  libpq_gettext("could not get socket error status: %s\n"),
    ! 									  strerror(SOCK_ERRNO));
      					goto error_return;
      				}
      				else if (optval != 0)
    ***************
    *** 1232,1238 ****
      				{
      					printfPQExpBuffer(&conn->errorMessage,
      									  libpq_gettext("could not get client address from socket: %s\n"),
    ! 									  strerror(errno));
      					goto error_return;
      				}
      
    --- 1232,1238 ----
      				{
      					printfPQExpBuffer(&conn->errorMessage,
      									  libpq_gettext("could not get client address from socket: %s\n"),
    ! 									  strerror(SOCK_ERRNO));
      					goto error_return;
      				}
      
    ***************
    *** 1271,1277 ****
      				{
      					printfPQExpBuffer(&conn->errorMessage,
      									  libpq_gettext("could not send startup packet: %s\n"),
    ! 									  strerror(errno));
      					goto error_return;
      				}
      
    --- 1271,1277 ----
      				{
      					printfPQExpBuffer(&conn->errorMessage,
      									  libpq_gettext("could not send startup packet: %s\n"),
    ! 									  strerror(SOCK_ERRNO));
      					goto error_return;
      				}
      
    ***************
    *** 2101,2107 ****
      int
      PQrequestCancel(PGconn *conn)
      {
    ! 	int			save_errno = errno;
      	int			tmpsock = -1;
      	struct
      	{
    --- 2101,2107 ----
      int
      PQrequestCancel(PGconn *conn)
      {
    ! 	int			save_errno = SOCK_ERRNO;
      	int			tmpsock = -1;
      	struct
      	{
    ***************
    *** 2173,2179 ****
      	return TRUE;
      
      cancel_errReturn:
    ! 	strcat(conn->errorMessage.data, strerror(errno));
      	strcat(conn->errorMessage.data, "\n");
      	conn->errorMessage.len = strlen(conn->errorMessage.data);
      	if (tmpsock >= 0)
    --- 2173,2179 ----
      	return TRUE;
      
      cancel_errReturn:
    ! 	strcat(conn->errorMessage.data, strerror(SOCK_ERRNO));
      	strcat(conn->errorMessage.data, "\n");
      	conn->errorMessage.len = strlen(conn->errorMessage.data);
      	if (tmpsock >= 0)
    Index: libpq/fe-exec.c
    ===================================================================
    RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v
    retrieving revision 1.105
    diff -C3 -r1.105 fe-exec.c
    *** libpq/fe-exec.c	2001/08/03 22:11:39	1.105
    --- libpq/fe-exec.c	2001/08/15 13:58:32
    ***************
    *** 2037,2046 ****
      	return buf;
      }
      
    - #ifdef WIN32					/* need to get at normal errno here */
    - #undef errno
    - #endif
    - 
      /*
        PQoidValue -
      		a perhaps preferable form of the above which just returns
    --- 2037,2042 ----
    ***************
    *** 2055,2061 ****
    --- 2051,2061 ----
      	if (!res || !res->cmdStatus || strncmp(res->cmdStatus, "INSERT ", 7) != 0)
      		return InvalidOid;
      
    + #ifdef WIN32
    +     SetLastError(0);
    + #else
      	errno = 0;
    + #endif
      	result = strtoul(res->cmdStatus + 7, &endptr, 10);
      
      	if (!endptr || (*endptr != ' ' && *endptr != '\0') || errno == ERANGE)
    ***************
    *** 2064,2072 ****
      		return (Oid) result;
      }
      
    - #ifdef WIN32					/* back to socket errno */
    - #define errno WSAGetLastError()
    - #endif
      
      /*
         PQcmdTuples -
    --- 2064,2069 ----
    Index: libpq/fe-lobj.c
    ===================================================================
    RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/libpq/fe-lobj.c,v
    retrieving revision 1.36
    diff -C3 -r1.36 fe-lobj.c
    *** libpq/fe-lobj.c	2001/08/03 22:11:39	1.36
    --- libpq/fe-lobj.c	2001/08/15 13:58:32
    ***************
    *** 30,41 ****
      
      #include "libpq/libpq-fs.h"		/* must come after sys/stat.h */
      
    - 
    - #ifdef WIN32					/* need to use normal errno in this file */
    - #undef errno
    - #endif
    - 
    - 
      #define LO_BUFSIZE		  8192
      
      static int	lo_initialize(PGconn *conn);
    --- 30,35 ----
    Index: libpq/fe-misc.c
    ===================================================================
    RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v
    retrieving revision 1.52
    diff -C3 -r1.52 fe-misc.c
    *** libpq/fe-misc.c	2001/07/20 17:45:06	1.52
    --- libpq/fe-misc.c	2001/08/15 13:58:32
    ***************
    *** 347,359 ****
      	if (select(conn->sock + 1, &input_mask, (fd_set *) NULL, (fd_set *) NULL,
      			   &timeout) < 0)
      	{
    ! 		if (errno == EINTR)
      			/* Interrupted system call - we'll just try again */
      			goto retry;
      
      		printfPQExpBuffer(&conn->errorMessage,
      						  libpq_gettext("select() failed: %s\n"),
    ! 						  strerror(errno));
      		return -1;
      	}
      
    --- 347,359 ----
      	if (select(conn->sock + 1, &input_mask, (fd_set *) NULL, (fd_set *) NULL,
      			   &timeout) < 0)
      	{
    ! 		if (SOCK_ERRNO == EINTR)
      			/* Interrupted system call - we'll just try again */
      			goto retry;
      
      		printfPQExpBuffer(&conn->errorMessage,
      						  libpq_gettext("select() failed: %s\n"),
    ! 						  strerror(SOCK_ERRNO));
      		return -1;
      	}
      
    ***************
    *** 381,393 ****
      	if (select(conn->sock + 1, (fd_set *) NULL, &input_mask, (fd_set *) NULL,
      			   &timeout) < 0)
      	{
    ! 		if (errno == EINTR)
      			/* Interrupted system call - we'll just try again */
      			goto retry;
      
      		printfPQExpBuffer(&conn->errorMessage,
      						  libpq_gettext("select() failed: %s\n"),
    ! 						  strerror(errno));
      		return -1;
      	}
      	return FD_ISSET(conn->sock, &input_mask) ? 1 : 0;
    --- 381,393 ----
      	if (select(conn->sock + 1, (fd_set *) NULL, &input_mask, (fd_set *) NULL,
      			   &timeout) < 0)
      	{
    ! 		if (SOCK_ERRNO == EINTR)
      			/* Interrupted system call - we'll just try again */
      			goto retry;
      
      		printfPQExpBuffer(&conn->errorMessage,
      						  libpq_gettext("select() failed: %s\n"),
    ! 						  strerror(SOCK_ERRNO));
      		return -1;
      	}
      	return FD_ISSET(conn->sock, &input_mask) ? 1 : 0;
    ***************
    *** 466,490 ****
      					 conn->inBufSize - conn->inEnd, 0);
      	if (nread < 0)
      	{
    ! 		if (errno == EINTR)
      			goto tryAgain;
      		/* Some systems return EAGAIN/EWOULDBLOCK for no data */
      #ifdef EAGAIN
    ! 		if (errno == EAGAIN)
      			return someread;
      #endif
      #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
    ! 		if (errno == EWOULDBLOCK)
      			return someread;
      #endif
      		/* We might get ECONNRESET here if using TCP and backend died */
      #ifdef ECONNRESET
    ! 		if (errno == ECONNRESET)
      			goto definitelyFailed;
      #endif
      		printfPQExpBuffer(&conn->errorMessage,
      						  libpq_gettext("could not receive data from server: %s\n"),
    ! 						  strerror(errno));
      		return -1;
      	}
      	if (nread > 0)
    --- 466,490 ----
      					 conn->inBufSize - conn->inEnd, 0);
      	if (nread < 0)
      	{
    ! 		if (SOCK_ERRNO == EINTR)
      			goto tryAgain;
      		/* Some systems return EAGAIN/EWOULDBLOCK for no data */
      #ifdef EAGAIN
    ! 		if (SOCK_ERRNO == EAGAIN)
      			return someread;
      #endif
      #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
    ! 		if (SOCK_ERRNO == EWOULDBLOCK)
      			return someread;
      #endif
      		/* We might get ECONNRESET here if using TCP and backend died */
      #ifdef ECONNRESET
    ! 		if (SOCK_ERRNO == ECONNRESET)
      			goto definitelyFailed;
      #endif
      		printfPQExpBuffer(&conn->errorMessage,
      						  libpq_gettext("could not receive data from server: %s\n"),
    ! 						  strerror(SOCK_ERRNO));
      		return -1;
      	}
      	if (nread > 0)
    ***************
    *** 552,576 ****
      					 conn->inBufSize - conn->inEnd, 0);
      	if (nread < 0)
      	{
    ! 		if (errno == EINTR)
      			goto tryAgain2;
      		/* Some systems return EAGAIN/EWOULDBLOCK for no data */
      #ifdef EAGAIN
    ! 		if (errno == EAGAIN)
      			return 0;
      #endif
      #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
    ! 		if (errno == EWOULDBLOCK)
      			return 0;
      #endif
      		/* We might get ECONNRESET here if using TCP and backend died */
      #ifdef ECONNRESET
    ! 		if (errno == ECONNRESET)
      			goto definitelyFailed;
      #endif
      		printfPQExpBuffer(&conn->errorMessage,
      						  libpq_gettext("could not receive data from server: %s\n"),
    ! 						  strerror(errno));
      		return -1;
      	}
      	if (nread > 0)
    --- 552,576 ----
      					 conn->inBufSize - conn->inEnd, 0);
      	if (nread < 0)
      	{
    ! 		if (SOCK_ERRNO == EINTR)
      			goto tryAgain2;
      		/* Some systems return EAGAIN/EWOULDBLOCK for no data */
      #ifdef EAGAIN
    ! 		if (SOCK_ERRNO == EAGAIN)
      			return 0;
      #endif
      #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
    ! 		if (SOCK_ERRNO == EWOULDBLOCK)
      			return 0;
      #endif
      		/* We might get ECONNRESET here if using TCP and backend died */
      #ifdef ECONNRESET
    ! 		if (SOCK_ERRNO == ECONNRESET)
      			goto definitelyFailed;
      #endif
      		printfPQExpBuffer(&conn->errorMessage,
      						  libpq_gettext("could not receive data from server: %s\n"),
    ! 						  strerror(SOCK_ERRNO));
      		return -1;
      	}
      	if (nread > 0)
    ***************
    *** 652,658 ****
      			 * EPIPE or ECONNRESET, assume we've lost the backend
      			 * connection permanently.
      			 */
    ! 			switch (errno)
      			{
      #ifdef EAGAIN
      				case EAGAIN:
    --- 652,658 ----
      			 * EPIPE or ECONNRESET, assume we've lost the backend
      			 * connection permanently.
      			 */
    ! 			switch (SOCK_ERRNO)
      			{
      #ifdef EAGAIN
      				case EAGAIN:
    ***************
    *** 688,694 ****
      				default:
      					printfPQExpBuffer(&conn->errorMessage,
      									  libpq_gettext("could not send data to server: %s\n"),
    ! 									  strerror(errno));
      					/* We don't assume it's a fatal error... */
      					return EOF;
      			}
    --- 688,694 ----
      				default:
      					printfPQExpBuffer(&conn->errorMessage,
      									  libpq_gettext("could not send data to server: %s\n"),
    ! 									  strerror(SOCK_ERRNO));
      					/* We don't assume it's a fatal error... */
      					return EOF;
      			}
    ***************
    *** 771,781 ****
      		if (select(conn->sock + 1, &input_mask, &output_mask, &except_mask,
      				   (struct timeval *) NULL) < 0)
      		{
    ! 			if (errno == EINTR)
      				goto retry;
      			printfPQExpBuffer(&conn->errorMessage,
      							  libpq_gettext("select() failed: %s\n"),
    ! 							  strerror(errno));
      			return EOF;
      		}
      	}
    --- 771,781 ----
      		if (select(conn->sock + 1, &input_mask, &output_mask, &except_mask,
      				   (struct timeval *) NULL) < 0)
      		{
    ! 			if (SOCK_ERRNO == EINTR)
      				goto retry;
      			printfPQExpBuffer(&conn->errorMessage,
      							  libpq_gettext("select() failed: %s\n"),
    ! 							  strerror(SOCK_ERRNO));
      			return EOF;
      		}
      	}
    Index: libpq/libpq-fe.h
    ===================================================================
    RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/libpq/libpq-fe.h,v
    retrieving revision 1.71
    diff -C3 -r1.71 libpq-fe.h
    *** libpq/libpq-fe.h	2001/03/22 04:01:27	1.71
    --- libpq/libpq-fe.h	2001/08/15 13:58:32
    ***************
    *** 21,30 ****
    --- 21,39 ----
      #endif
      
      #include <stdio.h>
    + 
    + #ifdef WIN32
    +     #define SOCK_ERRNO (WSAGetLastError ())
    + #else
    +     #define SOCK_ERRNO errno
    + #endif
    + 
    + 
      /* postgres_ext.h defines the backend's externally visible types,
       * such as Oid.
       */
      #include "postgres_ext.h"
    + 
      #ifdef USE_SSL
      #include <openssl/ssl.h>
      #endif
    Index: libpq/win32.h
    ===================================================================
    RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/libpq/win32.h,v
    retrieving revision 1.15
    diff -C3 -r1.15 win32.h
    *** libpq/win32.h	2001/08/03 22:11:39	1.15
    --- libpq/win32.h	2001/08/15 13:58:32
    ***************
    *** 23,38 ****
       */
      #define crypt(a,b) (a)
      
    - /*
    -  * Most of libpq uses "errno" to access error conditions from socket calls,
    -  * so on Windows we want to redirect those usages to WSAGetLastError().
    -  * Rather than #ifdef'ing every single place that has "errno", hack it up
    -  * with a macro instead.  But there are a few places that do need to touch
    -  * the regular errno variable.  For them, we #undef and then redefine errno.
    -  */
    - 
    - #define errno WSAGetLastError()
    - 
      #undef EAGAIN	/* doesn't apply on sockets */
      #undef EINTR
      #define EINTR WSAEINTR
    --- 23,28 ----
    
    
  19. Re: [HACKERS] Re: WIN32 errno patch

    Bruce Momjian <pgman@candle.pha.pa.us> — 2001-08-17T14:47:49Z

    Your patch has been added to the PostgreSQL unapplied patches list at:
    
    	http://candle.pha.pa.us/cgi-bin/pgpatches
    
    I will try to apply it within the next 48 hours.
    
    > 
    > 
    > Tom Lane wrote:
    > > 
    > > When someone sends me a Windoze implementation of the proposed
    > > SOCK_STRERROR() macro, I'll see about fixing it.  Till then
    > > I can't do much.
    > > 
    > >                         regards, tom lane
    > > 
    > 
    > Could you please review the following patch for libpq.
    > I've implemented the SOCK_ERRNO macro only because
    > both strerror and FormatMessage functions know nothing
    > about sockets errors.
    > I've compiled the current sources with this patch applied
    > on windows and Solaris without problems and tested it through
    > tcl interface only. It seems to work correctly - I could insert
    > and select large strings (>10k).
    > 
    > Regards
    > Mikhail Terekhov
    > 
    > 
    > Index: libpq/fe-connect.c
    > ===================================================================
    > RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v
    > retrieving revision 1.172
    > diff -C3 -r1.172 fe-connect.c
    > *** libpq/fe-connect.c	2001/08/03 22:11:39	1.172
    > --- libpq/fe-connect.c	2001/08/15 13:58:32
    > ***************
    > *** 711,717 ****
    >   	{
    >   		printfPQExpBuffer(&conn->errorMessage,
    >   						  libpq_gettext("could not set socket to non-blocking mode: %s\n"),
    > ! 						  strerror(errno));
    >   		return 0;
    >   	}
    >   
    > --- 711,717 ----
    >   	{
    >   		printfPQExpBuffer(&conn->errorMessage,
    >   						  libpq_gettext("could not set socket to non-blocking mode: %s\n"),
    > ! 						  strerror(SOCK_ERRNO));
    >   		return 0;
    >   	}
    >   
    > ***************
    > *** 735,741 ****
    >   	{
    >   		printfPQExpBuffer(&conn->errorMessage,
    >   						  libpq_gettext("could not set socket to TCP no delay mode: %s\n"),
    > ! 						  strerror(errno));
    >   		return 0;
    >   	}
    >   
    > --- 735,741 ----
    >   	{
    >   		printfPQExpBuffer(&conn->errorMessage,
    >   						  libpq_gettext("could not set socket to TCP no delay mode: %s\n"),
    > ! 						  strerror(SOCK_ERRNO));
    >   		return 0;
    >   	}
    >   
    > ***************
    > *** 890,896 ****
    >   	{
    >   		printfPQExpBuffer(&conn->errorMessage,
    >   						  libpq_gettext("could not create socket: %s\n"),
    > ! 						  strerror(errno));
    >   		goto connect_errReturn;
    >   	}
    >   
    > --- 890,896 ----
    >   	{
    >   		printfPQExpBuffer(&conn->errorMessage,
    >   						  libpq_gettext("could not create socket: %s\n"),
    > ! 						  strerror(SOCK_ERRNO));
    >   		goto connect_errReturn;
    >   	}
    >   
    > ***************
    > *** 922,928 ****
    >   	 */
    >   	if (connect(conn->sock, &conn->raddr.sa, conn->raddr_len) < 0)
    >   	{
    > ! 		if (errno == EINPROGRESS || errno == EWOULDBLOCK || errno == 0)
    >   		{
    >   			/*
    >   			 * This is fine - we're in non-blocking mode, and the
    > --- 922,928 ----
    >   	 */
    >   	if (connect(conn->sock, &conn->raddr.sa, conn->raddr_len) < 0)
    >   	{
    > ! 		if (SOCK_ERRNO == EINPROGRESS || SOCK_ERRNO == EWOULDBLOCK || errno == 0)
    >   		{
    >   			/*
    >   			 * This is fine - we're in non-blocking mode, and the
    > ***************
    > *** 933,939 ****
    >   		else
    >   		{
    >   			/* Something's gone wrong */
    > ! 			connectFailureMessage(conn, errno);
    >   			goto connect_errReturn;
    >   		}
    >   	}
    > --- 933,939 ----
    >   		else
    >   		{
    >   			/* Something's gone wrong */
    > ! 			connectFailureMessage(conn, SOCK_ERRNO);
    >   			goto connect_errReturn;
    >   		}
    >   	}
    > ***************
    > *** 1212,1218 ****
    >   				{
    >   					printfPQExpBuffer(&conn->errorMessage,
    >   									  libpq_gettext("could not get socket error status: %s\n"),
    > ! 									  strerror(errno));
    >   					goto error_return;
    >   				}
    >   				else if (optval != 0)
    > --- 1212,1218 ----
    >   				{
    >   					printfPQExpBuffer(&conn->errorMessage,
    >   									  libpq_gettext("could not get socket error status: %s\n"),
    > ! 									  strerror(SOCK_ERRNO));
    >   					goto error_return;
    >   				}
    >   				else if (optval != 0)
    > ***************
    > *** 1232,1238 ****
    >   				{
    >   					printfPQExpBuffer(&conn->errorMessage,
    >   									  libpq_gettext("could not get client address from socket: %s\n"),
    > ! 									  strerror(errno));
    >   					goto error_return;
    >   				}
    >   
    > --- 1232,1238 ----
    >   				{
    >   					printfPQExpBuffer(&conn->errorMessage,
    >   									  libpq_gettext("could not get client address from socket: %s\n"),
    > ! 									  strerror(SOCK_ERRNO));
    >   					goto error_return;
    >   				}
    >   
    > ***************
    > *** 1271,1277 ****
    >   				{
    >   					printfPQExpBuffer(&conn->errorMessage,
    >   									  libpq_gettext("could not send startup packet: %s\n"),
    > ! 									  strerror(errno));
    >   					goto error_return;
    >   				}
    >   
    > --- 1271,1277 ----
    >   				{
    >   					printfPQExpBuffer(&conn->errorMessage,
    >   									  libpq_gettext("could not send startup packet: %s\n"),
    > ! 									  strerror(SOCK_ERRNO));
    >   					goto error_return;
    >   				}
    >   
    > ***************
    > *** 2101,2107 ****
    >   int
    >   PQrequestCancel(PGconn *conn)
    >   {
    > ! 	int			save_errno = errno;
    >   	int			tmpsock = -1;
    >   	struct
    >   	{
    > --- 2101,2107 ----
    >   int
    >   PQrequestCancel(PGconn *conn)
    >   {
    > ! 	int			save_errno = SOCK_ERRNO;
    >   	int			tmpsock = -1;
    >   	struct
    >   	{
    > ***************
    > *** 2173,2179 ****
    >   	return TRUE;
    >   
    >   cancel_errReturn:
    > ! 	strcat(conn->errorMessage.data, strerror(errno));
    >   	strcat(conn->errorMessage.data, "\n");
    >   	conn->errorMessage.len = strlen(conn->errorMessage.data);
    >   	if (tmpsock >= 0)
    > --- 2173,2179 ----
    >   	return TRUE;
    >   
    >   cancel_errReturn:
    > ! 	strcat(conn->errorMessage.data, strerror(SOCK_ERRNO));
    >   	strcat(conn->errorMessage.data, "\n");
    >   	conn->errorMessage.len = strlen(conn->errorMessage.data);
    >   	if (tmpsock >= 0)
    > Index: libpq/fe-exec.c
    > ===================================================================
    > RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v
    > retrieving revision 1.105
    > diff -C3 -r1.105 fe-exec.c
    > *** libpq/fe-exec.c	2001/08/03 22:11:39	1.105
    > --- libpq/fe-exec.c	2001/08/15 13:58:32
    > ***************
    > *** 2037,2046 ****
    >   	return buf;
    >   }
    >   
    > - #ifdef WIN32					/* need to get at normal errno here */
    > - #undef errno
    > - #endif
    > - 
    >   /*
    >     PQoidValue -
    >   		a perhaps preferable form of the above which just returns
    > --- 2037,2042 ----
    > ***************
    > *** 2055,2061 ****
    > --- 2051,2061 ----
    >   	if (!res || !res->cmdStatus || strncmp(res->cmdStatus, "INSERT ", 7) != 0)
    >   		return InvalidOid;
    >   
    > + #ifdef WIN32
    > +     SetLastError(0);
    > + #else
    >   	errno = 0;
    > + #endif
    >   	result = strtoul(res->cmdStatus + 7, &endptr, 10);
    >   
    >   	if (!endptr || (*endptr != ' ' && *endptr != '\0') || errno == ERANGE)
    > ***************
    > *** 2064,2072 ****
    >   		return (Oid) result;
    >   }
    >   
    > - #ifdef WIN32					/* back to socket errno */
    > - #define errno WSAGetLastError()
    > - #endif
    >   
    >   /*
    >      PQcmdTuples -
    > --- 2064,2069 ----
    > Index: libpq/fe-lobj.c
    > ===================================================================
    > RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/libpq/fe-lobj.c,v
    > retrieving revision 1.36
    > diff -C3 -r1.36 fe-lobj.c
    > *** libpq/fe-lobj.c	2001/08/03 22:11:39	1.36
    > --- libpq/fe-lobj.c	2001/08/15 13:58:32
    > ***************
    > *** 30,41 ****
    >   
    >   #include "libpq/libpq-fs.h"		/* must come after sys/stat.h */
    >   
    > - 
    > - #ifdef WIN32					/* need to use normal errno in this file */
    > - #undef errno
    > - #endif
    > - 
    > - 
    >   #define LO_BUFSIZE		  8192
    >   
    >   static int	lo_initialize(PGconn *conn);
    > --- 30,35 ----
    > Index: libpq/fe-misc.c
    > ===================================================================
    > RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v
    > retrieving revision 1.52
    > diff -C3 -r1.52 fe-misc.c
    > *** libpq/fe-misc.c	2001/07/20 17:45:06	1.52
    > --- libpq/fe-misc.c	2001/08/15 13:58:32
    > ***************
    > *** 347,359 ****
    >   	if (select(conn->sock + 1, &input_mask, (fd_set *) NULL, (fd_set *) NULL,
    >   			   &timeout) < 0)
    >   	{
    > ! 		if (errno == EINTR)
    >   			/* Interrupted system call - we'll just try again */
    >   			goto retry;
    >   
    >   		printfPQExpBuffer(&conn->errorMessage,
    >   						  libpq_gettext("select() failed: %s\n"),
    > ! 						  strerror(errno));
    >   		return -1;
    >   	}
    >   
    > --- 347,359 ----
    >   	if (select(conn->sock + 1, &input_mask, (fd_set *) NULL, (fd_set *) NULL,
    >   			   &timeout) < 0)
    >   	{
    > ! 		if (SOCK_ERRNO == EINTR)
    >   			/* Interrupted system call - we'll just try again */
    >   			goto retry;
    >   
    >   		printfPQExpBuffer(&conn->errorMessage,
    >   						  libpq_gettext("select() failed: %s\n"),
    > ! 						  strerror(SOCK_ERRNO));
    >   		return -1;
    >   	}
    >   
    > ***************
    > *** 381,393 ****
    >   	if (select(conn->sock + 1, (fd_set *) NULL, &input_mask, (fd_set *) NULL,
    >   			   &timeout) < 0)
    >   	{
    > ! 		if (errno == EINTR)
    >   			/* Interrupted system call - we'll just try again */
    >   			goto retry;
    >   
    >   		printfPQExpBuffer(&conn->errorMessage,
    >   						  libpq_gettext("select() failed: %s\n"),
    > ! 						  strerror(errno));
    >   		return -1;
    >   	}
    >   	return FD_ISSET(conn->sock, &input_mask) ? 1 : 0;
    > --- 381,393 ----
    >   	if (select(conn->sock + 1, (fd_set *) NULL, &input_mask, (fd_set *) NULL,
    >   			   &timeout) < 0)
    >   	{
    > ! 		if (SOCK_ERRNO == EINTR)
    >   			/* Interrupted system call - we'll just try again */
    >   			goto retry;
    >   
    >   		printfPQExpBuffer(&conn->errorMessage,
    >   						  libpq_gettext("select() failed: %s\n"),
    > ! 						  strerror(SOCK_ERRNO));
    >   		return -1;
    >   	}
    >   	return FD_ISSET(conn->sock, &input_mask) ? 1 : 0;
    > ***************
    > *** 466,490 ****
    >   					 conn->inBufSize - conn->inEnd, 0);
    >   	if (nread < 0)
    >   	{
    > ! 		if (errno == EINTR)
    >   			goto tryAgain;
    >   		/* Some systems return EAGAIN/EWOULDBLOCK for no data */
    >   #ifdef EAGAIN
    > ! 		if (errno == EAGAIN)
    >   			return someread;
    >   #endif
    >   #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
    > ! 		if (errno == EWOULDBLOCK)
    >   			return someread;
    >   #endif
    >   		/* We might get ECONNRESET here if using TCP and backend died */
    >   #ifdef ECONNRESET
    > ! 		if (errno == ECONNRESET)
    >   			goto definitelyFailed;
    >   #endif
    >   		printfPQExpBuffer(&conn->errorMessage,
    >   						  libpq_gettext("could not receive data from server: %s\n"),
    > ! 						  strerror(errno));
    >   		return -1;
    >   	}
    >   	if (nread > 0)
    > --- 466,490 ----
    >   					 conn->inBufSize - conn->inEnd, 0);
    >   	if (nread < 0)
    >   	{
    > ! 		if (SOCK_ERRNO == EINTR)
    >   			goto tryAgain;
    >   		/* Some systems return EAGAIN/EWOULDBLOCK for no data */
    >   #ifdef EAGAIN
    > ! 		if (SOCK_ERRNO == EAGAIN)
    >   			return someread;
    >   #endif
    >   #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
    > ! 		if (SOCK_ERRNO == EWOULDBLOCK)
    >   			return someread;
    >   #endif
    >   		/* We might get ECONNRESET here if using TCP and backend died */
    >   #ifdef ECONNRESET
    > ! 		if (SOCK_ERRNO == ECONNRESET)
    >   			goto definitelyFailed;
    >   #endif
    >   		printfPQExpBuffer(&conn->errorMessage,
    >   						  libpq_gettext("could not receive data from server: %s\n"),
    > ! 						  strerror(SOCK_ERRNO));
    >   		return -1;
    >   	}
    >   	if (nread > 0)
    > ***************
    > *** 552,576 ****
    >   					 conn->inBufSize - conn->inEnd, 0);
    >   	if (nread < 0)
    >   	{
    > ! 		if (errno == EINTR)
    >   			goto tryAgain2;
    >   		/* Some systems return EAGAIN/EWOULDBLOCK for no data */
    >   #ifdef EAGAIN
    > ! 		if (errno == EAGAIN)
    >   			return 0;
    >   #endif
    >   #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
    > ! 		if (errno == EWOULDBLOCK)
    >   			return 0;
    >   #endif
    >   		/* We might get ECONNRESET here if using TCP and backend died */
    >   #ifdef ECONNRESET
    > ! 		if (errno == ECONNRESET)
    >   			goto definitelyFailed;
    >   #endif
    >   		printfPQExpBuffer(&conn->errorMessage,
    >   						  libpq_gettext("could not receive data from server: %s\n"),
    > ! 						  strerror(errno));
    >   		return -1;
    >   	}
    >   	if (nread > 0)
    > --- 552,576 ----
    >   					 conn->inBufSize - conn->inEnd, 0);
    >   	if (nread < 0)
    >   	{
    > ! 		if (SOCK_ERRNO == EINTR)
    >   			goto tryAgain2;
    >   		/* Some systems return EAGAIN/EWOULDBLOCK for no data */
    >   #ifdef EAGAIN
    > ! 		if (SOCK_ERRNO == EAGAIN)
    >   			return 0;
    >   #endif
    >   #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
    > ! 		if (SOCK_ERRNO == EWOULDBLOCK)
    >   			return 0;
    >   #endif
    >   		/* We might get ECONNRESET here if using TCP and backend died */
    >   #ifdef ECONNRESET
    > ! 		if (SOCK_ERRNO == ECONNRESET)
    >   			goto definitelyFailed;
    >   #endif
    >   		printfPQExpBuffer(&conn->errorMessage,
    >   						  libpq_gettext("could not receive data from server: %s\n"),
    > ! 						  strerror(SOCK_ERRNO));
    >   		return -1;
    >   	}
    >   	if (nread > 0)
    > ***************
    > *** 652,658 ****
    >   			 * EPIPE or ECONNRESET, assume we've lost the backend
    >   			 * connection permanently.
    >   			 */
    > ! 			switch (errno)
    >   			{
    >   #ifdef EAGAIN
    >   				case EAGAIN:
    > --- 652,658 ----
    >   			 * EPIPE or ECONNRESET, assume we've lost the backend
    >   			 * connection permanently.
    >   			 */
    > ! 			switch (SOCK_ERRNO)
    >   			{
    >   #ifdef EAGAIN
    >   				case EAGAIN:
    > ***************
    > *** 688,694 ****
    >   				default:
    >   					printfPQExpBuffer(&conn->errorMessage,
    >   									  libpq_gettext("could not send data to server: %s\n"),
    > ! 									  strerror(errno));
    >   					/* We don't assume it's a fatal error... */
    >   					return EOF;
    >   			}
    > --- 688,694 ----
    >   				default:
    >   					printfPQExpBuffer(&conn->errorMessage,
    >   									  libpq_gettext("could not send data to server: %s\n"),
    > ! 									  strerror(SOCK_ERRNO));
    >   					/* We don't assume it's a fatal error... */
    >   					return EOF;
    >   			}
    > ***************
    > *** 771,781 ****
    >   		if (select(conn->sock + 1, &input_mask, &output_mask, &except_mask,
    >   				   (struct timeval *) NULL) < 0)
    >   		{
    > ! 			if (errno == EINTR)
    >   				goto retry;
    >   			printfPQExpBuffer(&conn->errorMessage,
    >   							  libpq_gettext("select() failed: %s\n"),
    > ! 							  strerror(errno));
    >   			return EOF;
    >   		}
    >   	}
    > --- 771,781 ----
    >   		if (select(conn->sock + 1, &input_mask, &output_mask, &except_mask,
    >   				   (struct timeval *) NULL) < 0)
    >   		{
    > ! 			if (SOCK_ERRNO == EINTR)
    >   				goto retry;
    >   			printfPQExpBuffer(&conn->errorMessage,
    >   							  libpq_gettext("select() failed: %s\n"),
    > ! 							  strerror(SOCK_ERRNO));
    >   			return EOF;
    >   		}
    >   	}
    > Index: libpq/libpq-fe.h
    > ===================================================================
    > RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/libpq/libpq-fe.h,v
    > retrieving revision 1.71
    > diff -C3 -r1.71 libpq-fe.h
    > *** libpq/libpq-fe.h	2001/03/22 04:01:27	1.71
    > --- libpq/libpq-fe.h	2001/08/15 13:58:32
    > ***************
    > *** 21,30 ****
    > --- 21,39 ----
    >   #endif
    >   
    >   #include <stdio.h>
    > + 
    > + #ifdef WIN32
    > +     #define SOCK_ERRNO (WSAGetLastError ())
    > + #else
    > +     #define SOCK_ERRNO errno
    > + #endif
    > + 
    > + 
    >   /* postgres_ext.h defines the backend's externally visible types,
    >    * such as Oid.
    >    */
    >   #include "postgres_ext.h"
    > + 
    >   #ifdef USE_SSL
    >   #include <openssl/ssl.h>
    >   #endif
    > Index: libpq/win32.h
    > ===================================================================
    > RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/libpq/win32.h,v
    > retrieving revision 1.15
    > diff -C3 -r1.15 win32.h
    > *** libpq/win32.h	2001/08/03 22:11:39	1.15
    > --- libpq/win32.h	2001/08/15 13:58:32
    > ***************
    > *** 23,38 ****
    >    */
    >   #define crypt(a,b) (a)
    >   
    > - /*
    > -  * Most of libpq uses "errno" to access error conditions from socket calls,
    > -  * so on Windows we want to redirect those usages to WSAGetLastError().
    > -  * Rather than #ifdef'ing every single place that has "errno", hack it up
    > -  * with a macro instead.  But there are a few places that do need to touch
    > -  * the regular errno variable.  For them, we #undef and then redefine errno.
    > -  */
    > - 
    > - #define errno WSAGetLastError()
    > - 
    >   #undef EAGAIN	/* doesn't apply on sockets */
    >   #undef EINTR
    >   #define EINTR WSAEINTR
    > --- 23,28 ----
    > 
    > ---------------------------(end of broadcast)---------------------------
    > TIP 5: Have you checked our extensive FAQ?
    > 
    > http://www.postgresql.org/users-lounge/docs/faq.html
    > 
    
    -- 
      Bruce Momjian                        |  http://candle.pha.pa.us
      pgman@candle.pha.pa.us               |  (610) 853-3000
      +  If your life is a hard drive,     |  830 Blythe Avenue
      +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
    
    
  20. Re: Re: [HACKERS] Re: WIN32 errno patch

    Tom Lane <tgl@sss.pgh.pa.us> — 2001-08-17T15:38:09Z

    Bruce Momjian <pgman@candle.pha.pa.us> writes:
    > I will try to apply it within the next 48 hours.
    
    This isn't the right patch to apply, since Mikhail didn't fix the
    strerror problem.  I have some code from Magnus Naeslund that purports
    to handle the strerror issue, and will work it up into a patch real soon
    now.
    
    >> I've implemented the SOCK_ERRNO macro only because
    >> both strerror and FormatMessage functions know nothing
    >> about sockets errors.
    
    FWIW, Magnus says this works:
    
    #define SOCK_STRERROR my_sock_strerror
    
    const char* my_sock_strerror(unsigned long eno){
        static char buf[512]; // i know, not threadsafe
        if (!FormatMessage( 
                FORMAT_MESSAGE_FROM_SYSTEM | 
                FORMAT_MESSAGE_IGNORE_INSERTS,
                0,eno,
                MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                buf,sizeof(buf)-1,
                0
               )){
          sprintf(buf,"Unknown socket error(%u)",eno);
        }
        buf[sizeof(buf)-1]='\0';
        return buf;
    }
    
    
    Anyone have any objections to it?
    
    			regards, tom lane
    
    
  21. Re: Re: [HACKERS] Re: WIN32 errno patch

    Bruce Momjian <pgman@candle.pha.pa.us> — 2001-08-17T15:38:58Z

    OK.  Patch removed.
    
    > Bruce Momjian <pgman@candle.pha.pa.us> writes:
    > > I will try to apply it within the next 48 hours.
    > 
    > This isn't the right patch to apply, since Mikhail didn't fix the
    > strerror problem.  I have some code from Magnus Naeslund that purports
    > to handle the strerror issue, and will work it up into a patch real soon
    > now.
    > 
    > >> I've implemented the SOCK_ERRNO macro only because
    > >> both strerror and FormatMessage functions know nothing
    > >> about sockets errors.
    > 
    > FWIW, Magnus says this works:
    > 
    > #define SOCK_STRERROR my_sock_strerror
    > 
    > const char* my_sock_strerror(unsigned long eno){
    >     static char buf[512]; // i know, not threadsafe
    >     if (!FormatMessage( 
    >             FORMAT_MESSAGE_FROM_SYSTEM | 
    >             FORMAT_MESSAGE_IGNORE_INSERTS,
    >             0,eno,
    >             MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
    >             buf,sizeof(buf)-1,
    >             0
    >            )){
    >       sprintf(buf,"Unknown socket error(%u)",eno);
    >     }
    >     buf[sizeof(buf)-1]='\0';
    >     return buf;
    > }
    > 
    > 
    > Anyone have any objections to it?
    > 
    > 			regards, tom lane
    > 
    
    -- 
      Bruce Momjian                        |  http://candle.pha.pa.us
      pgman@candle.pha.pa.us               |  (610) 853-3000
      +  If your life is a hard drive,     |  830 Blythe Avenue
      +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
    
    
  22. Re: [HACKERS] Re: WIN32 errno patch

    Mikhail Terekhov <terekhov@emc.com> — 2001-08-17T18:51:59Z

    
    Tom Lane wrote:
    > 
    > Bruce Momjian <pgman@candle.pha.pa.us> writes:
    > > I will try to apply it within the next 48 hours.
    > 
    > This isn't the right patch to apply, since Mikhail didn't fix the
    > strerror problem.  I have some code from Magnus Naeslund that purports
    > to handle the strerror issue, and will work it up into a patch real soon
    > now.
    > 
    > >> I've implemented the SOCK_ERRNO macro only because
    > >> both strerror and FormatMessage functions know nothing
    > >> about sockets errors.
    > 
    > FWIW, Magnus says this works:
    > 
    > #define SOCK_STRERROR my_sock_strerror
    > 
    > const char* my_sock_strerror(unsigned long eno){
    >     static char buf[512]; // i know, not threadsafe
    >     if (!FormatMessage(
    >             FORMAT_MESSAGE_FROM_SYSTEM |
    >             FORMAT_MESSAGE_IGNORE_INSERTS,
    >             0,eno,
    >             MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
    >             buf,sizeof(buf)-1,
    >             0
    >            )){
    >       sprintf(buf,"Unknown socket error(%u)",eno);
    >     }
    >     buf[sizeof(buf)-1]='\0';
    >     return buf;
    > }
    > 
    > Anyone have any objections to it?
    > 
    
    On my system (NT4 sp.6, VC6.0) the FormatMessage function always
    returns 0 for errno in the [10000 - 10100] range (winsock errors).
    That's why i've wrote that this function knows nothing about
    sockets errors. Using this function looks very impressive but the
    net result is null. If Magnus could get some meaningfull messages
    for winsock errors from FormatMessage I'd be glad to know what is
    missing from my setup.
    
    Regards,
    Mikhail Terekhov
    
    
  23. Re: [HACKERS] Re: WIN32 errno patch

    Mikhail Terekhov <terekhov@emc.com> — 2001-08-17T19:21:48Z

    
    Tom Lane wrote:
    > 
    > Bruce Momjian <pgman@candle.pha.pa.us> writes:
    > > I will try to apply it within the next 48 hours.
    > 
    > This isn't the right patch to apply, since Mikhail didn't fix the
    > strerror problem.  I have some code from Magnus Naeslund that purports
    > to handle the strerror issue, and will work it up into a patch real soon
    > now.
    > 
    
    As i've said in my other message this code doesn't solve the strerror
    problem. I'd suggest to separate these two problems because
    	1. Without errno patch the code doesn't even compile,
    	   but with errno patch the code compiles and works.
    	2. Without strerror patch we will have the same result as before,
    	   i.e. error code but no error message. IMHO, it is impossible
    	   to get winsock error messages without some system or version
    	   dependent hack.
    
    Regards,
    Mikhail Terekhov
    
    
  24. Re: Re: [HACKERS] Re: WIN32 errno patch

    Magnus Naeslund(f) <mag@fbab.net> — 2001-08-18T13:53:40Z

    From: "Mikhail Terekhov" <terekhov@emc.com>
    [snip]
    > On my system (NT4 sp.6, VC6.0) the FormatMessage function always
    > returns 0 for errno in the [10000 - 10100] range (winsock errors).
    > That's why i've wrote that this function knows nothing about
    > sockets errors. Using this function looks very impressive but the
    > net result is null. If Magnus could get some meaningfull messages
    > for winsock errors from FormatMessage I'd be glad to know what is
    > missing from my setup.
    >
    
    You can load the "netmsg.dll" and get the messages from that hmodule.
    That should probably be done and then fallback to plain FormatMessage
    without hmodule parameter.
    Do you have an netsmg.dll on nt4 (i think so)?
    On win2k it's not needed, anyhoo, thats what i'm running.
    
    Magnus
    
    > Regards,
    > Mikhail Terekhov
    >
    
    
    
    
  25. Re: Re: [HACKERS] Re: WIN32 errno patch

    Magnus Naeslund(f) <mag@fbab.net> — 2001-08-18T14:15:31Z

    Ok, where's a "system dependent hack" :)
    It seems that win9x doesn't have the "netmsg.dll" so it defaults to "normal"
    FormatMessage.
    I wonder if one could load wsock32.dll or winsock.dll on those systems
    instead of netmsg.dll.
    
    Mikhail, could you please test this code on your nt4 system?
    Could someone else test this code on a win98/95 system?
    
    It works on win2k over here.
    
    (code attached)
    
    Magnus
    
  26. Re: WIN32 errno patch

    Serguei Mokhov <sa_mokho@alcor.concordia.ca> — 2001-08-18T16:33:19Z

    ----- Original Message ----- 
    From: Magnus Naeslund(f) <mag@fbab.net>
    Sent: Saturday, August 18, 2001 10:15 AM
    
    
    > Ok, where's a "system dependent hack" :)
    > It seems that win9x doesn't have the "netmsg.dll" so it defaults to "normal"
    > FormatMessage.
    > I wonder if one could load wsock32.dll or winsock.dll on those systems
    > instead of netmsg.dll.
    
    Windows 98SE, M$ Visual C++ 6.0
    In the project settings in the Link library list
    you can put 'wsock32.lib'.
     
    > Could someone else test this code on a win98/95 system?
    
    I compiled and run it. I didn't produce any error messages for IP 10.10.10.3
    you put there. I used localhost instead, and here is the
    result:
    
    socket error(10061):Unknown socket error(10061)
    
    I don't know whether this is what you expected or not.
    
    S.
    
    
    
    
    
  27. Re: WIN32 errno patch

    Magnus Naeslund(f) <mag@fbab.net> — 2001-08-18T17:07:42Z

    From: "Serguei Mokhov" <sa_mokho@alcor.concordia.ca>
    
    [snip]
    
    > Windows 98SE, M$ Visual C++ 6.0
    > In the project settings in the Link library list
    > you can put 'wsock32.lib'.
    >
    > > Could someone else test this code on a win98/95 system?
    >
    > I compiled and run it. I didn't produce any error messages for IP
    10.10.10.3
    > you put there. I used localhost instead, and here is the
    > result:
    >
    > socket error(10061):Unknown socket error(10061)
    >
    > I don't know whether this is what you expected or not.
    >
    
    Well this was about what i thought...
    It's not working too good :(
    I'll try to find out a good way of doing this on win9x.
    
    > S.
    
    Magnus
    
    
    
    
    
  28. Re: [HACKERS] Re: WIN32 errno patch

    Mikhail Terekhov <terekhov@emc.com> — 2001-08-20T16:31:49Z

    
    "Magnus Naeslund(f)" wrote:
    > 
    > This is a multi-part message in MIME format.
    > 
    > ------=_NextPart_000_0106_01C12801.00DAC460
    > Content-Type: text/plain; charset="iso-8859-1"
    > Content-Transfer-Encoding: 7bit
    > 
    > Ok, where's a "system dependent hack" :)
    > It seems that win9x doesn't have the "netmsg.dll" so it defaults to "normal"
    > FormatMessage.
    > I wonder if one could load wsock32.dll or winsock.dll on those systems
    > instead of netmsg.dll.
    > 
    > Mikhail, could you please test this code on your nt4 system?
    > Could someone else test this code on a win98/95 system?
    > 
    > It works on win2k over here.
    > 
    > (code attached)
    > 
    > Magnus
    
    It works on win2k here too but not on win98/95 or winNT.
    Anyway, attached is the patch which uses Magnus's my_sock_strerror
    function (renamed to winsock_strerror). The only difference is that 
    I put the code to load and unload netmsg.dll in the libpqdll.c
    (is this OK Magnus?).
    
    Regards
    Mikhail Terekhov
  29. Re: [HACKERS] Re: WIN32 errno patch

    Mikhail Terekhov <terekhov@emc.com> — 2001-08-21T20:31:45Z

    Any chance to review/apply this patch?
    
    Regards,
    Mikhail Terekhov
    
    
    Mikhail Terekhov wrote:
    > 
    > "Magnus Naeslund(f)" wrote:
    > >
    > > This is a multi-part message in MIME format.
    > >
    > > ------=_NextPart_000_0106_01C12801.00DAC460
    > > Content-Type: text/plain; charset="iso-8859-1"
    > > Content-Transfer-Encoding: 7bit
    > >
    > > Ok, where's a "system dependent hack" :)
    > > It seems that win9x doesn't have the "netmsg.dll" so it defaults to "normal"
    > > FormatMessage.
    > > I wonder if one could load wsock32.dll or winsock.dll on those systems
    > > instead of netmsg.dll.
    > >
    > > Mikhail, could you please test this code on your nt4 system?
    > > Could someone else test this code on a win98/95 system?
    > >
    > > It works on win2k over here.
    > >
    > > (code attached)
    > >
    > > Magnus
    > 
    > It works on win2k here too but not on win98/95 or winNT.
    > Anyway, attached is the patch which uses Magnus's my_sock_strerror
    > function (renamed to winsock_strerror). The only difference is that
    > I put the code to load and unload netmsg.dll in the libpqdll.c
    > (is this OK Magnus?).
    > 
    > Regards
    > Mikhail Terekhov
    > 
    >   --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    >                      Name: libpq.patch.gz
    >    libpq.patch.gz    Type: Gsview32 File (application/x-gzip)
    >                  Encoding: base64
    
    
  30. Re: Re: [HACKERS] Re: WIN32 errno patch

    Bruce Momjian <pgman@candle.pha.pa.us> — 2001-08-23T17:00:00Z

    Can I assume the current CVS has all the Win32 issues resolved?
    
    > Tom Lane wrote:
    > > 
    > > Bruce Momjian <pgman@candle.pha.pa.us> writes:
    > > > I will try to apply it within the next 48 hours.
    > > 
    > > This isn't the right patch to apply, since Mikhail didn't fix the
    > > strerror problem.  I have some code from Magnus Naeslund that purports
    > > to handle the strerror issue, and will work it up into a patch real soon
    > > now.
    > > 
    > 
    > As i've said in my other message this code doesn't solve the strerror
    > problem. I'd suggest to separate these two problems because
    > 	1. Without errno patch the code doesn't even compile,
    > 	   but with errno patch the code compiles and works.
    > 	2. Without strerror patch we will have the same result as before,
    > 	   i.e. error code but no error message. IMHO, it is impossible
    > 	   to get winsock error messages without some system or version
    > 	   dependent hack.
    > 
    > Regards,
    > Mikhail Terekhov
    > 
    > ---------------------------(end of broadcast)---------------------------
    > TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org
    > 
    
    -- 
      Bruce Momjian                        |  http://candle.pha.pa.us
      pgman@candle.pha.pa.us               |  (610) 853-3000
      +  If your life is a hard drive,     |  830 Blythe Avenue
      +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
    
    
  31. Re: [HACKERS] Re: WIN32 errno patch

    Mikhail Terekhov <terekhov@emc.com> — 2001-08-24T18:25:34Z

    See [COMMITTERS] pgsql/ /configure /configure.in oc/FAQ oc/FAQ_ ...] tread.
    
    Regards,
    Mikhail Terekhov
    
    Bruce Momjian wrote:
    > 
    > Can I assume the current CVS has all the Win32 issues resolved?
    >