libpq(win32) s/errno/WSAGetLastError()/ - Mailing list pgsql-patches

From Sergey Chumakov
Subject libpq(win32) s/errno/WSAGetLastError()/
Date
Msg-id 20011022181815.A25652@cit.org.by
Whole thread Raw
Responses Re: libpq(win32) s/errno/WSAGetLastError()/  (Tom Lane <tgl@sss.pgh.pa.us>)
Re: libpq(win32) s/errno/WSAGetLastError()/  (Bruce Momjian <pgman@candle.pha.pa.us>)
List pgsql-patches
Your name        : Sergey Chumakov
Your email address    : yas@cit.org.by


System Configuration
---------------------
  Architecture (example: Intel Pentium)      : Intel Pentium

  Operating System (example: Linux 2.0.26 ELF)     : Windows 2000 SP2

  PostgreSQL version (example: PostgreSQL-7.1.3): PostgreSQL-7.1.3

  Compiler used (example:  gcc 2.95.2)        : MSVS6 SP5 (Microsoft (R) 32-bit C/C++ Optimizing Compiler Version
12.00.8804for 80x86) 


Please enter a FULL description of your problem:
------------------------------------------------

libpq PQexec failed with large query (sizeof(Query) > 8192).



Please describe a way to repeat the problem.   Please try to provide a
concise reproducible example, if at all possible:
----------------------------------------------------------------------


// SQL: create table test(f1 text); insert into test values(null);

#include <stdlib.h>
#include <string.h>
#include <libpq-fe.h>

int main(int argc, char* argv[])
{
    PGconn *conn = NULL;
    PGresult *res = NULL;
    char *szQ = NULL;

    PQconninfoOption* opt = PQconndefaults();

    conn = PQsetdbLogin("localhost", NULL, NULL, NULL, "template1", "postgres", NULL);

    szQ = (char*)malloc(32000);
    memset(szQ, 'A', 64001);
    memcpy(szQ, "update test set f1='", strlen("update test set f1='"));
    szQ[63998] = '\'';
    szQ[63999] = '\0';

    if( PQstatus(conn) == CONNECTION_BAD )
    {
        printf("%s", PQerrorMessage(conn));
        goto end_work;
    }

    res = PQexec(conn, szQ);
    if( !res || PQresultStatus(res) != PGRES_COMMAND_OK )
    {
        printf("%s", PQerrorMessage(conn));
        goto end_work;
    }

end_work:
    if( res )
        PQclear(res);
    if( conn )
        PQfinish(conn);
    free(szQ);

    return 0;
}



If you know how this problem might be fixed, list the solution below:
---------------------------------------------------------------------

Small patch for socket error detection/processing


diff -rcN postgresql-7.1.3.orig/src/interfaces/libpq/fe-misc.c postgresql-7.1.3/src/interfaces/libpq/fe-misc.c
*** postgresql-7.1.3.orig/src/interfaces/libpq/fe-misc.c    Sun Apr  1 02:13:30 2001
--- postgresql-7.1.3/src/interfaces/libpq/fe-misc.c    Mon Oct 22 17:12:47 2001
***************
*** 328,340 ****
--- 328,347 ----
      if (select(conn->sock + 1, &input_mask, (fd_set *) NULL, (fd_set *) NULL,
                 &timeout) < 0)
      {
+ #ifdef WIN32
+       if (WSAGetLastError() == WSAEINTR)
+ #else
          if (errno == EINTR)
+ #endif
              /* Interrupted system call - we'll just try again */
              goto retry;

          printfPQExpBuffer(&conn->errorMessage,
                        "pqReadReady() -- select() failed: errno=%d\n%s\n",
                            errno, strerror(errno));
+ #ifdef WIN32
+         printf("Winsock error: %i\n", WSAGetLastError());
+ #endif
          return -1;
      }

***************
*** 362,374 ****
--- 369,388 ----
      if (select(conn->sock + 1, (fd_set *) NULL, &input_mask, (fd_set *) NULL,
                 &timeout) < 0)
      {
+ #ifdef WIN32
+       if (WSAGetLastError() == WSAEINTR)
+ #else
          if (errno == EINTR)
+ #endif
              /* Interrupted system call - we'll just try again */
              goto retry;

          printfPQExpBuffer(&conn->errorMessage,
                       "pqWriteReady() -- select() failed: errno=%d\n%s\n",
                            errno, strerror(errno));
+ #ifdef WIN32
+         printf("Winsock error: %i\n", WSAGetLastError());
+ #endif
          return -1;
      }
      return FD_ISSET(conn->sock, &input_mask) ? 1 : 0;
***************
*** 441,448 ****
--- 455,475 ----
                       conn->inBufSize - conn->inEnd, 0);
      if (nread < 0)
      {
+ #ifdef WIN32
+       int wserrno = WSAGetLastError();
+
+       if (wserrno == WSAEINTR)
+ #else
          if (errno == EINTR)
+ #endif
              goto tryAgain;
+ #ifdef WIN32
+       if (wserrno == WSAEWOULDBLOCK)
+         return someread;
+
+       if (wserrno == WSAECONNRESET)
+         goto definitelyFailed;
+ #else
          /* Some systems return EAGAIN/EWOULDBLOCK for no data */
  #ifdef EAGAIN
          if (errno == EAGAIN)
***************
*** 457,469 ****
          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)
!     {
          conn->inEnd += nread;

          /*
--- 484,500 ----
          if (errno == ECONNRESET)
              goto definitelyFailed;
  #endif
+ #endif /* WIN32 */
          printfPQExpBuffer(&conn->errorMessage,
                          "pqReadData() --  read() failed: errno=%d\n%s\n",
                            errno, strerror(errno));
+ #ifdef WIN32
+         printf("Winsock error: %i\n", WSAGetLastError());
+ #endif
          return -1;
      }
      if (nread > 0)
!       {
          conn->inEnd += nread;

          /*
***************
*** 527,534 ****
--- 558,578 ----
                       conn->inBufSize - conn->inEnd, 0);
      if (nread < 0)
      {
+ #ifdef WIN32
+       int wserrno = WSAGetLastError();
+
+       if (wserrno == WSAEINTR)
+ #else
          if (errno == EINTR)
+ #endif
              goto tryAgain2;
+ #ifdef WIN32
+       if (wserrno == WSAEWOULDBLOCK)
+         return someread;
+
+       if (wserrno == WSAECONNRESET)
+         goto definitelyFailed;
+ #else
          /* Some systems return EAGAIN/EWOULDBLOCK for no data */
  #ifdef EAGAIN
          if (errno == EAGAIN)
***************
*** 543,556 ****
          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)
      {
!         conn->inEnd += nread;
          return 1;
      }

--- 587,604 ----
          if (errno == ECONNRESET)
              goto definitelyFailed;
  #endif
+ #endif
          printfPQExpBuffer(&conn->errorMessage,
                          "pqReadData() --  read() failed: errno=%d\n%s\n",
                            errno, strerror(errno));
+ #ifdef WIN32
+         printf("Winsock error: %i\n", WSAGetLastError());
+ #endif
          return -1;
      }
      if (nread > 0)
      {
!       conn->inEnd += nread;
          return 1;
      }

***************
*** 627,632 ****
--- 675,689 ----
               * EPIPE or ECONNRESET, assume we've lost the backend
               * connection permanently.
               */
+ #ifdef WIN32
+           switch (WSAGetLastError())
+             {
+             case WSAEWOULDBLOCK:
+               break;
+             case WSAEINTR:
+               continue;
+             case WSAECONNRESET:
+ #else
              switch (errno)
              {
  #ifdef EAGAIN
***************
*** 644,649 ****
--- 701,707 ----
  #ifdef ECONNRESET
                  case ECONNRESET:
  #endif
+ #endif
                      printfPQExpBuffer(&conn->errorMessage,
                                        "pqFlush() -- backend closed the channel unexpectedly.\n"
                                        "\tThis probably means the backend terminated abnormally"
***************
*** 663,668 ****
--- 721,729 ----
                      printfPQExpBuffer(&conn->errorMessage,
                        "pqFlush() --  couldn't send data: errno=%d\n%s\n",
                                        errno, strerror(errno));
+ #ifdef WIN32
+                     printf("Winsock error: %i\n", WSAGetLastError());
+ #endif
                      /* We don't assume it's a fatal error... */
                      return EOF;
              }
***************
*** 745,755 ****
--- 806,823 ----
          if (select(conn->sock + 1, &input_mask, &output_mask, &except_mask,
                     (struct timeval *) NULL) < 0)
          {
+ #ifdef WIN32
+           if (WSAGetLastError() == WSAEINTR)
+ #else
              if (errno == EINTR)
+ #endif
                  goto retry;
              printfPQExpBuffer(&conn->errorMessage,
                                "pqWait() -- select() failed: errno=%d\n%s\n",
                                errno, strerror(errno));
+ #ifdef WIN32
+             printf("Winsock error: %i\n", WSAGetLastError());
+ #endif
              return EOF;
          }
      }

pgsql-patches by date:

Previous
From: Mark Lillywhite
Date:
Subject: DatabaseMetadata patch
Next
From: Tom Lane
Date:
Subject: Re: libpq(win32) s/errno/WSAGetLastError()/