From owner-freebsd-hackers Sat Apr 8 10: 5:25 2000 Delivered-To: freebsd-hackers@freebsd.org Received: from fw.wintelcom.net (ns1.wintelcom.net [209.1.153.20]) by hub.freebsd.org (Postfix) with ESMTP id 4D26437B6EE for ; Sat, 8 Apr 2000 10:05:20 -0700 (PDT) (envelope-from bright@fw.wintelcom.net) Received: (from bright@localhost) by fw.wintelcom.net (8.10.0/8.10.0) id e38HVZW28954; Sat, 8 Apr 2000 10:31:35 -0700 (PDT) Date: Sat, 8 Apr 2000 10:31:35 -0700 From: Alfred Perlstein To: Sean Peck Cc: freebsd-hackers@FreeBSD.ORG Subject: Re: FreeBSD 3.3 fork/Exec bug? Message-ID: <20000408103135.Z4381@fw.wintelcom.net> References: <20000408084711.W4381@fw.wintelcom.net> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Mailer: Mutt 1.0.1i In-Reply-To: ; from speck@news1.newsindex.com on Sat, Apr 08, 2000 at 12:38:20PM -0400 Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG * Sean Peck [000408 09:47] wrote: > Alfred, > > Here is the code being used. ew. :P There seems to be some problems in your tcp connect library... > 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 36 is EINPROGRESS, somehow your connect function isn't handling non-blocking connects properly. > 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_ZERO here? > FD_SET(sock, &fds); > if (secs >= 0) { > timeout.tv_sec = secs; > timeout.tv_usec = 0; > } > > ret = select(sock + 1, 0L, &fds, 0L, timeoutp); 0L -> NULL please :) > 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; > } > Pick up a copy of Unix Netork Programming vol I, see page 411, it has a very good example on how to do non-blocking connects properly. -- -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