Subject: Problem with inheriting socket filehandles across forks in B17.1 under Win95?
From: [email-masked] (Jim Hunt)

1 Mar 1997 13:59:45 -0800
Approved: [email-masked]
Distribution: cygnus
Message-ID: <[email-masked]>
Reply-To: [email-masked]
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
X-Mailer: Mozilla 3.0 (Win95; I)
Original-To: [email-masked]
Original-Sender: [email-masked]

There appears to be a problem with inheriting open socket filehandles across
forks on B17.1 when running under Win95.

The attached programs are a simple socket server/client programs which I was
using as a learning exercise (source code borrowed heavily from other sources).
They compile and run without problems on Linux and AIX.  They compile under
Cygnus B17.1 on Win95, but the read in the child section of the server code
fails, returning -1 without waiting for any data to be sent by the client to
the socket.  I put a debug option into the server code to skip the fork call
just as a test; the server is then able to successfully read data sent by the
client. 

Anyone have any suggestions?

I checked the mail archives at cygnus.com, but they appear to only go up to
Dec. 22.  Is there a more up to date mail archive or (even better) an up to
date bug list for B17.1?

To invoke the programs:

   server <-d> <server_name>

          (-d bypasses the fork call)

   client <server_name>

And then just type messages into the client to send them to the server.

Thanks in advance for any help.

Jim
[email-masked]

********************************* server.c ***********************************
#include <errno.h> /* obligatory includes */
#include <signal.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
#include <fcntl.h>

#define NAME "TCP_SERV_NAME"

main(argc, argv)
int argc;
char *argv[];
{
    int sock, msgsock, rval, con, clientlen, forkflag;
    int child[100], optptr;
    struct sockaddr_in server;
    struct sockaddr_in client;
    char buf[1024];
    char myname[30];
    struct servent *sp;
    struct hostent *hp;

    forkflag = 0;
    clientlen = sizeof(client);
    sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock < 0) {
        perror("opening stream socket");
        exit(1);
    }
    strcpy(myname,NAME);
    for(optptr=1;optptr<argc;optptr++) {
      if(!strcmp(argv[optptr],"-d")) {
	forkflag = 1;
      } else {
	strcpy(myname,argv[optptr]);
      }
    }
    if((hp=gethostbyname(myname))==NULL) {
        perror("hostbyname fubar\n");
        exit(1);
    }
    bzero((char *)&server,sizeof(server));
    bcopy(hp->h_addr,(char *)&server.sin_addr,hp->h_length); 
    server.sin_family = AF_INET;
    server.sin_port = 2345;
    if (bind(sock, (struct sockaddr *) &server, sizeof(server))) {
        perror("binding stream socket");
        exit(1);
    }
    if(listen(sock, 5)) {
      perror("listen\n");
    }
    con = 0;
    printf("Listening for connection 1....\n");
    fflush(stdout);
    for (;;) {
        msgsock = accept(sock, (struct sockaddr *)&client, &clientlen);
        con++;
        if (msgsock == -1) {
            perror("accept");
  	    exit(1);
	}
	printf("Successful connection on channel %d\n",con);
	if (forkflag==0) {
	  child[con] = fork();
	}
        if ((child[con]==0) || (forkflag==1)) {
	    fflush(stdout);
	    while((rval = read(msgsock, buf, sizeof(buf))) >0) {
	      printf("%d: %s\n",con,buf);
	    }
	    close(msgsock);
	    printf("Closing connection on channel %d\n",con);
	    printf("rval = %d\n",rval);
	    fflush(stdout);
	    if(forkflag==0) {
	      exit(0);
	    }
	}
    }
    close(sock);
    unlink(NAME);
}

********************************* client.c ***********************************
#include <errno.h> /* obligatory includes */
#include <signal.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <netdb.h>

#define NAME "TCP_SERV_NAME"
#define PORT 2345

main(argc, argv)
    int argc;
    char *argv[];
{
    int sock;
    char myname[30];
    struct sockaddr_in server;
    struct servent *sp;
    struct hostent *hp;
    char buf[1024];

    gets(buf);          /* flush out stdin */
    if (argc < 2) {
        printf("Enter machine to talk to ==> ");
        gets(buf);
        printf("Thank you ... calling %s\n",buf);
        strcpy(myname,buf);
    } else {
        strcpy(myname,argv[1]);
    }
    sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock < 0) {
        perror("opening stream socket");
        exit(1);
    }
    server.sin_family = AF_INET;
    if ((hp=gethostbyname(myname))==NULL) {
        printf("hostbyname fubar\n");
        exit(1);
    }
    bzero((char *)&server,sizeof(server));
    server.sin_family = AF_INET;
    server.sin_port = PORT;
    bcopy(hp->h_addr,(char *)&server.sin_addr,hp->h_length); 
    if (connect(sock, (struct sockaddr *) &server, sizeof(struct sockaddr_in)) < 0) {
        close(sock);
        perror("connecting stream socket");
        exit(1);
    }
    gets(buf);
    while(buf[0]) {
        fflush(stdout);
        if(write(sock,buf,sizeof(buf)) < 0)
            perror("writing on stream socket");
        gets(buf);
    }
    close(sock);
}
-
For help on using this list, send a message to
"[email-masked]" with one line of text: "help".