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 SSendtoByName(int sfd, const char *const buf, size_t size, int fl, const char *const toAddrStr, int tlen) 12 { 13 int nwrote, tleft, result; 14 vsio_sigproc_t sigalrm, sigpipe; 15 time_t done, now; 16 struct sockaddr_in toAddr; 17 18 if ((result = AddrStrToAddr(toAddrStr, &toAddr, -1)) < 0) { 19 return (result); 20 } 21 22 if (SSetjmp(gNetTimeoutJmp) != 0) { 23 alarm(0); 24 (void) SSignal(SIGALRM, (sio_sigproc_t) sigalrm); 25 (void) SSignal(SIGPIPE, (sio_sigproc_t) sigpipe); 26 errno = ETIMEDOUT; 27 return (kTimeoutErr); 28 } 29 30 if (SSetjmp(gPipeJmp) != 0) { 31 alarm(0); 32 (void) SSignal(SIGALRM, (sio_sigproc_t) sigalrm); 33 (void) SSignal(SIGPIPE, (sio_sigproc_t) sigpipe); 34 errno = EPIPE; 35 return (kBrokenPipeErr); 36 } 37 38 sigalrm = (vsio_sigproc_t) SSignal(SIGALRM, SIOHandler); 39 sigpipe = (vsio_sigproc_t) SSignal(SIGPIPE, SIOHandler); 40 41 time(&now); 42 done = now + tlen; 43 tleft = (int) (done - now); 44 forever { 45 (void) alarm((unsigned int) tleft); 46 nwrote = sendto(sfd, buf, size, fl, 47 (struct sockaddr *) &toAddr, 48 (int) sizeof(struct sockaddr_in)); 49 (void) alarm(0); 50 if (nwrote >= 0) 51 break; 52 if (errno != EINTR) 53 break; /* Fatal error. */ 54 errno = 0; 55 time(&now); 56 tleft = (int) (done - now); 57 if (tleft < 1) { 58 nwrote = kTimeoutErr; 59 errno = ETIMEDOUT; 60 break; 61 } 62 } 63 64 (void) SSignal(SIGALRM, (sio_sigproc_t) sigalrm); 65 (void) SSignal(SIGPIPE, (sio_sigproc_t) sigpipe); 66 67 return (nwrote); 68 } /* SSendtoByName */ 69 70 #else 71 72 int 73 SSendtoByName(int sfd, const char *const buf, size_t size, int fl, const char *const toAddrStr, int tlen) 74 { 75 int nwrote, tleft; 76 time_t done, now; 77 fd_set ss; 78 struct timeval tv; 79 int result; 80 struct sockaddr_in toAddr; 81 82 if ((result = AddrStrToAddr(toAddrStr, &toAddr, -1)) < 0) { 83 return (result); 84 } 85 86 time(&now); 87 done = now + tlen; 88 nwrote = 0; 89 forever { 90 forever { 91 if (now >= done) { 92 errno = ETIMEDOUT; 93 return (kTimeoutErr); 94 } 95 tleft = (int) (done - now); 96 errno = 0; 97 FD_ZERO(&ss); 98 FD_SET(sfd, &ss); 99 tv.tv_sec = tleft; 100 tv.tv_usec = 0; 101 result = select(sfd + 1, NULL, SELECT_TYPE_ARG234 &ss, NULL, SELECT_TYPE_ARG5 &tv); 102 if (result == 1) { 103 /* ready */ 104 break; 105 } else if (result == 0) { 106 /* timeout */ 107 errno = ETIMEDOUT; 108 return (kTimeoutErr); 109 } else if (errno != EINTR) { 110 return (-1); 111 } 112 time(&now); 113 } 114 115 nwrote = sendto(sfd, buf, size, fl, 116 (struct sockaddr *) &toAddr, 117 (int) sizeof(struct sockaddr_in)); 118 119 if (nwrote >= 0) 120 break; 121 if (errno != EINTR) 122 break; /* Fatal error. */ 123 } 124 125 return (nwrote); 126 } /* SSendto */ 127 128 #endif 129 130 131 132 int 133 SendtoByName(int sfd, const char *const buf, size_t size, const char *const toAddrStr) 134 { 135 int result; 136 struct sockaddr_in toAddr; 137 138 if ((result = AddrStrToAddr(toAddrStr, &toAddr, -1)) < 0) { 139 return (result); 140 } 141 142 do { 143 result = sendto(sfd, buf, size, 0, 144 (struct sockaddr *) &toAddr, 145 (int) sizeof(struct sockaddr_in)); 146 } while ((result < 0) && (errno == EINTR)); 147 148 return (result); 149 } /* SendtoByName */ 150