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