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