Subject: fork & recv problem (writing a bind and accept service).
From: Paul Halliday <[email-masked]>
To: [email-masked]
Date: Tue, 28 Sep 1999 12:36:20 +0000

This sounds similar to a bug someone has recently posted:
I'm writing a service which binds, listens, accepts incoming TCP connections
then forks a child which does the remote communication (standard
thing), using Cygwinb20.1 on Windows 95.

But the child process does not receive anything from the client end through the 
socket (using recv or read). Only the original parent seems able to do this.
Writing a multitasking service will be a major pain without this (stacks of
socket descriptors, managing select lists etc).

The following code snippet illustrates the problem. If I telnet to
port 11111, type in some chars and hit return the service should print
the first character received to stdout. Under HP-UX and Linux it works.
Under Cygwin (Win95 at least) it does not.

Is this a known bug and/or are there any workarounds? 

I know inetd is one which will work (if all else fails I will have to use this)
but I'd rather have a standalone service.

Many thanks,

		Paul.

--
Paul Halliday
MIS Dept.       Bridgend Plant.     Sony Manufacturing Co UK.
_________________________________________________________
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <signal.h>

int Read_Client_Command(int cfd);

int main(int argc, char *argv[])
{
	int sfd, cfd, 
	    port = 11111, 
	    clientlen;

	struct sockaddr_in ServerAddr, ClientAddr;

	if (argc == 2) 	
		port = atoi(argv[1]);

	if ((sfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
	    perror("socket");
	    exit(1);
	}

	memset(&ServerAddr, 0, sizeof(ServerAddr));	
	ServerAddr.sin_family 		= AF_INET;
	ServerAddr.sin_addr.s_addr 	= htonl(INADDR_ANY);
	ServerAddr.sin_port 		= htons((short) port);

	if (bind(sfd, (struct sockaddr *)&ServerAddr, sizeof(ServerAddr)) == -1) {
	    	fprintf(stderr, "bind to port %d failed: %s",
			ntohs(ServerAddr.sin_port), strerror(errno));
	    	exit(1);
	}

	if (listen(sfd, 2) == -1) {
		perror("listen");
		exit(1);
	}

	printf("Server is listening ...\n");
	
	for(;;) {
	    	clientlen = sizeof(ClientAddr);
	    	if ((cfd = accept(sfd, (struct sockaddr*)&ClientAddr, &clientlen)) == -1) {
			perror("accept");
			exit(0);
	    	}
		printf("Accepted a connection ...\n");

		if (!fork()) { 	/* Child Process. */
	                while (Read_Client_Command(cfd) == -1)
		                usleep(100000);
			exit(0);
		}
		close(cfd);
	}
}

int Read_Client_Command(int cfd)
{
	char client_character[2];

	client_character[1] = '\0';

       	if (recv(cfd, client_character, 1, 0) > 0) {
		printf("Character received is %s\n", client_character);
		return 0;
	} else {
		printf("No characters received ..\n");
		return -1;
	}
}

_________________________________________________________________________

* * * * * Notice Of Disclaimer & Confidentiality * * * * *

The contents of this E:Mail message does not in any way constitute 
the opinion of Sony Manufacturing Co. UK, but that of the individual 
person who composed it.

It is intended for the named addressee only and it contains 
information which may be confidential and privileged.

Unless you are the named addressee or authorised to receive it 
on their behalf, you may not use, copy or disclose it's contents to
anyone else.  

If you have received this message by mistake please contact:

Sony Manufacturing Co. UK., Bridgend Industrial Est.,
Bridgend, Mid Glam, CF31 3YH.

Tel (+44) 01656 767000, Fax (+44) 01656 767222

MIS Manager

--
Want to unsubscribe from this list?
Send a message to [email-masked]