Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 8 Apr 2000 12:38:20 -0400 (EDT)
From:      Sean Peck <speck@news1.newsindex.com>
To:        Alfred Perlstein <bright@wintelcom.net>
Cc:        freebsd-hackers@FreeBSD.ORG
Subject:   Re: FreeBSD 3.3 fork/Exec bug?
Message-ID:  <Pine.BSI.3.95.1000408122156.882A-100000@news1.newsindex.com>
In-Reply-To: <20000408084711.W4381@fw.wintelcom.net>

next in thread | previous in thread | raw e-mail | index | archive | help
Alfred,

  Here is the code being used.

This is the Server Code, xxx are the IP of box, yyy is port this server is
listening too passed to the client

user_port = socket_config(xxxx);
while (y<1){
  if(!fork()){
  printf("Starting Client  %d\n",getpid());
  close(user_port);
  execlp("./client","client","XXX.XXX.XXX.XXX","YYYY",NULL);
  printf("Ending forked %d\n",xxx);
  exit(0);
}
y++;
}

=========================================================================================

This is the client main


 sleep(10);  //this is just to make sure that the server is ready to
	    // listen  added for tracing and testing of this bug
if(argc<3){printf("Usage get host port\n");exit(0);}
strcpy(localhostname,argv[1]);
port1 = atoi(argv[2]);
 printf("Connectiong to %s port %d\n",localhostname,port1);
signal(SIGPIPE,SIG_IGN);

 result=10;

printf("GETTING PAGE FROM SERVER\n");
while((strcmp(buf,"NONE")!=0)&&(result!=TCP_CONNECT_NONE)&&(timeout!=10)){
 memset(buf,0,sizeof(buf));
 result=10;
 timeout=0;

 while((result !=1)&&(result!=TCP_CONNECT_NONE)&&(timeout!=10)){
  result = tcp_get_conn(localhostname,port1,10,&sock1);
  if(result==TCP_CONNECT_TIMEOUT){timeout++;}
 }
 printf("result %d\n",result);  //This is coming back 1 in both the
			        // fork/execlp and in direct from shell
				// running
 printf("ERRNO %d\n",errno);   // this is coming back 36 in both shell and
				// fork/execlp

 if ((result!=TCP_CONNECT_NONE)&&(timeout!=10)){
 write(sock1,"GIMME\n",6); 
 bufp=buf;
 //Does not appeart to be blocking
while((size=read(sock1, bufp, (5000-(bufp-buf))))>0){
  printf("size %d\n",size);
 bufp+=size;
   }
 }
close(sock1);
 printf("GOT INFO\n");
 if(timeout==10){strcpy(buf,"NONE");}
 printf("GOT BUF: %s\n",buf);   // In fork this comes back with Empty	
				// string, but has valid data if 	 
				// run seperately.  When forked, Server
				// just stays in select state, never 
				// gets any connections, but clients
				// execute as if they have one.

=================================================================================

Here is the tcp_get_connection() code

/*
 * given a HOST name and service PORT number, return connected TCP
 * socket to the requested service at the requested host.  It will
 * timeout after SECS (if < 0 then hang).  Passes back socket in SOCKP
 * and returns error codes.
 */

/* tcp_get_conn return codes */
#define TCP_NO_ERROR		1		/* no error */
#define TCP_NOT_FOUND		2		/* host not found */
#define TCP_SOCKET_FAILURE	3		/* socket create failure
*/
#define TCP_CONNECT_ERROR	4		/* socket connect error */
#define TCP_CONNECT_TIMEOUT	5		/* socket connect timeout
*/
#define TCP_CONNECT_NONE	6		/* socket didn't connect
*/
#define TCP_TRANSFER_ERROR	7		/* read/write error */

EXPORT	int	tcp_get_conn(const char * host, const int port,
			     const int secs, int * sockp)
{
  struct sockaddr_in	sadr;
  struct hostent	*hostp;
  struct timeval	timeout, *timeoutp;
  fd_set		fds;
  char			**addrp, okay = 0;
  int			sock, ret;
#ifdef __osf__
  struct itimerval	timer;
#endif
  
  /* locate host */
  hostp = gethostbyname(host);
  if (hostp == NULL)
    return TCP_NOT_FOUND;
  
  /* setup internet port */
  sadr.sin_family = (u_short)AF_INET;
  sadr.sin_port = htons(port);
  
  sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  if (sock < 0)
    return TCP_SOCKET_FAILURE;
  
#ifndef __osf__
  /* make the fd non-blocking */
  (void)fcntl(sock, F_SETFL, fcntl(sock, F_GETFL, 0) | O_NONBLOCK);
#endif
  
  if (secs < 0)
    timeoutp = 0L;
  else
    timeoutp = &timeout;
  FD_ZERO(&fds);
  
  /* try to connect to the remote server */
  for (addrp = hostp->h_addr_list; *addrp != NULL; addrp++) {
    (void)memcpy((void *)&sadr.sin_addr, *addrp, sizeof(sadr.sin_addr));

#ifdef __osf__
    /* set the timer */
    timer.it_interval = timeout;
    setitimer(ITIMER_REAL, &timer, NULL);
    (void)signal(SIGALRM, catch_alarm);
    alarm_caught = FALSE;
#endif
    
    /* connect or start the connection */
    ret = connect(sock, (void *)&sadr, sizeof(sadr));

#ifdef __osf__
    /* disable the timer */
    timer.it_value.tv_sec = 0;
    timer.it_value.tv_usec = 0;
    setitimer(ITIMER_REAL, &timer, NULL);
    (void)signal(SIGALRM, SIG_IGN);
#endif

    if (ret == 0) {
      okay = 1;
      break;
    }

#ifdef __osf__
    (void)close(sock);
    
    if (alarm_caught)
      return TCP_CONNECT_TIMEOUT;
    else
      return TCP_CONNECT_ERROR;
#endif

    /* not waiting for connection? */

    if (errno != EINPROGRESS && errno != EWOULDBLOCK) {
      /* connection refused? */

      if (errno == ECONNREFUSED)
	continue;

      /* otherwise error */
      (void)close(sock);
      return TCP_CONNECT_ERROR;
    }
    
    for (;;) {
      FD_SET(sock, &fds);
      if (secs >= 0) {
	timeout.tv_sec = secs;
	timeout.tv_usec = 0;
      }
      
      ret = select(sock + 1, 0L, &fds, 0L, timeoutp);
      if (ret > 0 && FD_ISSET(sock, &fds)) {
	okay = 1;
	break;
      }
      if (ret == 0) {
	(void)close(sock);
	return TCP_CONNECT_TIMEOUT;
      }
      if (ret < 0 && errno != EINTR) {
	(void)close(sock);
	return TCP_CONNECT_ERROR;
      }
    }
    
    if (okay)
      break;
  }
  
  /* connection made? */
  if (okay) {
#ifndef __osf__
    /* turn off non-blocking */
    (void)fcntl(sock, F_SETFL, fcntl(sock, F_GETFL, 0) & ~O_NONBLOCK);
#endif
    *sockp = sock;
    return TCP_NO_ERROR;
  }
  
  (void)close(sock);
  return TCP_CONNECT_NONE;
}





Sean Peck
News Index -- The original News Only Search Engine.
http://www.newsindex.com/
On Sat, 8 Apr 2000, Alfred Perlstein wrote:

> * Sean Peck <speck@news1.newsindex.com> [000408 07:58] wrote:
> > 
> > I am having a bizarre problem with a system on FreeBSD.
> > 
> > The system consists of a server who forks its clients.
> > When the clients are forked, they try to connect to the server and get
> > information.  Unfortunately when they fork off (fork/execlp), they say
> > they connected to
> > server and recieved nothing, yet the server does not register the
> > connection or request for info.  If I run the client independently (not
> > via fork/execlp)  everything works just fine.
> > 
> > This code is deployed and operational on BSDi without a problem, so I
> > assume that this is OS related, does anyone know anything about, or can
> > help me with this?
> 
> Without some example code to demostrate the problem there's not much
> we can do to address this.
> 
> -- 
> -Alfred Perlstein - [bright@wintelcom.net|alfred@freebsd.org]
> "I have the heart of a child; I keep it in a jar on my desk."
> 



To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSI.3.95.1000408122156.882A-100000>