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(my_socket fd, uint timeout);
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);
104
105
CHARSET_INFO *default_client_charset_info = &my_charset_latin1;
108
109
char drizzle_server_last_error[DRIZZLE_ERRMSG_SIZE];
110
111
/****************************************************************************
111
A modified version of connect(). my_connect() allows you to specify
112
A modified version of connect(). connect_with_timeout() allows you to specify
112
113
a timeout value, in seconds, that we should wait until we
113
114
derermine we can't connect to a particular host. If timeout is 0,
114
my_connect() will behave exactly like connect().
115
connect_with_timeout() will behave exactly like connect().
116
117
Base version coded by Steve Bernacki, Jr. <steve@navinet.net>
117
118
*****************************************************************************/
119
int my_connect(my_socket fd, const struct sockaddr *name, uint namelen,
121
int connect_with_timeout(int fd, const struct sockaddr *name, uint namelen, int32_t timeout)
122
123
int flags, res, s_err;
171
if (res < 0 || !(ufds.revents & (POLLIN | POLLPRI)))
172
if (res < 0 || !(ufds.revents & (POLLIN | POLLPRI)) || (ufds.revents & POLLHUP))
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 */
1342
1271
memset(&hints, 0, sizeof(hints));
1343
1272
hints.ai_socktype= SOCK_STREAM;
1344
hints.ai_protocol= IPPROTO_TCP;
1345
hints.ai_family= AF_UNSPEC;
1273
/* OSX 10.5 was failing unless defined only as support IPV4 */
1274
#ifdef TARGET_OS_OSX
1275
hints.ai_family= AF_INET;
1347
1279
snprintf(port_buf, NI_MAXSERV, "%d", port);
1348
1280
gai_errno= getaddrinfo(host, port_buf, &hints, &res_lst);
1358
1290
/* We only look at the first item (something to think about changing in the future) */
1359
1291
t_res= res_lst;
1361
my_socket sock= socket(t_res->ai_family, t_res->ai_socktype,
1293
int sock= socket(t_res->ai_family, t_res->ai_socktype,
1362
1294
t_res->ai_protocol);
1363
1295
if (sock == SOCKET_ERROR)
1380
if (my_connect(sock, t_res->ai_addr, t_res->ai_addrlen,
1381
drizzle->options.connect_timeout))
1312
if (connect_with_timeout(sock, t_res->ai_addr, t_res->ai_addrlen, drizzle->options.connect_timeout))
1383
1314
set_drizzle_extended_error(drizzle, CR_CONN_HOST_ERROR, unknown_sqlstate,
1384
1315
ER(CR_CONN_HOST_ERROR), host, socket_errno);