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

From Bruce Momjian
Subject Re: libpq(win32) s/errno/WSAGetLastError()/
Date
Msg-id 200110240154.f9O1smP17878@candle.pha.pa.us
Whole thread Raw
In response to libpq(win32) s/errno/WSAGetLastError()/  (Sergey Chumakov <yas@cit.org.by>)
List pgsql-patches
This is all fixed in CVS and will be in 7.2.


---------------------------------------------------------------------------

>
> 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;
>           }
>       }
>
> ---------------------------(end of broadcast)---------------------------
> TIP 3: if posting/reading through Usenet, please send an appropriate
> subscribe-nomail command to majordomo@postgresql.org so that your
> message can get through to the mailing list cleanly
>

--
  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

pgsql-patches by date:

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