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