ncftp for win32 3.0.3
[reactos.git] / reactos / apps / utils / net / ncftp / sio / SSendtoByName.c
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 */