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