Path: utzoo!utgpu!news-server.csri.toronto.edu!mailrus!ncar!unmvax!unmvax.cs.unm.edu!mike From: mike@turing.cs.unm.edu (Michael I. Bushnell) Newsgroups: comp.unix.wizards Subject: Re: buffer i/o using read(2) on BSD sockets Message-ID: Date: 16 Mar 90 18:38:11 GMT References: <637@lot.ACA.MCC.COM> <85@cvbnetPrime.COM> Sender: news@unmvax.cs.unm.edu (The News service) Reply-To: mike@unmvax.cs.unm.edu Organization: University of No Money, Albuquerque, New Mexico Lines: 46 In-Reply-To: aperez@cvbnet.UUCP's message of 8 Mar 90 15:43:46 GMT In article <85@cvbnetPrime.COM> aperez@cvbnet.UUCP (Arturo Perez x6739) writes: >This is one of my pet peeves about BSD sockets. There is no way >to read an arbitrary amount of data from a socket. You have to be >aware of the kernel level buffering NO MATTER WHAT LEVEL your writing >your code at; i.e. apps, system, etc. >Why can't the kernel block your process until you get all the data you're >asking for (unless, of course, FIONBIO or O_NDELAY is set)? If I'm >willing to wait, I'm willing to wait. And if the connection goes down during >the transfer, I can live with that, too, just return an error. >Why was such a silly decision made? Nothing new. The same is true of terminal I/O. All you need is: int myread(des, buf, buflen) int des, buflen char *buf; { char *bp = buf; int nread = 0, nbytes; while (nread != buflen) { nbytes = read(des, bp, buflen - nread); if (nbytes == -1) return -1; /* Or whatever else you want */ bp += nbytes, nread += nbytes; } } This will solve your problem quite nicely. Any questions? Now you *don't* need to know about the low-level buffering. -- Michael I. Bushnell \ This above all; to thine own self be true LIBERTE, EGALITE, FRATERNITE \ And it must follow, as the night the day, mike@unmvax.cs.unm.edu /\ Thou canst not be false to any man. CARPE DIEM / \ Farewell: my blessing season this in thee!