Return to BSD News archive
Xref: sserve comp.unix.ultrix:13608 comp.unix.bsd:4798 Newsgroups: comp.unix.ultrix,comp.unix.bsd Path: sserve!manuel!munnari.oz.au!spool.mu.edu!wupost!uunet!mcsun!sun4nl!fwi.uva.nl!casper From: casper@fwi.uva.nl (Casper H.S. Dik) Subject: Re: A major BSD socket bug? Message-ID: <1992Sep9.095942.12013@fwi.uva.nl> Sender: news@fwi.uva.nl Nntp-Posting-Host: adam.fwi.uva.nl Organization: FWI, University of Amsterdam References: <1992Sep9.053147.411@lmpsbbs.comm.mot.com> Date: Wed, 9 Sep 1992 09:59:42 GMT Lines: 60 rittle@supra (Loren James Rittle) writes: >I have reproduced this bug (be it in my code or the BSD OS) under >both ULTRIX 4.2A and SunOS 4.1.2. As I don't read any sun groups, I didn't >know where to crosspost there. The example below is under 20 lines of code. This is not a bug, but a possibly unexpect effect of a call to recvfrom(). First a bit of comment: >#define ERROR(a) do { perror (a); exit (1); } while (0) >#define SEND(m) if (sendto (s,m,sizeof m,0,&a,sizeof a)==-1) ERROR ("sendto"); >#define RECV rcv.sin_addr.S_un.S_addr = 0; m[0] = '\0'; \ > recvfrom (s, m, sizeof m, 0, &rcv, &rcvsize); \ > printf ("%d %s\n", rcv.sin_addr.S_un.S_addr, m) Yuck! This may seem to make the code more readable, but only if you think that less code is more readable code. Don't do this is production code. >int main () >{ > if ((s = socket (AF_INET, SOCK_DGRAM, 0)) == -1) ERROR ("socket"); > if (bind (s, &a, sizeof a) == -1) ERROR ("bind"); > if (ioctl (s, FIONBIO, (char *) &one) == -1) ERROR ("ioctl"); > SEND ("hello1"); > RECV; /* AND PRINT NETWORK ADDRESS OF SENDER AND MESSAGE */ > RECV; /* THIS RECV DOESN'T FIND ANYTHING BUT DOESN'T BLOCK */ This is where thing go wrong. You have initialised the variable recvsize to the size of the address structure. But, this parameter is a value/result parameter. On entry, you specify the size available for the address, on exit the system specifies the real size of the address. When reading fails, recvfrom doesn't store an address (or stores 0 bytes). This is indictating by modifying the recvfrom variable and giving it the value zero. All subsequent calls to recvfrom will not return an address. If you add ``rvcsize = sizeof rcv;'' to your RECV; macro, recvfrom will return the address, as it will know there is space available to write the address. One can argue that recvfrom shouldn't touch rcvsize when an error code is returned, but there is no valid reason not to reinitialise the rcvsize variable. I also see that you do: 57> cc test2.c -ldl on the Sun. This probably indicates that someone screwed up when installing a new shared libc. (I.e., if it doesn't work without the -ldl) Casper -- | Casper H.S. Dik | casper@fwi.uva.nl