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
SSendto(int sfd,const char * const buf,size_t size,int fl,const struct sockaddr_in * const toAddr,int tlen)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
SSendto(int sfd,const char * const buf,size_t size,int fl,const struct sockaddr_in * const toAddr,int tlen)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
Sendto(int sfd,const char * const buf,size_t size,const struct sockaddr_in * const toAddr)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