99
99
static void drizzle_close_free_options(DRIZZLE *drizzle);
100
100
static void drizzle_close_free(DRIZZLE *drizzle);
102
static int wait_for_data(int fd, int32_t timeout);
103
int connect_with_timeout(int fd, const struct sockaddr *name, uint namelen, int32_t timeout);
102
static int wait_for_data(my_socket fd, uint timeout);
105
104
CHARSET_INFO *default_client_charset_info = &my_charset_latin1;
109
108
char drizzle_server_last_error[DRIZZLE_ERRMSG_SIZE];
111
110
/****************************************************************************
112
A modified version of connect(). connect_with_timeout() allows you to specify
111
A modified version of connect(). my_connect() allows you to specify
113
112
a timeout value, in seconds, that we should wait until we
114
113
derermine we can't connect to a particular host. If timeout is 0,
115
connect_with_timeout() will behave exactly like connect().
114
my_connect() will behave exactly like connect().
117
116
Base version coded by Steve Bernacki, Jr. <steve@navinet.net>
118
117
*****************************************************************************/
121
int connect_with_timeout(int fd, const struct sockaddr *name, uint namelen, int32_t timeout)
119
int my_connect(my_socket fd, const struct sockaddr *name, uint namelen,
123
122
int flags, res, s_err;
172
if (res < 0 || !(ufds.revents & (POLLIN | POLLPRI)) || (ufds.revents & POLLHUP))
171
if (res < 0 || !(ufds.revents & (POLLIN | POLLPRI)))
175
SOCKOPT_OPTLEN_TYPE s_err_size = sizeof(uint);
178
time_t start_time, now_time;
181
if (fd >= FD_SETSIZE) /* Check if wrong error */
182
return 0; /* Can't use timeout */
185
Our connection is "in progress." We can use the select() call to wait
186
up to a specified period of time for the connection to suceed.
187
If select() returns 0 (after waiting howevermany seconds), our socket
188
never became writable (host is probably unreachable.) Otherwise, if
189
select() returns 1, then one of two conditions exist:
191
1. An error occured. We use getsockopt() to check for this.
192
2. The connection was set up sucessfully: getsockopt() will
193
return 0 as an error.
195
Thanks goes to Andrew Gierth <andrew@erlenstar.demon.co.uk>
196
who posted this method of timing out a connect() in
197
comp.unix.programmer on August 15th, 1997.
203
select could be interrupted by a signal, and if it is,
204
the timeout should be adjusted and the select restarted
205
to work around OSes that don't restart select and
206
implementations of select that don't adjust tv upon
207
failure to reflect the time remaining
209
start_time= my_time(0);
212
tv.tv_sec = (long) timeout;
215
if ((res = select(fd+1, NULL, (int*) &sfds, NULL, &tv)) > 0)
218
if ((res = select(fd+1, NULL, &sfds, NULL, &tv)) > 0)
221
if (res == 0) /* timeout */
223
now_time= my_time(0);
224
timeout-= (uint) (now_time - start_time);
225
if (errno != EINTR || (int) timeout <= 0)
230
select() returned something more interesting than zero, let's
231
see if we have any errors. If the next two statements pass,
232
we've got an open socket!
236
if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (char*) &s_err, &s_err_size) != 0)
240
{ /* getsockopt could succeed */
242
return(-1); /* but return an error... */
245
#endif /* HAVE_POLL */
1271
1342
memset(&hints, 0, sizeof(hints));
1272
1343
hints.ai_socktype= SOCK_STREAM;
1273
/* OSX 10.5 was failing unless defined only as support IPV4 */
1274
#ifdef TARGET_OS_OSX
1275
hints.ai_family= AF_INET;
1344
hints.ai_protocol= IPPROTO_TCP;
1345
hints.ai_family= AF_UNSPEC;
1279
1347
snprintf(port_buf, NI_MAXSERV, "%d", port);
1280
1348
gai_errno= getaddrinfo(host, port_buf, &hints, &res_lst);
1290
1358
/* We only look at the first item (something to think about changing in the future) */
1291
1359
t_res= res_lst;
1293
int sock= socket(t_res->ai_family, t_res->ai_socktype,
1361
my_socket sock= socket(t_res->ai_family, t_res->ai_socktype,
1294
1362
t_res->ai_protocol);
1295
1363
if (sock == SOCKET_ERROR)
1312
if (connect_with_timeout(sock, t_res->ai_addr, t_res->ai_addrlen, drizzle->options.connect_timeout))
1380
if (my_connect(sock, t_res->ai_addr, t_res->ai_addrlen,
1381
drizzle->options.connect_timeout))
1314
1383
set_drizzle_extended_error(drizzle, CR_CONN_HOST_ERROR, unknown_sqlstate,
1315
1384
ER(CR_CONN_HOST_ERROR), host, socket_errno);