2
* Drizzle Client & Protocol Library
4
* Copyright (C) 2008 Eric Day (eday@oddments.org)
7
* Use and distribution licensed under the BSD license. See
8
* the COPYING file in this directory for full text.
13
* @brief Connection Definitions
19
* @addtogroup drizzle_con_static Static Connection Declarations
20
* @ingroup drizzle_con
25
* Set socket options for a connection.
27
* @param[in] con Connection structure previously initialized with
28
* drizzle_con_create(), drizzle_con_clone(), or related functions.
29
* @return Standard drizzle return value.
31
static drizzle_return_t _con_setsockopt(drizzle_con_st *con);
39
int drizzle_con_fd(const drizzle_con_st *con)
44
drizzle_return_t drizzle_con_set_fd(drizzle_con_st *con, int fd)
50
ret= _con_setsockopt(con);
51
if (ret != DRIZZLE_RETURN_OK)
52
con->drizzle->last_errno= errno;
57
void drizzle_con_close(drizzle_con_st *con)
65
con->options&= (drizzle_con_options_t)~DRIZZLE_CON_READY;
66
con->packet_number= 0;
67
con->buffer_ptr= con->buffer;
72
drizzle_state_reset(con);
75
drizzle_return_t drizzle_con_set_events(drizzle_con_st *con, short events)
79
if ((con->events | events) == con->events)
80
return DRIZZLE_RETURN_OK;
84
if (con->drizzle->event_watch_fn != NULL)
86
ret= con->drizzle->event_watch_fn(con, con->events,
87
con->drizzle->event_watch_context);
88
if (ret != DRIZZLE_RETURN_OK)
90
drizzle_con_close(con);
95
return DRIZZLE_RETURN_OK;
98
drizzle_return_t drizzle_con_set_revents(drizzle_con_st *con, short revents)
100
drizzle_return_t ret;
103
con->options|= DRIZZLE_CON_IO_READY;
105
con->revents= revents;
107
/* Remove external POLLOUT watch if we didn't ask for it. Otherwise we spin
108
forever until another POLLIN state change. This is much more efficient
109
than removing POLLOUT on every state change since some external polling
110
mechanisms need to use a system call to change flags (like Linux epoll). */
111
if (revents & POLLOUT && !(con->events & POLLOUT) &&
112
con->drizzle->event_watch_fn != NULL)
114
ret= con->drizzle->event_watch_fn(con, con->events,
115
con->drizzle->event_watch_context);
116
if (ret != DRIZZLE_RETURN_OK)
118
drizzle_con_close(con);
123
con->events&= (short)~revents;
125
return DRIZZLE_RETURN_OK;
128
drizzle_st *drizzle_con_drizzle(const drizzle_con_st *con)
133
const char *drizzle_con_error(const drizzle_con_st *con)
135
return drizzle_error(con->drizzle);
138
int drizzle_con_errno(const drizzle_con_st *con)
140
return drizzle_errno(con->drizzle);
143
uint16_t drizzle_con_error_code(const drizzle_con_st *con)
145
return drizzle_error_code(con->drizzle);
148
const char *drizzle_con_sqlstate(const drizzle_con_st *con)
150
return drizzle_sqlstate(con->drizzle);
153
drizzle_con_options_t drizzle_con_options(const drizzle_con_st *con)
158
void drizzle_con_set_options(drizzle_con_st *con,
159
drizzle_con_options_t options)
161
con->options= options;
164
void drizzle_con_add_options(drizzle_con_st *con,
165
drizzle_con_options_t options)
167
con->options|= options;
169
/* If asking for the experimental Drizzle protocol, clean the MySQL flag. */
170
if (con->options & DRIZZLE_CON_EXPERIMENTAL)
171
con->options&= (drizzle_con_options_t)~DRIZZLE_CON_MYSQL;
174
void drizzle_con_remove_options(drizzle_con_st *con,
175
drizzle_con_options_t options)
177
con->options&= ~options;
180
const char *drizzle_con_host(const drizzle_con_st *con)
182
if (con->socket_type == DRIZZLE_CON_SOCKET_TCP)
184
if (con->socket.tcp.host == NULL && !(con->options & DRIZZLE_CON_LISTEN))
185
return DRIZZLE_DEFAULT_TCP_HOST;
187
return con->socket.tcp.host;
193
in_port_t drizzle_con_port(const drizzle_con_st *con)
195
if (con->socket_type == DRIZZLE_CON_SOCKET_TCP)
197
if (con->socket.tcp.port != 0)
198
return con->socket.tcp.port;
200
if (con->options & DRIZZLE_CON_MYSQL)
201
return DRIZZLE_DEFAULT_TCP_PORT_MYSQL;
203
return DRIZZLE_DEFAULT_TCP_PORT;
209
void drizzle_con_set_tcp(drizzle_con_st *con, const char *host, in_port_t port)
211
drizzle_con_reset_addrinfo(con);
213
con->socket_type= DRIZZLE_CON_SOCKET_TCP;
216
con->socket.tcp.host= NULL;
219
con->socket.tcp.host= con->socket.tcp.host_buffer;
220
strncpy(con->socket.tcp.host, host, NI_MAXHOST);
221
con->socket.tcp.host[NI_MAXHOST - 1]= 0;
224
con->socket.tcp.port= port;
227
const char *drizzle_con_user(const drizzle_con_st *con)
232
const char *drizzle_con_password(const drizzle_con_st *con)
234
return con->password;
237
void drizzle_con_set_auth(drizzle_con_st *con, const char *user,
238
const char *password)
244
strncpy(con->user, user, DRIZZLE_MAX_USER_SIZE);
245
con->user[DRIZZLE_MAX_USER_SIZE - 1]= 0;
248
if (password == NULL)
252
strncpy(con->password, password, DRIZZLE_MAX_PASSWORD_SIZE);
253
con->password[DRIZZLE_MAX_PASSWORD_SIZE - 1]= 0;
257
const char *drizzle_con_db(const drizzle_con_st *con)
262
void drizzle_con_set_db(drizzle_con_st *con, const char *db)
268
strncpy(con->db, db, DRIZZLE_MAX_DB_SIZE);
269
con->db[DRIZZLE_MAX_DB_SIZE - 1]= 0;
273
void *drizzle_con_context(const drizzle_con_st *con)
278
void drizzle_con_set_context(drizzle_con_st *con, void *context)
280
con->context= context;
283
void drizzle_con_set_context_free_fn(drizzle_con_st *con,
284
drizzle_con_context_free_fn *function)
286
con->context_free_fn= function;
289
uint8_t drizzle_con_protocol_version(const drizzle_con_st *con)
291
return con->protocol_version;
294
const char *drizzle_con_server_version(const drizzle_con_st *con)
296
return con->server_version;
299
uint32_t drizzle_con_server_version_number(const drizzle_con_st *con)
307
current= con->server_version;
309
major= (uint32_t)strtoul(current, &end, 10);
311
minor= (uint32_t)strtoul(current, &end, 10);
313
version= (uint32_t)strtoul(current, &end, 10);
315
return (major * 10000) + (minor * 100) + version;
318
uint32_t drizzle_con_thread_id(const drizzle_con_st *con)
320
return con->thread_id;
323
const uint8_t *drizzle_con_scramble(const drizzle_con_st *con)
325
return con->scramble;
328
drizzle_capabilities_t drizzle_con_capabilities(const drizzle_con_st *con)
330
return con->capabilities;
333
drizzle_charset_t drizzle_con_charset(const drizzle_con_st *con)
338
drizzle_con_status_t drizzle_con_status(const drizzle_con_st *con)
343
uint32_t drizzle_con_max_packet_size(const drizzle_con_st *con)
345
return con->max_packet_size;
352
drizzle_return_t drizzle_con_connect(drizzle_con_st *con)
354
if (con->options & DRIZZLE_CON_READY)
355
return DRIZZLE_RETURN_OK;
357
if (drizzle_state_none(con))
359
if (!(con->options & DRIZZLE_CON_RAW_PACKET))
361
drizzle_state_push(con, drizzle_state_handshake_server_read);
362
drizzle_state_push(con, drizzle_state_packet_read);
365
drizzle_state_push(con, drizzle_state_connect);
366
drizzle_state_push(con, drizzle_state_addrinfo);
369
return drizzle_state_loop(con);
372
drizzle_result_st *drizzle_con_quit(drizzle_con_st *con,
373
drizzle_result_st *result,
374
drizzle_return_t *ret_ptr)
376
return drizzle_con_command_write(con, result, DRIZZLE_COMMAND_QUIT, NULL, 0,
380
drizzle_result_st *drizzle_quit(drizzle_con_st *con,
381
drizzle_result_st *result,
382
drizzle_return_t *ret_ptr)
384
return drizzle_con_quit(con, result, ret_ptr);
387
drizzle_result_st *drizzle_con_select_db(drizzle_con_st *con,
388
drizzle_result_st *result,
390
drizzle_return_t *ret_ptr)
392
drizzle_con_set_db(con, db);
393
return drizzle_con_command_write(con, result, DRIZZLE_COMMAND_INIT_DB,
394
db, strlen(db), strlen(db), ret_ptr);
397
drizzle_result_st *drizzle_select_db(drizzle_con_st *con,
398
drizzle_result_st *result,
400
drizzle_return_t *ret_ptr)
402
return drizzle_con_select_db(con, result, db, ret_ptr);
405
drizzle_result_st *drizzle_con_shutdown(drizzle_con_st *con,
406
drizzle_result_st *result,
407
drizzle_return_t *ret_ptr)
409
if (con->options & DRIZZLE_CON_MYSQL)
411
return drizzle_con_command_write(con, result, DRIZZLE_COMMAND_SHUTDOWN,
415
return drizzle_con_command_write(con, result, DRIZZLE_COMMAND_SHUTDOWN, NULL,
419
drizzle_result_st *drizzle_shutdown(drizzle_con_st *con,
420
drizzle_result_st *result, uint32_t level,
421
drizzle_return_t *ret_ptr)
424
return drizzle_con_shutdown(con, result, ret_ptr);
427
drizzle_result_st *drizzle_con_ping(drizzle_con_st *con,
428
drizzle_result_st *result,
429
drizzle_return_t *ret_ptr)
431
return drizzle_con_command_write(con, result, DRIZZLE_COMMAND_PING, NULL, 0,
435
drizzle_result_st *drizzle_ping(drizzle_con_st *con,
436
drizzle_result_st *result,
437
drizzle_return_t *ret_ptr)
439
return drizzle_con_ping(con, result, ret_ptr);
442
drizzle_result_st *drizzle_con_command_write(drizzle_con_st *con,
443
drizzle_result_st *result,
444
drizzle_command_t command,
445
const void *data, size_t size,
447
drizzle_return_t *ret_ptr)
449
if (!(con->options & DRIZZLE_CON_READY))
451
if (con->options & DRIZZLE_CON_RAW_PACKET)
453
drizzle_set_error(con->drizzle, "drizzle_command_write",
454
"connection not ready");
455
*ret_ptr= DRIZZLE_RETURN_NOT_READY;
459
*ret_ptr= drizzle_con_connect(con);
460
if (*ret_ptr != DRIZZLE_RETURN_OK)
464
if (drizzle_state_none(con))
466
if (con->options & (DRIZZLE_CON_RAW_PACKET | DRIZZLE_CON_NO_RESULT_READ))
470
con->result= drizzle_result_create(con, result);
471
if (con->result == NULL)
473
*ret_ptr= DRIZZLE_RETURN_MEMORY;
478
con->command= command;
479
con->command_data= (uint8_t *)data;
480
con->command_size= size;
481
con->command_offset= 0;
482
con->command_total= total;
484
drizzle_state_push(con, drizzle_state_command_write);
486
else if (con->command_data == NULL)
488
con->command_data= (uint8_t *)data;
489
con->command_size= size;
492
*ret_ptr= drizzle_state_loop(con);
493
if (*ret_ptr == DRIZZLE_RETURN_PAUSE)
494
*ret_ptr= DRIZZLE_RETURN_OK;
495
else if (*ret_ptr != DRIZZLE_RETURN_OK &&
496
*ret_ptr != DRIZZLE_RETURN_IO_WAIT &&
497
*ret_ptr != DRIZZLE_RETURN_ERROR_CODE)
499
drizzle_result_free(con->result);
510
drizzle_return_t drizzle_con_listen(drizzle_con_st *con)
512
if (con->options & DRIZZLE_CON_READY)
513
return DRIZZLE_RETURN_OK;
515
if (drizzle_state_none(con))
517
drizzle_state_push(con, drizzle_state_listen);
518
drizzle_state_push(con, drizzle_state_addrinfo);
521
return drizzle_state_loop(con);
524
int drizzle_con_backlog(const drizzle_con_st *con)
529
void drizzle_con_set_backlog(drizzle_con_st *con, int backlog)
531
con->backlog= backlog;
534
void drizzle_con_set_protocol_version(drizzle_con_st *con,
535
uint8_t protocol_version)
537
con->protocol_version= protocol_version;
540
void drizzle_con_set_server_version(drizzle_con_st *con,
541
const char *server_version)
543
if (server_version == NULL)
544
con->server_version[0]= 0;
547
strncpy(con->server_version, server_version,
548
DRIZZLE_MAX_SERVER_VERSION_SIZE);
549
con->server_version[DRIZZLE_MAX_SERVER_VERSION_SIZE - 1]= 0;
553
void drizzle_con_set_thread_id(drizzle_con_st *con, uint32_t thread_id)
555
con->thread_id= thread_id;
558
void drizzle_con_set_scramble(drizzle_con_st *con, const uint8_t *scramble)
560
if (scramble == NULL)
564
con->scramble= con->scramble_buffer;
565
memcpy(con->scramble, scramble, DRIZZLE_MAX_SCRAMBLE_SIZE);
569
void drizzle_con_set_capabilities(drizzle_con_st *con,
570
drizzle_capabilities_t capabilities)
572
con->capabilities= capabilities;
575
void drizzle_con_set_charset(drizzle_con_st *con, drizzle_charset_t charset)
577
con->charset= charset;
580
void drizzle_con_set_status(drizzle_con_st *con, drizzle_con_status_t status)
585
void drizzle_con_set_max_packet_size(drizzle_con_st *con,
586
uint32_t max_packet_size)
588
con->max_packet_size= max_packet_size;
591
void drizzle_con_copy_handshake(drizzle_con_st *con, drizzle_con_st *from)
593
drizzle_con_set_auth(con, from->user, NULL);
594
drizzle_con_set_scramble(con, from->scramble);
595
drizzle_con_set_db(con, from->db);
596
drizzle_con_set_protocol_version(con, from->protocol_version);
597
drizzle_con_set_server_version(con, from->server_version);
598
drizzle_con_set_thread_id(con, from->thread_id);
599
drizzle_con_set_scramble(con, from->scramble);
600
drizzle_con_set_capabilities(con, from->capabilities);
601
drizzle_con_set_charset(con, from->charset);
602
drizzle_con_set_status(con, from->status);
603
drizzle_con_set_max_packet_size(con, from->max_packet_size);
606
void *drizzle_con_command_read(drizzle_con_st *con,
607
drizzle_command_t *command, size_t *offset,
608
size_t *size, size_t *total,
609
drizzle_return_t *ret_ptr)
611
if (drizzle_state_none(con))
613
con->packet_number= 0;
614
con->command_offset= 0;
615
con->command_total= 0;
617
drizzle_state_push(con, drizzle_state_command_read);
618
drizzle_state_push(con, drizzle_state_packet_read);
621
*offset= con->command_offset;
623
*ret_ptr= drizzle_state_loop(con);
624
if (*ret_ptr == DRIZZLE_RETURN_PAUSE)
625
*ret_ptr= DRIZZLE_RETURN_OK;
627
*command= con->command;
628
*size= con->command_size;
629
*total= con->command_total;
631
return con->command_data;
634
void *drizzle_con_command_buffer(drizzle_con_st *con,
635
drizzle_command_t *command, size_t *total,
636
drizzle_return_t *ret_ptr)
638
uint8_t *command_data;
642
command_data= drizzle_con_command_read(con, command, &offset, &size, total,
644
if (*ret_ptr != DRIZZLE_RETURN_OK)
647
if (command_data == NULL)
653
if (con->command_buffer == NULL)
655
con->command_buffer= malloc((*total) + 1);
656
if (con->command_buffer == NULL)
658
drizzle_set_error(con->drizzle, "drizzle_command_buffer", "malloc");
659
*ret_ptr= DRIZZLE_RETURN_MEMORY;
664
memcpy(con->command_buffer + offset, command_data, size);
666
while ((offset + size) != (*total))
668
command_data= drizzle_con_command_read(con, command, &offset, &size, total,
670
if (*ret_ptr != DRIZZLE_RETURN_OK)
673
memcpy(con->command_buffer + offset, command_data, size);
676
command_data= con->command_buffer;
677
con->command_buffer= NULL;
678
command_data[*total]= 0;
687
void drizzle_con_reset_addrinfo(drizzle_con_st *con)
689
switch (con->socket_type)
691
case DRIZZLE_CON_SOCKET_TCP:
692
if (con->socket.tcp.addrinfo != NULL)
694
freeaddrinfo(con->socket.tcp.addrinfo);
695
con->socket.tcp.addrinfo= NULL;
699
case DRIZZLE_CON_SOCKET_UDS:
700
con->socket.uds.addrinfo.ai_addr= NULL;
707
con->addrinfo_next= NULL;
714
drizzle_return_t drizzle_state_addrinfo(drizzle_con_st *con)
716
drizzle_con_tcp_st *tcp;
718
char port[NI_MAXSERV];
722
drizzle_log_debug(con->drizzle, "drizzle_state_addrinfo");
724
switch (con->socket_type)
726
case DRIZZLE_CON_SOCKET_TCP:
727
tcp= &(con->socket.tcp);
729
if (tcp->addrinfo != NULL)
731
freeaddrinfo(tcp->addrinfo);
736
snprintf(port, NI_MAXSERV, "%u", tcp->port);
737
else if (con->options & DRIZZLE_CON_MYSQL)
738
snprintf(port, NI_MAXSERV, "%u", DRIZZLE_DEFAULT_TCP_PORT_MYSQL);
740
snprintf(port, NI_MAXSERV, "%u", DRIZZLE_DEFAULT_TCP_PORT);
742
memset(&ai, 0, sizeof(struct addrinfo));
743
ai.ai_socktype= SOCK_STREAM;
744
ai.ai_protocol= IPPROTO_TCP;
746
if (con->options & DRIZZLE_CON_LISTEN)
748
ai.ai_flags = AI_PASSIVE;
749
ai.ai_family = AF_UNSPEC;
754
if (tcp->host == NULL)
755
host= DRIZZLE_DEFAULT_TCP_HOST;
760
ret= getaddrinfo(host, port, &ai, &(tcp->addrinfo));
763
drizzle_set_error(con->drizzle, "drizzle_state_addrinfo",
764
"getaddrinfo:%s", gai_strerror(ret));
765
return DRIZZLE_RETURN_GETADDRINFO;
768
con->addrinfo_next= tcp->addrinfo;
772
case DRIZZLE_CON_SOCKET_UDS:
773
con->addrinfo_next= &(con->socket.uds.addrinfo);
780
drizzle_state_pop(con);
781
return DRIZZLE_RETURN_OK;
784
drizzle_return_t drizzle_state_connect(drizzle_con_st *con)
787
drizzle_return_t dret;
789
drizzle_log_debug(con->drizzle, "drizzle_state_connect");
793
(void)close(con->fd);
797
if (con->addrinfo_next == NULL)
799
drizzle_set_error(con->drizzle, "drizzle_state_connect",
800
"could not connect");
801
drizzle_state_reset(con);
802
return DRIZZLE_RETURN_COULD_NOT_CONNECT;
805
con->fd= socket(con->addrinfo_next->ai_family,
806
con->addrinfo_next->ai_socktype,
807
con->addrinfo_next->ai_protocol);
810
drizzle_set_error(con->drizzle, "drizzle_state_connect", "socket:%d",
812
con->drizzle->last_errno= errno;
813
return DRIZZLE_RETURN_ERRNO;
816
dret= _con_setsockopt(con);
817
if (dret != DRIZZLE_RETURN_OK)
819
con->drizzle->last_errno= errno;
825
ret= connect(con->fd, con->addrinfo_next->ai_addr,
826
con->addrinfo_next->ai_addrlen);
829
/*Mapping windows specific error codes to Posix*/
830
errno = WSAGetLastError();
842
drizzle_log_crazy(con->drizzle, "connect return=%d errno=%d", ret, errno);
846
con->addrinfo_next= NULL;
850
if (errno == EAGAIN || errno == EINTR)
853
if (errno == EINPROGRESS)
855
drizzle_state_pop(con);
856
drizzle_state_push(con, drizzle_state_connecting);
857
return DRIZZLE_RETURN_OK;
860
if (errno == ECONNREFUSED || errno == ENETUNREACH || errno == ETIMEDOUT)
862
con->addrinfo_next= con->addrinfo_next->ai_next;
863
return DRIZZLE_RETURN_OK;
866
drizzle_set_error(con->drizzle, "drizzle_state_connect", "connect:%d",
868
con->drizzle->last_errno= errno;
869
return DRIZZLE_RETURN_ERRNO;
872
drizzle_state_pop(con);
873
return DRIZZLE_RETURN_OK;
876
drizzle_return_t drizzle_state_connecting(drizzle_con_st *con)
878
drizzle_return_t ret;
880
drizzle_log_debug(con->drizzle, "drizzle_state_connecting");
884
if (con->revents & POLLOUT)
886
drizzle_state_pop(con);
887
return DRIZZLE_RETURN_OK;
889
else if (con->revents & (POLLERR | POLLHUP | POLLNVAL))
892
drizzle_state_pop(con);
893
drizzle_state_push(con, drizzle_state_connect);
894
con->addrinfo_next= con->addrinfo_next->ai_next;
895
return DRIZZLE_RETURN_OK;
898
ret= drizzle_con_set_events(con, POLLOUT);
899
if (ret != DRIZZLE_RETURN_OK)
902
if (con->drizzle->options & DRIZZLE_NON_BLOCKING)
903
return DRIZZLE_RETURN_IO_WAIT;
905
ret= drizzle_con_wait(con->drizzle);
906
if (ret != DRIZZLE_RETURN_OK)
911
drizzle_return_t drizzle_state_read(drizzle_con_st *con)
913
drizzle_return_t ret;
916
drizzle_log_debug(con->drizzle, "drizzle_state_read");
918
if (con->buffer_size == 0)
919
con->buffer_ptr= con->buffer;
920
else if ((con->buffer_ptr - con->buffer) > (DRIZZLE_MAX_BUFFER_SIZE / 2))
922
memmove(con->buffer, con->buffer_ptr, con->buffer_size);
923
con->buffer_ptr= con->buffer;
928
read_size = recv(con->fd, (char *)con->buffer_ptr + con->buffer_size,
929
(size_t)DRIZZLE_MAX_BUFFER_SIZE -
930
((size_t)(con->buffer_ptr - con->buffer) +
931
con->buffer_size),0);
933
/*Get windows error codes and map it to Posix*/
934
errno = WSAGetLastError();
944
drizzle_log_crazy(con->drizzle, "read fd=%d return=%zd errno=%d", con->fd,
949
drizzle_set_error(con->drizzle, "drizzle_state_read",
950
"lost connection to server (EOF)");
951
return DRIZZLE_RETURN_LOST_CONNECTION;
953
else if (read_size == -1)
957
ret= drizzle_con_set_events(con, POLLIN);
958
if (ret != DRIZZLE_RETURN_OK)
961
if (con->drizzle->options & DRIZZLE_NON_BLOCKING)
962
return DRIZZLE_RETURN_IO_WAIT;
964
ret= drizzle_con_wait(con->drizzle);
965
if (ret != DRIZZLE_RETURN_OK)
970
else if (errno == ECONNREFUSED)
973
drizzle_state_pop(con);
974
drizzle_state_push(con, drizzle_state_connect);
975
con->addrinfo_next= con->addrinfo_next->ai_next;
976
return DRIZZLE_RETURN_OK;
978
else if (errno == EINTR)
980
else if (errno == EPIPE || errno == ECONNRESET)
982
drizzle_set_error(con->drizzle, "drizzle_state_read",
983
"lost connection to server (%d)", errno);
984
return DRIZZLE_RETURN_LOST_CONNECTION;
987
drizzle_set_error(con->drizzle, "drizzle_state_read", "read:%d", errno);
988
con->drizzle->last_errno= errno;
989
return DRIZZLE_RETURN_ERRNO;
992
con->buffer_size+= (size_t)read_size;
996
drizzle_state_pop(con);;
997
return DRIZZLE_RETURN_OK;
1000
drizzle_return_t drizzle_state_write(drizzle_con_st *con)
1002
drizzle_return_t ret;
1005
drizzle_log_debug(con->drizzle, "drizzle_state_write");
1007
while (con->buffer_size != 0)
1010
write_size = send(con->fd,(char *) con->buffer_ptr, con->buffer_size,0);
1012
drizzle_log_crazy(con->drizzle, "write fd=%d return=%zd errno=%d", con->fd,
1015
if (write_size == 0)
1017
drizzle_set_error(con->drizzle, "drizzle_state_write",
1018
"lost connection to server (EOF)");
1019
return DRIZZLE_RETURN_LOST_CONNECTION;
1021
else if (write_size == -1)
1023
if (errno == EAGAIN)
1025
ret= drizzle_con_set_events(con, POLLOUT);
1026
if (ret != DRIZZLE_RETURN_OK)
1029
if (con->drizzle->options & DRIZZLE_NON_BLOCKING)
1030
return DRIZZLE_RETURN_IO_WAIT;
1032
ret= drizzle_con_wait(con->drizzle);
1033
if (ret != DRIZZLE_RETURN_OK)
1038
else if (errno == EINTR)
1040
else if (errno == EPIPE || errno == ECONNRESET)
1042
drizzle_set_error(con->drizzle, "drizzle_state_write",
1043
"lost connection to server (%d)", errno);
1044
return DRIZZLE_RETURN_LOST_CONNECTION;
1047
drizzle_set_error(con->drizzle, "drizzle_state_write", "write:%d", errno);
1048
con->drizzle->last_errno= errno;
1049
return DRIZZLE_RETURN_ERRNO;
1052
con->buffer_ptr+= write_size;
1053
con->buffer_size-= (size_t)write_size;
1054
if (con->buffer_size == 0)
1058
con->buffer_ptr= con->buffer;
1060
drizzle_state_pop(con);
1061
return DRIZZLE_RETURN_OK;
1064
drizzle_return_t drizzle_state_listen(drizzle_con_st *con)
1066
char host[NI_MAXHOST];
1067
char port[NI_MAXSERV];
1071
drizzle_con_st *new_con;
1073
for (; con->addrinfo_next != NULL;
1074
con->addrinfo_next= con->addrinfo_next->ai_next)
1076
ret= getnameinfo(con->addrinfo_next->ai_addr,
1077
con->addrinfo_next->ai_addrlen, host, NI_MAXHOST, port,
1078
NI_MAXSERV, NI_NUMERICHOST | NI_NUMERICSERV);
1081
drizzle_set_error(con->drizzle, "drizzle_state_listen", "getnameinfo:%s",
1083
return DRIZZLE_RETURN_GETADDRINFO;
1086
/* Call to socket() can fail for some getaddrinfo results, try another. */
1087
fd= socket(con->addrinfo_next->ai_family, con->addrinfo_next->ai_socktype,
1088
con->addrinfo_next->ai_protocol);
1091
drizzle_log_info(con->drizzle, "could not listen on %s:%s", host, port);
1092
drizzle_set_error(con->drizzle, "drizzle_state_listen", "socket:%d",
1099
ret= setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,(const char*) &opt, sizeof(opt));
1101
ret= setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
1106
drizzle_set_error(con->drizzle, "drizzle_state_listen", "setsockopt:%d",
1108
return DRIZZLE_RETURN_ERRNO;
1111
ret= bind(fd, con->addrinfo_next->ai_addr, con->addrinfo_next->ai_addrlen);
1115
drizzle_set_error(con->drizzle, "drizzle_state_listen", "bind:%d", errno);
1116
if (errno == EADDRINUSE)
1120
drizzle_log_info(con->drizzle, "could not listen on %s:%s", host,
1127
return DRIZZLE_RETURN_ERRNO;
1130
if (listen(fd, con->backlog) == -1)
1133
drizzle_set_error(con->drizzle, "drizzle_state_listen", "listen:%d",
1135
return DRIZZLE_RETURN_ERRNO;
1145
new_con= drizzle_con_clone(con->drizzle, NULL, con);
1146
if (new_con == NULL)
1149
return DRIZZLE_RETURN_MEMORY;
1155
/* Wait for read events on the listening socket. */
1156
ret= drizzle_con_set_events(new_con, POLLIN);
1157
if (ret != DRIZZLE_RETURN_OK)
1159
drizzle_con_free(new_con);
1163
drizzle_log_info(con->drizzle, "listening on %s:%s", host, port);
1166
/* Report last socket() error if we couldn't find an address to bind. */
1168
return DRIZZLE_RETURN_ERRNO;
1170
drizzle_state_pop(con);
1171
return DRIZZLE_RETURN_OK;
1175
* Static Definitions
1178
static drizzle_return_t _con_setsockopt(drizzle_con_st *con)
1181
struct linger linger;
1182
struct timeval waittime;
1187
ret= setsockopt(con->fd, IPPROTO_TCP, TCP_NODELAY, (const char*)&ret,
1188
(socklen_t)sizeof(int));
1190
ret= setsockopt(con->fd, IPPROTO_TCP, TCP_NODELAY, &ret,
1191
(socklen_t)sizeof(int));
1194
if (ret == -1 && errno != EOPNOTSUPP)
1196
drizzle_set_error(con->drizzle, "_con_setsockopt",
1197
"setsockopt:TCP_NODELAY:%d", errno);
1198
return DRIZZLE_RETURN_ERRNO;
1202
linger.l_linger= DRIZZLE_DEFAULT_SOCKET_TIMEOUT;
1205
ret= setsockopt(con->fd, SOL_SOCKET, SO_LINGER, (const char*)&linger,
1206
(socklen_t)sizeof(struct linger));
1208
ret= setsockopt(con->fd, SOL_SOCKET, SO_LINGER, &linger,
1209
(socklen_t)sizeof(struct linger));
1214
drizzle_set_error(con->drizzle, "_con_setsockopt",
1215
"setsockopt:SO_LINGER:%d", errno);
1216
return DRIZZLE_RETURN_ERRNO;
1219
waittime.tv_sec= DRIZZLE_DEFAULT_SOCKET_TIMEOUT;
1220
waittime.tv_usec= 0;
1223
ret= setsockopt(con->fd, SOL_SOCKET, SO_SNDTIMEO, (const char*)&waittime,
1224
(socklen_t)sizeof(struct timeval));
1226
ret= setsockopt(con->fd, SOL_SOCKET, SO_SNDTIMEO, &waittime,
1227
(socklen_t)sizeof(struct timeval));
1230
if (ret == -1 && errno != ENOPROTOOPT)
1232
drizzle_set_error(con->drizzle, "_con_setsockopt",
1233
"setsockopt:SO_SNDTIMEO:%d", errno);
1234
return DRIZZLE_RETURN_ERRNO;
1238
ret= setsockopt(con->fd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&waittime,
1239
(socklen_t)sizeof(struct timeval));
1241
ret= setsockopt(con->fd, SOL_SOCKET, SO_RCVTIMEO, &waittime,
1242
(socklen_t)sizeof(struct timeval));
1245
if (ret == -1 && errno != ENOPROTOOPT)
1247
drizzle_set_error(con->drizzle, "_con_setsockopt",
1248
"setsockopt:SO_RCVTIMEO:%d", errno);
1249
return DRIZZLE_RETURN_ERRNO;
1252
ret= DRIZZLE_DEFAULT_SOCKET_SEND_SIZE;
1254
ret= setsockopt(con->fd, SOL_SOCKET, SO_SNDBUF, (const char*)&ret, (socklen_t)sizeof(int));
1256
ret= setsockopt(con->fd, SOL_SOCKET, SO_SNDBUF, &ret, (socklen_t)sizeof(int));
1260
drizzle_set_error(con->drizzle, "_con_setsockopt",
1261
"setsockopt:SO_SNDBUF:%d", errno);
1262
return DRIZZLE_RETURN_ERRNO;
1265
ret= DRIZZLE_DEFAULT_SOCKET_RECV_SIZE;
1267
ret= setsockopt(con->fd, SOL_SOCKET, SO_RCVBUF, (const char*)&ret, (socklen_t)sizeof(int));
1269
ret= setsockopt(con->fd, SOL_SOCKET, SO_RCVBUF, &ret, (socklen_t)sizeof(int));
1273
drizzle_set_error(con->drizzle, "_con_setsockopt",
1274
"setsockopt:SO_RCVBUF:%d", errno);
1275
return DRIZZLE_RETURN_ERRNO;
1278
#if defined (_WIN32)
1279
unsigned long asyncmode = 1;
1280
ioctlsocket(con->fd, FIONBIO, &asyncmode);
1282
ret= fcntl(con->fd, F_GETFL, 0);
1285
drizzle_set_error(con->drizzle, "_con_setsockopt", "fcntl:F_GETFL:%d",
1287
return DRIZZLE_RETURN_ERRNO;
1290
ret= fcntl(con->fd, F_SETFL, ret | O_NONBLOCK);
1293
drizzle_set_error(con->drizzle, "_con_setsockopt", "fcntl:F_SETFL:%d",
1295
return DRIZZLE_RETURN_ERRNO;
1299
return DRIZZLE_RETURN_OK;