1 #include "syshdrs.h" 2 3 #if !defined(NO_UNIX_DOMAIN_SOCKETS) && !defined(NO_SIGNALS) 4 5 extern volatile Sjmp_buf gNetTimeoutJmp; 6 extern volatile Sjmp_buf gPipeJmp; 7 8 int 9 URecvfrom(int sfd, char *const buf, size_t size, int fl, struct sockaddr_un *const fromAddr, int *ualen, int tlen) 10 { 11 int nread, tleft; 12 vsio_sigproc_t sigalrm, sigpipe; 13 time_t done, now; 14 15 if (SSetjmp(gNetTimeoutJmp) != 0) { 16 alarm(0); 17 (void) SSignal(SIGALRM, (sio_sigproc_t) sigalrm); 18 (void) SSignal(SIGPIPE, (sio_sigproc_t) sigpipe); 19 errno = ETIMEDOUT; 20 return (kTimeoutErr); 21 } 22 23 if (SSetjmp(gPipeJmp) != 0) { 24 alarm(0); 25 (void) SSignal(SIGALRM, (sio_sigproc_t) sigalrm); 26 (void) SSignal(SIGPIPE, (sio_sigproc_t) sigpipe); 27 errno = EPIPE; 28 return (kBrokenPipeErr); 29 } 30 31 sigalrm = (vsio_sigproc_t) SSignal(SIGALRM, SIOHandler); 32 sigpipe = (vsio_sigproc_t) SSignal(SIGPIPE, SIOHandler); 33 34 time(&now); 35 done = now + tlen; 36 tleft = (int) (done - now); 37 forever { 38 *ualen = sizeof(struct sockaddr_un); 39 (void) alarm((unsigned int) tleft); 40 nread = recvfrom(sfd, buf, size, fl, 41 (struct sockaddr *) fromAddr, ualen); 42 (void) alarm(0); 43 if (nread >= 0) 44 break; 45 if (errno != EINTR) 46 break; /* Fatal error. */ 47 errno = 0; 48 time(&now); 49 tleft = (int) (done - now); 50 if (tleft < 1) { 51 nread = kTimeoutErr; 52 errno = ETIMEDOUT; 53 break; 54 } 55 } 56 57 (void) SSignal(SIGALRM, (sio_sigproc_t) sigalrm); 58 (void) SSignal(SIGPIPE, (sio_sigproc_t) sigpipe); 59 60 return (nread); 61 } /* URecvfrom */ 62 63 #endif 64