1 #include "syshdrs.h" 2 3 #if !defined(NO_SIGNALS) && defined(SIGPIPE) 4 extern volatile Sjmp_buf gPipeJmp; 5 #endif 6 7 /* Read up to "size" bytes on sfd. 8 * 9 * If "retry" is on, after a successful read of less than "size" 10 * bytes, it will attempt to read more, upto "size." 11 * 12 * Although "retry" would seem to indicate you may want to always 13 * read "size" bytes or else it is an error, even with that on you 14 * may get back a value < size. Set "retry" to 0 when you want to 15 * return as soon as there is a chunk of data whose size is <= "size". 16 */ 17 18 int 19 PRead(int sfd, char *const buf0, size_t size, int retry) 20 { 21 int nread; 22 volatile int nleft; 23 char *volatile buf = buf0; 24 #if !defined(NO_SIGNALS) && defined(SIGPIPE) 25 vsio_sigproc_t sigpipe; 26 27 if (SSetjmp(gPipeJmp) != 0) { 28 (void) SSignal(SIGPIPE, (sio_sigproc_t) sigpipe); 29 nread = size - nleft; 30 if (nread > 0) 31 return (nread); 32 errno = EPIPE; 33 return (kBrokenPipeErr); 34 } 35 36 sigpipe = (vsio_sigproc_t) SSignal(SIGPIPE, SIOHandler); 37 #endif 38 errno = 0; 39 40 nleft = (int) size; 41 forever { 42 nread = read(sfd, buf, nleft); 43 if (nread <= 0) { 44 if (nread == 0) { 45 /* EOF */ 46 nread = size - nleft; 47 goto done; 48 } else if (errno != EINTR) { 49 nread = size - nleft; 50 if (nread == 0) 51 nread = -1; 52 goto done; 53 } else { 54 errno = 0; 55 nread = 0; 56 /* Try again. */ 57 } 58 } 59 nleft -= nread; 60 if ((nleft <= 0) || (retry == 0)) 61 break; 62 buf += nread; 63 } 64 nread = size - nleft; 65 66 done: 67 #if !defined(NO_SIGNALS) && defined(SIGPIPE) 68 (void) SSignal(SIGPIPE, (sio_sigproc_t) sigpipe); 69 #endif 70 return (nread); 71 } /* PRead */ 72