Subject: Got this error: COPY FOR DUP FAILED...
From: [email-masked] (D. Richard Hipp)

21 Nov 1997 07:46:04 -0800
Message-ID: <[email-masked]>
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
To: [email-masked]

I just now tried to compile an old Unix program on a
W95 box using b18.  The program does some funky forking
and dupping.  Unfortunately, Cygwin32 isn't quite up to
this yet.  Here is the error message:

   waitpid (0, x, y) not supported
   COPY FOR DUP FAILED, handle in 15 6!!
   COPY FOR DUP FAILED, handle in 15 6!!
   COPY FOR DUP FAILED, handle in 15 6!!

The "waitpid not supported" part I can live with.  But the
failure to DUP the socket is a problem.

Can anyone suggest a work-around? 

The source code to the module that gives this trouble
follows:

/*
** Listen on the given TCP port for connections.  Whenever a connection
** arrives, create a child process to handle it.
**
** The parent process never returns from this routine.  But child
** processes do return, and when they do, their "stdin" and "stdout"
** are connected to the socket.
*/
static void ListenOnPort(int iPort, char *zPermUser){
  int listener;                /* The server socket */
  int connection;              /* A socket for each individual connection */
  fd_set readfds;              /* Set of file descriptors for select() */
  int lenaddr;                 /* Length of the inaddr structure */
  int child;                   /* PID of the child process */
  int nchildren = 0;           /* Number of child processes */
  struct timeval delay;        /* How long to wait inside select() */
  struct sockaddr_in inaddr;   /* The socket address */

  memset(&inaddr, 0, sizeof(inaddr));
  inaddr.sin_family = AF_INET;
  inaddr.sin_addr.s_addr = INADDR_ANY;
  inaddr.sin_port = htons(iPort);
  listener = socket(AF_INET, SOCK_STREAM, 0);
  if( listener<0 ){
    fprintf(stderr,"Can't create a socket\n");
    exit(1);
  }
  if( bind(listener, (struct sockaddr*)&inaddr, sizeof(inaddr))<0 ){
    fprintf(stderr,"Can't bind to port %d\n", iPort);
    exit(1);
  }
  listen(listener,10);
  if( zPermUser ){
    struct passwd *pwd = getpwnam(zPermUser);
    if( pwd ){
      setgid(pwd->pw_gid);
      setuid(pwd->pw_uid);
    }else{
      fprintf(stderr,"%s: no such user\n",zPermUser);
      exit(1);
    }
  }
  while( 1 ){
    if( nchildren>MAX_PARALLEL ){
      /* Slow down if connections are arriving too fast */
      sleep( nchildren-MAX_PARALLEL );
    }
    delay.tv_sec = 60;
    delay.tv_usec = 0;
    FD_ZERO(&readfds);
    FD_SET( listener, &readfds);
    if( select( listener+1, &readfds, 0, 0, &delay) ){
      lenaddr = sizeof(inaddr);
      connection = accept(listener, (struct sockaddr*)&inaddr, &lenaddr);
      if( connection>=0 ){
        child = fork();
        if( child!=0 ){
          if( child>0 ) nchildren++;
          close(connection);
        }else{
          close(0);
          dup(connection);
          close(1);
          dup(connection);
          close(2);
          dup(connection);
          close(connection);
          return;
        }
      }
    }
    /* Bury dead children */
    while( waitpid(0, 0, WNOHANG)>0 ){
      nchildren--;
    }
  }
  /* NOT REACHED */  
}

   
-- 
D. Richard Hipp -- [email-masked] -- http://users.vnet.net/drh
-
For help on using this list (especially unsubscribing), send a message to
"[email-masked]" with one line of text: "help".