Re: libpq sockets on win32 - Mailing list pgsql-interfaces

From Bruce Momjian
Subject Re: libpq sockets on win32
Date
Msg-id 200106041921.f54JLns03333@candle.pha.pa.us
Whole thread Raw
In response to RE: libpq sockets on win32  ("Jeff Johnson" <jeff@jeffjohnson.net>)
List pgsql-interfaces
> As Tom Lane points out in another post, the "define errno
> WSAGetLastError" seems to confuse a variable with a function.  I was
> surprised that such a thing could work.  I'm happy to hear that it
> doesn't.
>
> What about something like this:
>
> #ifdef WIN32
> #define s_errno WSAGetLastError()
> #else
> #define s_errno errno
> #endif
>
> /* for socket functions, check s_errno */
> if (s_errno == EINPROGRESS || s_errno == 0)
> ...
>
> /* for non-socket functions, check errno as usual */
> if (errno == ENOENT)
> ...

I have done exactly that.  I assume fcntl(), ioctl(), select() use errno
even if used on a socket, while getsockopt(), setsockopt(), socket(),
connect(), getsockname(), send(), recv() use WSAGetLastError.  Is this
list correct?

The patch is attached.  Please let me know so I can finalize it and
apply it.

--
  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
Index: src/interfaces/libpq/fe-connect.c
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v
retrieving revision 1.164
diff -c -r1.164 fe-connect.c
*** src/interfaces/libpq/fe-connect.c    2001/03/31 23:14:37    1.164
--- src/interfaces/libpq/fe-connect.c    2001/06/04 19:18:14
***************
*** 735,741 ****
      {
          printfPQExpBuffer(&conn->errorMessage,
                   "connectNoDelay() -- setsockopt failed: errno=%d\n%s\n",
!                           errno, strerror(errno));
  #ifdef WIN32
          printf("Winsock error: %i\n", WSAGetLastError());
  #endif
--- 735,741 ----
      {
          printfPQExpBuffer(&conn->errorMessage,
                   "connectNoDelay() -- setsockopt failed: errno=%d\n%s\n",
!                           sockerrno, strerror(sockerrno));
  #ifdef WIN32
          printf("Winsock error: %i\n", WSAGetLastError());
  #endif
***************
*** 890,896 ****
          printfPQExpBuffer(&conn->errorMessage,
                            "connectDBStart() -- "
                            "socket() failed: errno=%d\n%s\n",
!                           errno, strerror(errno));
          goto connect_errReturn;
      }

--- 890,896 ----
          printfPQExpBuffer(&conn->errorMessage,
                            "connectDBStart() -- "
                            "socket() failed: errno=%d\n%s\n",
!                           sockerrno, strerror(sockerrno));
          goto connect_errReturn;
      }

***************
*** 934,944 ****
       */
      if (connect(conn->sock, &conn->raddr.sa, conn->raddr_len) < 0)
      {
! #ifndef WIN32
!         if (errno == EINPROGRESS || errno == 0)
! #else
!         if (WSAGetLastError() == WSAEINPROGRESS)
! #endif
          {

              /*
--- 934,940 ----
       */
      if (connect(conn->sock, &conn->raddr.sa, conn->raddr_len) < 0)
      {
!         if (sockerrno == EINPROGRESS || sockerrno == 0)
          {

              /*
***************
*** 950,956 ****
          else
          {
              /* Something's gone wrong */
!             connectFailureMessage(conn, "connectDBStart()", errno);
              goto connect_errReturn;
          }
      }
--- 946,952 ----
          else
          {
              /* Something's gone wrong */
!             connectFailureMessage(conn, "connectDBStart()", sockerrno);
              goto connect_errReturn;
          }
      }
***************
*** 970,983 ****
          {
              printfPQExpBuffer(&conn->errorMessage,
                                "connectDB() -- couldn't send SSL negotiation packet: errno=%d\n%s\n",
!                               errno, strerror(errno));
              goto connect_errReturn;
          }
          /* Now receive the postmasters response */
          if (recv(conn->sock, &SSLok, 1, 0) != 1)
          {
              printfPQExpBuffer(&conn->errorMessage, "PQconnectDB() -- couldn't read postmaster response:
errno=%d\n%s\n",
!                               errno, strerror(errno));
              goto connect_errReturn;
          }
          if (SSLok == 'S')
--- 966,979 ----
          {
              printfPQExpBuffer(&conn->errorMessage,
                                "connectDB() -- couldn't send SSL negotiation packet: errno=%d\n%s\n",
!                               sockerrno, strerror(sockerrno));
              goto connect_errReturn;
          }
          /* Now receive the postmasters response */
          if (recv(conn->sock, &SSLok, 1, 0) != 1)
          {
              printfPQExpBuffer(&conn->errorMessage, "PQconnectDB() -- couldn't read postmaster response:
errno=%d\n%s\n",
!                               sockerrno, strerror(sockerrno));
              goto connect_errReturn;
          }
          if (SSLok == 'S')
***************
*** 1233,1239 ****
                      printfPQExpBuffer(&conn->errorMessage,
                                 "PQconnectPoll() -- getsockopt() failed: "
                                        "errno=%d\n%s\n",
!                                       errno, strerror(errno));
                      goto error_return;
                  }
                  else if (optval != 0)
--- 1229,1235 ----
                      printfPQExpBuffer(&conn->errorMessage,
                                 "PQconnectPoll() -- getsockopt() failed: "
                                        "errno=%d\n%s\n",
!                                       sockerrno, strerror(sockerrno));
                      goto error_return;
                  }
                  else if (optval != 0)
***************
*** 1255,1261 ****
                      printfPQExpBuffer(&conn->errorMessage,
                                "PQconnectPoll() -- getsockname() failed: "
                                        "errno=%d\n%s\n",
!                                       errno, strerror(errno));
                      goto error_return;
                  }

--- 1251,1257 ----
                      printfPQExpBuffer(&conn->errorMessage,
                                "PQconnectPoll() -- getsockname() failed: "
                                        "errno=%d\n%s\n",
!                                       sockerrno, strerror(sockerrno));
                      goto error_return;
                  }

***************
*** 1296,1302 ****
                                        "PQconnectPoll() --  "
                                        "couldn't send startup packet: "
                                        "errno=%d\n%s\n",
!                                       errno, strerror(errno));
                      goto error_return;
                  }

--- 1292,1298 ----
                                        "PQconnectPoll() --  "
                                        "couldn't send startup packet: "
                                        "errno=%d\n%s\n",
!                                       sockerrno, strerror(sockerrno));
                      goto error_return;
                  }

***************
*** 2110,2116 ****
--- 2106,2114 ----
  int
  PQrequestCancel(PGconn *conn)
  {
+ #ifndef WIN32
      int            save_errno = errno;
+ #endif
      int            tmpsock = -1;
      struct
      {
***************
*** 2127,2133 ****
--- 2125,2133 ----
          strcpy(conn->errorMessage.data,
                 "PQrequestCancel() -- connection is not open\n");
          conn->errorMessage.len = strlen(conn->errorMessage.data);
+ #ifndef WIN32
          errno = save_errno;
+ #endif
          return FALSE;
      }

***************
*** 2173,2183 ****
      close(tmpsock);
  #endif

      errno = save_errno;
      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,2185 ----
      close(tmpsock);
  #endif

+ #ifndef WIN32
      errno = save_errno;
+ #endif
      return TRUE;

  cancel_errReturn:
!     strcat(conn->errorMessage.data, strerror(sockerrno));
      strcat(conn->errorMessage.data, "\n");
      conn->errorMessage.len = strlen(conn->errorMessage.data);
      if (tmpsock >= 0)
***************
*** 2188,2194 ****
--- 2190,2198 ----
          close(tmpsock);
  #endif
      }
+ #ifndef WIN32
      errno = save_errno;
+ #endif
      return FALSE;
  }

Index: src/interfaces/libpq/fe-misc.c
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v
retrieving revision 1.49
diff -c -r1.49 fe-misc.c
*** src/interfaces/libpq/fe-misc.c    2001/05/28 15:29:51    1.49
--- src/interfaces/libpq/fe-misc.c    2001/06/04 19:18:20
***************
*** 447,471 ****
                       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,
                          "pqReadData() --  read() failed: errno=%d\n%s\n",
!                           errno, strerror(errno));
          return -1;
      }
      if (nread > 0)
--- 447,471 ----
                       conn->inBufSize - conn->inEnd, 0);
      if (nread < 0)
      {
!         if (sockerrno == EINTR)
              goto tryAgain;
          /* Some systems return EAGAIN/EWOULDBLOCK for no data */
  #ifdef EAGAIN
!         if (sockerrno == EAGAIN)
              return someread;
  #endif
  #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
!         if (sockerrno == EWOULDBLOCK)
              return someread;
  #endif
          /* We might get ECONNRESET here if using TCP and backend died */
  #ifdef ECONNRESET
!         if (sockerrno == ECONNRESET)
              goto definitelyFailed;
  #endif
          printfPQExpBuffer(&conn->errorMessage,
                          "pqReadData() --  read() failed: errno=%d\n%s\n",
!                           sockerrno, strerror(sockerrno));
          return -1;
      }
      if (nread > 0)
***************
*** 533,557 ****
                       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,
                          "pqReadData() --  read() failed: errno=%d\n%s\n",
!                           errno, strerror(errno));
          return -1;
      }
      if (nread > 0)
--- 533,557 ----
                       conn->inBufSize - conn->inEnd, 0);
      if (nread < 0)
      {
!         if (sockerrno == EINTR)
              goto tryAgain2;
          /* Some systems return EAGAIN/EWOULDBLOCK for no data */
  #ifdef EAGAIN
!         if (sockerrno == EAGAIN)
              return 0;
  #endif
  #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
!         if (sockerrno == EWOULDBLOCK)
              return 0;
  #endif
          /* We might get ECONNRESET here if using TCP and backend died */
  #ifdef ECONNRESET
!         if (sockerrno == ECONNRESET)
              goto definitelyFailed;
  #endif
          printfPQExpBuffer(&conn->errorMessage,
                          "pqReadData() --  read() failed: errno=%d\n%s\n",
!                           sockerrno, strerror(sockerrno));
          return -1;
      }
      if (nread > 0)
***************
*** 633,639 ****
               * EPIPE or ECONNRESET, assume we've lost the backend
               * connection permanently.
               */
!             switch (errno)
              {
  #ifdef EAGAIN
                  case EAGAIN:
--- 633,639 ----
               * EPIPE or ECONNRESET, assume we've lost the backend
               * connection permanently.
               */
!             switch (sockerrno)
              {
  #ifdef EAGAIN
                  case EAGAIN:
***************
*** 668,674 ****
                  default:
                      printfPQExpBuffer(&conn->errorMessage,
                        "pqFlush() --  couldn't send data: errno=%d\n%s\n",
!                                       errno, strerror(errno));
                      /* We don't assume it's a fatal error... */
                      return EOF;
              }
--- 668,674 ----
                  default:
                      printfPQExpBuffer(&conn->errorMessage,
                        "pqFlush() --  couldn't send data: errno=%d\n%s\n",
!                                       sockerrno, strerror(sockerrno));
                      /* We don't assume it's a fatal error... */
                      return EOF;
              }
Index: src/interfaces/libpq/libpq-int.h
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/libpq/libpq-int.h,v
retrieving revision 1.33
diff -c -r1.33 libpq-int.h
*** src/interfaces/libpq/libpq-int.h    2001/03/22 04:01:27    1.33
--- src/interfaces/libpq/libpq-int.h    2001/06/04 19:18:23
***************
*** 34,39 ****
--- 34,45 ----
  #include <openssl/err.h>
  #endif

+ #ifndef WIN32
+ #define sockerrno errno
+ #else
+ #define sockerrno WSAGetLastError
+ #endif
+
  /* libpq supports this version of the frontend/backend protocol.
   *
   * NB: we used to use PG_PROTOCOL_LATEST from the backend pqcomm.h file,

pgsql-interfaces by date:

Previous
From: "Jeff Johnson"
Date:
Subject: RE: libpq sockets on win32
Next
From: "Jeff Johnson"
Date:
Subject: RE: libpq sockets on win32