Re: Proposed replacement for pipe under Win32 - Mailing list pgsql-patches

From Bruce Momjian
Subject Re: Proposed replacement for pipe under Win32
Date
Msg-id 200401090458.i094wRs12483@candle.pha.pa.us
Whole thread Raw
In response to Proposed replacement for pipe under Win32  (Claudio Natoli <claudio.natoli@memetrics.com>)
List pgsql-patches
I have applied your new pipe.c file, the macros you listed (with
modification), and the configure glue to make it work.

Patch and new file attached and applied.

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

Claudio Natoli wrote:
>
> To go in src/port/ directory.
>
> This is to allow the handles returned by pipe to be used in select() calls
> (which Win32 doesn't allow with the native pipe() call), thereby obviating
> the need for reworking of the select() mechanisms in pgstat.c.
>
> Additionally, something of the sort would be required at the top of pgstat.c
>
> #ifdef WIN32
> #define pipe(a)        pgpipe(a)
> #define write(a,b,c)    send(a,b,c,0)
> #define read(a,b,c)     recv(a,b,c,0)
> #endif
>
> For reference, see this thread:
> http://archives.postgresql.org/pgsql-hackers/2003-12/msg00650.php

--
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 359-1001
  +  If your life is a hard drive,     |  13 Roberts Road
  +  Christ can be your backup.        |  Newtown Square, Pennsylvania 19073
Index: configure
===================================================================
RCS file: /cvsroot/pgsql-server/configure,v
retrieving revision 1.319
diff -c -c -r1.319 configure
*** configure    23 Dec 2003 18:40:51 -0000    1.319
--- configure    9 Jan 2004 03:48:13 -0000
***************
*** 12227,12233 ****
  case $host_os in mingw*)
  LIBOBJS="$LIBOBJS dirmod.$ac_objext"
  LIBOBJS="$LIBOBJS copydir.$ac_objext"
! LIBOBJS="$LIBOBJS gettimeofday.$ac_objext" ;;
  esac

  if test "$with_readline" = yes; then
--- 12227,12234 ----
  case $host_os in mingw*)
  LIBOBJS="$LIBOBJS dirmod.$ac_objext"
  LIBOBJS="$LIBOBJS copydir.$ac_objext"
! LIBOBJS="$LIBOBJS gettimeofday.$ac_objext"
! LIBOBJS="$LIBOBJS pipe.$ac_objext" ;;
  esac

  if test "$with_readline" = yes; then
Index: configure.in
===================================================================
RCS file: /cvsroot/pgsql-server/configure.in,v
retrieving revision 1.309
diff -c -c -r1.309 configure.in
*** configure.in    23 Dec 2003 18:40:52 -0000    1.309
--- configure.in    9 Jan 2004 03:48:14 -0000
***************
*** 924,930 ****
  case $host_os in mingw*)
  AC_LIBOBJ(dirmod)
  AC_LIBOBJ(copydir)
! AC_LIBOBJ(gettimeofday) ;;
  esac

  if test "$with_readline" = yes; then
--- 924,931 ----
  case $host_os in mingw*)
  AC_LIBOBJ(dirmod)
  AC_LIBOBJ(copydir)
! AC_LIBOBJ(gettimeofday)
! AC_LIBOBJ(pipe) ;;
  esac

  if test "$with_readline" = yes; then
Index: src/backend/postmaster/pgstat.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/backend/postmaster/pgstat.c,v
retrieving revision 1.51
diff -c -c -r1.51 pgstat.c
*** src/backend/postmaster/pgstat.c    6 Jan 2004 23:15:22 -0000    1.51
--- src/backend/postmaster/pgstat.c    9 Jan 2004 03:48:16 -0000
***************
*** 135,140 ****
--- 135,153 ----
  static void pgstat_recv_dropdb(PgStat_MsgDropdb *msg, int len);
  static void pgstat_recv_resetcounter(PgStat_MsgResetcounter *msg, int len);

+ /*
+  *    WIN32 doesn't allow descriptors returned by pipe() to be used in select(),
+  *    so for that platform we use socket() instead of pipe().
+  */
+ #ifndef WIN32
+ #define pgpipe(a)            pipe(a)
+ #define piperead(a,b,c)        read(a,b,c)
+ #define pipewrite(a,b,c)    write(a,b,c)
+ #else
+ /* pgpipe() is in /src/port */
+ #define piperead(a,b,c)        recv(a,b,c,0)
+ #define pipewrite(a,b,c)    send(a,b,c,0)
+ #endif

  /* ------------------------------------------------------------
   * Public functions called from postmaster follow
***************
*** 1380,1386 ****
       * two buffer processes competing to read from the UDP socket --- not
       * good.
       */
!     if (pipe(pgStatPipe) < 0)
      {
          ereport(LOG,
                  (errcode_for_socket_access(),
--- 1393,1399 ----
       * two buffer processes competing to read from the UDP socket --- not
       * good.
       */
!     if (pgpipe(pgStatPipe) < 0)
      {
          ereport(LOG,
                  (errcode_for_socket_access(),
***************
*** 1595,1601 ****

              while (nread < targetlen)
              {
!                 len = read(readPipe,
                             ((char *) &msg) + nread,
                             targetlen - nread);
                  if (len < 0)
--- 1608,1614 ----

              while (nread < targetlen)
              {
!                 len = piperead(readPipe,
                             ((char *) &msg) + nread,
                             targetlen - nread);
                  if (len < 0)
***************
*** 1920,1926 ****
              if (xfr > msg_have)
                  xfr = msg_have;
              Assert(xfr > 0);
!             len = write(writePipe, msgbuffer + msg_send, xfr);
              if (len < 0)
              {
                  if (errno == EINTR || errno == EAGAIN)
--- 1933,1939 ----
              if (xfr > msg_have)
                  xfr = msg_have;
              Assert(xfr > 0);
!             len = pipewrite(writePipe, msgbuffer + msg_send, xfr);
              if (len < 0)
              {
                  if (errno == EINTR || errno == EAGAIN)
/*-------------------------------------------------------------------------
 *
 * pipe.c
 *      pipe()
 *
 * Copyright (c) 1996-2003, PostgreSQL Global Development Group
 *
 *    This is a replacement version of pipe for Win32 which allows
 *    returned handles to be used in select(). Note that read/write calls
 *    must be replaced with recv/send.
 *
 * IDENTIFICATION
 *      $PostgreSQL: pgsql-server/src/port/pipe.c,v 1.1 2004/01/09 04:58:09 momjian Exp $
 *
 *-------------------------------------------------------------------------
 */

#include "postgres.h"

int
pgpipe(int handles[2])
{
    SOCKET        s;
    struct sockaddr_in serv_addr;
    int            len = sizeof(serv_addr);

    handles[0] = handles[1] = INVALID_SOCKET;

    if ((s = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
        return -1;

    memset((void *) &serv_addr, 0, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(0);
    serv_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
    if (bind(s, (SOCKADDR *) & serv_addr, len) == SOCKET_ERROR ||
        listen(s, 1) == SOCKET_ERROR ||
        getsockname(s, (SOCKADDR *) & serv_addr, &len) == SOCKET_ERROR ||
        (handles[1] = socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
    {
        closesocket(s);
        return -1;
    }

    if (connect(handles[1], (SOCKADDR *) & serv_addr, len) == SOCKET_ERROR ||
        (handles[0] = accept(s, (SOCKADDR *) & serv_addr, &len)) == INVALID_SOCKET)
    {
        closesocket(handles[1]);
        handles[1] = INVALID_SOCKET;
        closesocket(s);
        return -1;
    }
    closesocket(s);
    return 0;
}

pgsql-patches by date:

Previous
From: Bruce Momjian
Date:
Subject: Re: fork/exec patch: pre-CreateProcess finalization
Next
From: Claudio Natoli
Date:
Subject: Re: fork/exec patch: pre-CreateProcess finalization