1 #include "syshdrs.h" 2 3 #ifndef NO_SIGNALS 4 extern volatile Sjmp_buf gNetTimeoutJmp; 5 extern volatile Sjmp_buf gPipeJmp; 6 #endif 7 8 #ifndef NO_SIGNALS 9 10 int 11 SRecvmsg(int sfd, void *const msg, int fl, int tlen) 12 { 13 int nread, tleft; 14 vsio_sigproc_t sigalrm, sigpipe; 15 time_t done, now; 16 17 if (tlen < 0) { 18 errno = 0; 19 for (;;) { 20 nread = recvmsg(sfd, (struct msghdr *) msg, fl); 21 if ((nread >= 0) || (errno != EINTR)) 22 return (nread); 23 } 24 } 25 26 if (SSetjmp(gNetTimeoutJmp) != 0) { 27 alarm(0); 28 (void) SSignal(SIGALRM, (sio_sigproc_t) sigalrm); 29 (void) SSignal(SIGPIPE, (sio_sigproc_t) sigpipe); 30 errno = ETIMEDOUT; 31 return (kTimeoutErr); 32 } 33 34 if (SSetjmp(gPipeJmp) != 0) { 35 alarm(0); 36 (void) SSignal(SIGALRM, (sio_sigproc_t) sigalrm); 37 (void) SSignal(SIGPIPE, (sio_sigproc_t) sigpipe); 38 errno = EPIPE; 39 return (kBrokenPipeErr); 40 } 41 42 sigalrm = (vsio_sigproc_t) SSignal(SIGALRM, SIOHandler); 43 sigpipe = (vsio_sigproc_t) SSignal(SIGPIPE, SIOHandler); 44 45 time(&now); 46 done = now + tlen; 47 tleft = (int) (done - now); 48 forever { 49 (void) alarm((unsigned int) tleft); 50 nread = recvmsg(sfd, (struct msghdr *) msg, fl); 51 (void) alarm(0); 52 if (nread >= 0) 53 break; 54 if (errno != EINTR) 55 break; /* Fatal error. */ 56 errno = 0; 57 time(&now); 58 tleft = (int) (done - now); 59 if (tleft < 1) { 60 nread = kTimeoutErr; 61 errno = ETIMEDOUT; 62 break; 63 } 64 } 65 66 (void) SSignal(SIGALRM, (sio_sigproc_t) sigalrm); 67 (void) SSignal(SIGPIPE, (sio_sigproc_t) sigpipe); 68 69 return (nread); 70 } /* SRecvmsg */ 71 72 #elif defined(HAVE_RECVMSG) 73 74 int 75 SRecvmsg(int sfd, void *const msg, int fl, int tlen) 76 { 77 int nread, tleft; 78 time_t done, now; 79 fd_set ss; 80 struct timeval tv; 81 int result; 82 83 if (tlen < 0) { 84 errno = 0; 85 for (;;) { 86 nread = recvmsg(sfd, (struct msghdr *) msg, fl); 87 if ((nread >= 0) || (errno != EINTR)) 88 return (nread); 89 } 90 } 91 92 time(&now); 93 done = now + tlen; 94 tleft = (int) (done - now); 95 forever { 96 97 for (;;) { 98 errno = 0; 99 FD_ZERO(&ss); 100 FD_SET(sfd, &ss); 101 tv.tv_sec = tleft; 102 tv.tv_usec = 0; 103 result = select(sfd + 1, SELECT_TYPE_ARG234 &ss, NULL, NULL, SELECT_TYPE_ARG5 &tv); 104 if (result == 1) { 105 /* ready */ 106 break; 107 } else if (result == 0) { 108 /* timeout */ 109 errno = ETIMEDOUT; 110 SETWSATIMEOUTERR 111 return (kTimeoutErr); 112 } else if (errno != EINTR) { 113 return (-1); 114 } 115 } 116 117 nread = recvmsg(sfd, (struct msghdr *) msg, fl); 118 119 if (nread >= 0) 120 break; 121 if (errno != EINTR) 122 break; /* Fatal error. */ 123 errno = 0; 124 time(&now); 125 tleft = (int) (done - now); 126 if (tleft < 1) { 127 nread = kTimeoutErr; 128 errno = ETIMEDOUT; 129 SETWSATIMEOUTERR 130 break; 131 } 132 } 133 134 return (nread); 135 } /* SRecvmsg */ 136 137 #endif 138