145
148
* Base version coded by Steve Bernacki, Jr. <steve@navinet.net>
146
149
*****************************************************************************/
151
int socket_block(my_socket s,my_bool blocked)
154
unsigned long socket_blocked= blocked ? 0 : 1;
155
return ioctlsocket(s, FIONBIO, &socket_blocked);
157
int flags= fcntl(s, F_GETFL, 0);
162
return fcntl(s, F_SETFL, flags);
148
166
static int connect2(my_socket s, const struct sockaddr *name, uint namelen,
151
#if defined(_WIN32) || defined(OS2)
152
return connect(s, (struct sockaddr*) name, namelen);
154
int flags, res, s_err;
155
170
socklen_t s_err_size = sizeof(uint);
172
struct pollfd poll_fd;
157
175
struct timeval tv;
158
time_t start_time, now_time;
161
If they passed us a timeout of zero, we should behave
162
exactly like the normal connect() call does.
166
179
return connect(s, (struct sockaddr*) name, namelen);
168
flags = fcntl(s, F_GETFL, 0); /* Set socket to not block */
170
fcntl(s, F_SETFL, flags | O_NONBLOCK); /* and save the flags.. */
181
/* set socket to non blocking */
182
if (socket_block(s, 0) == SOCKET_ERROR)
185
res= connect(s, (struct sockaddr*) name, namelen);
190
if (GetLastError() != WSAEWOULDBLOCK &&
191
GetLastError() != WSAEINPROGRESS)
193
if (errno != EINPROGRESS)
173
res = connect(s, (struct sockaddr*) name, namelen);
174
s_err = errno; /* Save the error... */
175
fcntl(s, F_SETFL, flags);
176
if ((res != 0) && (s_err != EINPROGRESS))
197
memset(&poll_fd, 0, sizeof(struct pollfd));
198
poll_fd.events= POLLOUT | POLLERR;
201
/* connection timeout in milliseconds */
202
res= poll(&poll_fd, 1, (timeout > -1) ? timeout * 1000 : timeout);
178
errno = s_err; /* Restore it */
206
/* Error= - 1, timeout = 0 */
181
if (res == 0) /* Connected quickly! */
185
Otherwise, our connection is "in progress." We can use
186
the select() call to wait up to a specified period of time
187
for the connection to suceed. If select() returns 0
188
(after waiting howevermany seconds), our socket never became
189
writable (host is probably unreachable.) Otherwise, if
190
select() returns 1, then one of two conditions exist:
192
1. An error occured. We use getsockopt() to check for this.
193
2. The connection was set up sucessfully: getsockopt() will
194
return 0 as an error.
196
Thanks goes to Andrew Gierth <andrew@erlenstar.demon.co.uk>
197
who posted this method of timing out a connect() in
198
comp.unix.programmer on August 15th, 1997.
202
216
FD_SET(s, &sfds);
204
select could be interrupted by a signal, and if it is,
205
the timeout should be adjusted and the select restarted
206
to work around OSes that don't restart select and
207
implementations of select that don't adjust tv upon
208
failure to reflect the time remaining
210
start_time = time(NULL);
213
tv.tv_sec = (long) timeout;
215
#if defined(HPUX) && defined(THREAD)
216
if ((res = select(s+1, NULL, (int*) &sfds, NULL, &tv)) > 0)
219
if ((res = select(s+1, NULL, &sfds, NULL, &tv)) > 0)
219
memset(&tv, 0, sizeof(struct timeval));
222
res= select(s+1, NULL, &sfds, &efds, &tv);
222
if (res == 0) /* timeout */
225
timeout-= (uint) (now_time - start_time);
226
if (errno != EINTR || (int) timeout <= 0)
231
select() returned something more interesting than zero, let's
232
see if we have any errors. If the next two statements pass,
233
we've got an open socket!
237
228
if (getsockopt(s, SOL_SOCKET, SO_ERROR, (char*) &s_err, &s_err_size) != 0)