~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to libdrizzle/conn.c

  • Committer: Brian Aker
  • Date: 2008-07-08 16:17:31 UTC
  • Revision ID: brian@tangent.org-20080708161731-io36j7igglok79py
DATE cleanup.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Drizzle Client & Protocol Library
3
 
 *
4
 
 * Copyright (C) 2008 Eric Day (eday@oddments.org)
5
 
 * All rights reserved.
6
 
 *
7
 
 * Use and distribution licensed under the BSD license.  See
8
 
 * the COPYING file in this directory for full text.
9
 
 */
10
 
 
11
 
/**
12
 
 * @file
13
 
 * @brief Connection Definitions
14
 
 */
15
 
 
16
 
#include "common.h"
17
 
 
18
 
/**
19
 
 * @addtogroup drizzle_con_static Static Connection Declarations
20
 
 * @ingroup drizzle_con
21
 
 * @{
22
 
 */
23
 
 
24
 
/**
25
 
 * Set socket options for a connection.
26
 
 *
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.
30
 
 */
31
 
static drizzle_return_t _con_setsockopt(drizzle_con_st *con);
32
 
 
33
 
/** @} */
34
 
 
35
 
/*
36
 
 * Common Definitions
37
 
 */
38
 
 
39
 
int drizzle_con_fd(const drizzle_con_st *con)
40
 
{
41
 
  return con->fd;
42
 
}
43
 
 
44
 
drizzle_return_t drizzle_con_set_fd(drizzle_con_st *con, int fd)
45
 
{
46
 
  drizzle_return_t ret;
47
 
 
48
 
  con->fd= fd;
49
 
 
50
 
  ret= _con_setsockopt(con);
51
 
  if (ret != DRIZZLE_RETURN_OK)
52
 
    con->drizzle->last_errno= errno;
53
 
 
54
 
  return ret;
55
 
}
56
 
 
57
 
void drizzle_con_close(drizzle_con_st *con)
58
 
{
59
 
  if (con->fd == -1)
60
 
    return;
61
 
 
62
 
  (void)close(con->fd);
63
 
  con->fd= -1;
64
 
 
65
 
  con->options&= (drizzle_con_options_t)~DRIZZLE_CON_READY;
66
 
  con->packet_number= 0;
67
 
  con->buffer_ptr= con->buffer;
68
 
  con->buffer_size= 0;
69
 
  con->events= 0;
70
 
  con->revents= 0;
71
 
 
72
 
  drizzle_state_reset(con);
73
 
}
74
 
 
75
 
drizzle_return_t drizzle_con_set_events(drizzle_con_st *con, short events)
76
 
{
77
 
  drizzle_return_t ret;
78
 
 
79
 
  if ((con->events | events) == con->events)
80
 
    return DRIZZLE_RETURN_OK;
81
 
 
82
 
  con->events|= events;
83
 
 
84
 
  if (con->drizzle->event_watch_fn != NULL)
85
 
  {
86
 
    ret= con->drizzle->event_watch_fn(con, con->events,
87
 
                                      con->drizzle->event_watch_context);
88
 
    if (ret != DRIZZLE_RETURN_OK)
89
 
    {
90
 
      drizzle_con_close(con);
91
 
      return ret;
92
 
    }
93
 
  }
94
 
 
95
 
  return DRIZZLE_RETURN_OK;
96
 
}
97
 
 
98
 
drizzle_return_t drizzle_con_set_revents(drizzle_con_st *con, short revents)
99
 
{
100
 
  drizzle_return_t ret;
101
 
 
102
 
  if (revents != 0)
103
 
    con->options|= DRIZZLE_CON_IO_READY;
104
 
 
105
 
  con->revents= revents;
106
 
 
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)
113
 
  {
114
 
    ret= con->drizzle->event_watch_fn(con, con->events,
115
 
                                      con->drizzle->event_watch_context);
116
 
    if (ret != DRIZZLE_RETURN_OK)
117
 
    {
118
 
      drizzle_con_close(con);
119
 
      return ret;
120
 
    }
121
 
  }
122
 
 
123
 
  con->events&= (short)~revents;
124
 
 
125
 
  return DRIZZLE_RETURN_OK;
126
 
}
127
 
 
128
 
drizzle_st *drizzle_con_drizzle(const drizzle_con_st *con)
129
 
{
130
 
  return con->drizzle;
131
 
}
132
 
 
133
 
const char *drizzle_con_error(const drizzle_con_st *con)
134
 
{
135
 
  return drizzle_error(con->drizzle);
136
 
}
137
 
 
138
 
int drizzle_con_errno(const drizzle_con_st *con)
139
 
{
140
 
  return drizzle_errno(con->drizzle);
141
 
}
142
 
 
143
 
uint16_t drizzle_con_error_code(const drizzle_con_st *con)
144
 
{
145
 
  return drizzle_error_code(con->drizzle);
146
 
}
147
 
 
148
 
const char *drizzle_con_sqlstate(const drizzle_con_st *con)
149
 
{
150
 
  return drizzle_sqlstate(con->drizzle);
151
 
}
152
 
 
153
 
drizzle_con_options_t drizzle_con_options(const drizzle_con_st *con)
154
 
{
155
 
  return con->options;
156
 
}
157
 
 
158
 
void drizzle_con_set_options(drizzle_con_st *con,
159
 
                             drizzle_con_options_t options)
160
 
{
161
 
  con->options= options;
162
 
}
163
 
 
164
 
void drizzle_con_add_options(drizzle_con_st *con,
165
 
                             drizzle_con_options_t options)
166
 
{
167
 
  con->options|= options;
168
 
 
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;
172
 
}
173
 
 
174
 
void drizzle_con_remove_options(drizzle_con_st *con,
175
 
                                drizzle_con_options_t options)
176
 
{
177
 
  con->options&= ~options;
178
 
}
179
 
 
180
 
const char *drizzle_con_host(const drizzle_con_st *con)
181
 
{
182
 
  if (con->socket_type == DRIZZLE_CON_SOCKET_TCP)
183
 
  {
184
 
    if (con->socket.tcp.host == NULL && !(con->options & DRIZZLE_CON_LISTEN))
185
 
      return DRIZZLE_DEFAULT_TCP_HOST;
186
 
 
187
 
    return con->socket.tcp.host;
188
 
  }
189
 
 
190
 
  return NULL;
191
 
}
192
 
 
193
 
in_port_t drizzle_con_port(const drizzle_con_st *con)
194
 
{
195
 
  if (con->socket_type == DRIZZLE_CON_SOCKET_TCP)
196
 
  {
197
 
    if (con->socket.tcp.port != 0)
198
 
      return con->socket.tcp.port;
199
 
 
200
 
    if (con->options & DRIZZLE_CON_MYSQL)
201
 
      return DRIZZLE_DEFAULT_TCP_PORT_MYSQL;
202
 
 
203
 
    return DRIZZLE_DEFAULT_TCP_PORT;
204
 
  }
205
 
 
206
 
  return 0;
207
 
}
208
 
 
209
 
void drizzle_con_set_tcp(drizzle_con_st *con, const char *host, in_port_t port)
210
 
{
211
 
  drizzle_con_reset_addrinfo(con);
212
 
 
213
 
  con->socket_type= DRIZZLE_CON_SOCKET_TCP;
214
 
 
215
 
  if (host == NULL)
216
 
    con->socket.tcp.host= NULL;
217
 
  else
218
 
  {
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;
222
 
  }
223
 
 
224
 
  con->socket.tcp.port= port;
225
 
}
226
 
 
227
 
const char *drizzle_con_user(const drizzle_con_st *con)
228
 
{
229
 
  return con->user;
230
 
}
231
 
 
232
 
const char *drizzle_con_password(const drizzle_con_st *con)
233
 
{
234
 
  return con->password;
235
 
}
236
 
 
237
 
void drizzle_con_set_auth(drizzle_con_st *con, const char *user,
238
 
                          const char *password)
239
 
{
240
 
  if (user == NULL)
241
 
    con->user[0]= 0;
242
 
  else
243
 
  {
244
 
    strncpy(con->user, user, DRIZZLE_MAX_USER_SIZE);
245
 
    con->user[DRIZZLE_MAX_USER_SIZE - 1]= 0;
246
 
  }
247
 
 
248
 
  if (password == NULL)
249
 
    con->password[0]= 0;
250
 
  else
251
 
  {
252
 
    strncpy(con->password, password, DRIZZLE_MAX_PASSWORD_SIZE);
253
 
    con->password[DRIZZLE_MAX_PASSWORD_SIZE - 1]= 0;
254
 
  }
255
 
}
256
 
 
257
 
const char *drizzle_con_db(const drizzle_con_st *con)
258
 
{
259
 
  return con->db;
260
 
}
261
 
 
262
 
void drizzle_con_set_db(drizzle_con_st *con, const char *db)
263
 
{
264
 
  if (db == NULL)
265
 
    con->db[0]= 0;
266
 
  else
267
 
  {
268
 
    strncpy(con->db, db, DRIZZLE_MAX_DB_SIZE);
269
 
    con->db[DRIZZLE_MAX_DB_SIZE - 1]= 0;
270
 
  }
271
 
}
272
 
 
273
 
void *drizzle_con_context(const drizzle_con_st *con)
274
 
{
275
 
  return con->context;
276
 
}
277
 
 
278
 
void drizzle_con_set_context(drizzle_con_st *con, void *context)
279
 
{
280
 
  con->context= context;
281
 
}
282
 
 
283
 
void drizzle_con_set_context_free_fn(drizzle_con_st *con,
284
 
                                     drizzle_con_context_free_fn *function)
285
 
{
286
 
  con->context_free_fn= function;
287
 
}
288
 
 
289
 
uint8_t drizzle_con_protocol_version(const drizzle_con_st *con)
290
 
{
291
 
  return con->protocol_version;
292
 
}
293
 
 
294
 
const char *drizzle_con_server_version(const drizzle_con_st *con)
295
 
{
296
 
  return con->server_version;
297
 
}
298
 
 
299
 
uint32_t drizzle_con_server_version_number(const drizzle_con_st *con)
300
 
{
301
 
  uint32_t major;
302
 
  uint32_t minor;
303
 
  uint32_t version;
304
 
  const char *current;
305
 
  char *end;
306
 
 
307
 
  current= con->server_version;
308
 
 
309
 
  major= (uint32_t)strtoul(current, &end, 10);
310
 
  current= end + 1;
311
 
  minor= (uint32_t)strtoul(current, &end, 10);
312
 
  current= end + 1;
313
 
  version= (uint32_t)strtoul(current, &end, 10);
314
 
 
315
 
  return (major * 10000) + (minor * 100) + version;
316
 
}
317
 
 
318
 
uint32_t drizzle_con_thread_id(const drizzle_con_st *con)
319
 
{
320
 
  return con->thread_id;
321
 
}
322
 
 
323
 
const uint8_t *drizzle_con_scramble(const drizzle_con_st *con)
324
 
{
325
 
  return con->scramble;
326
 
}
327
 
 
328
 
drizzle_capabilities_t drizzle_con_capabilities(const drizzle_con_st *con)
329
 
{
330
 
  return con->capabilities;
331
 
}
332
 
 
333
 
drizzle_charset_t drizzle_con_charset(const drizzle_con_st *con)
334
 
{
335
 
  return con->charset;
336
 
}
337
 
 
338
 
drizzle_con_status_t drizzle_con_status(const drizzle_con_st *con)
339
 
{
340
 
  return con->status;
341
 
}
342
 
 
343
 
uint32_t drizzle_con_max_packet_size(const drizzle_con_st *con)
344
 
{
345
 
  return con->max_packet_size;
346
 
}
347
 
 
348
 
/*
349
 
 * Client Definitions
350
 
 */
351
 
 
352
 
drizzle_return_t drizzle_con_connect(drizzle_con_st *con)
353
 
{
354
 
  if (con->options & DRIZZLE_CON_READY)
355
 
    return DRIZZLE_RETURN_OK;
356
 
 
357
 
  if (drizzle_state_none(con))
358
 
  {
359
 
    if (!(con->options & DRIZZLE_CON_RAW_PACKET))
360
 
    {
361
 
      drizzle_state_push(con, drizzle_state_handshake_server_read);
362
 
      drizzle_state_push(con, drizzle_state_packet_read);
363
 
    }
364
 
 
365
 
    drizzle_state_push(con, drizzle_state_connect);
366
 
    drizzle_state_push(con, drizzle_state_addrinfo);
367
 
  }
368
 
 
369
 
  return drizzle_state_loop(con);
370
 
}
371
 
 
372
 
drizzle_result_st *drizzle_con_quit(drizzle_con_st *con,
373
 
                                    drizzle_result_st *result,
374
 
                                    drizzle_return_t *ret_ptr)
375
 
{
376
 
  return drizzle_con_command_write(con, result, DRIZZLE_COMMAND_QUIT, NULL, 0,
377
 
                                   0, ret_ptr);
378
 
}
379
 
 
380
 
drizzle_result_st *drizzle_quit(drizzle_con_st *con,
381
 
                                drizzle_result_st *result,
382
 
                                drizzle_return_t *ret_ptr)
383
 
{
384
 
  return drizzle_con_quit(con, result, ret_ptr);
385
 
}
386
 
 
387
 
drizzle_result_st *drizzle_con_select_db(drizzle_con_st *con,
388
 
                                         drizzle_result_st *result,
389
 
                                         const char *db,
390
 
                                         drizzle_return_t *ret_ptr)
391
 
{
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);
395
 
}
396
 
 
397
 
drizzle_result_st *drizzle_select_db(drizzle_con_st *con,
398
 
                                     drizzle_result_st *result,
399
 
                                     const char *db,
400
 
                                     drizzle_return_t *ret_ptr)
401
 
{
402
 
  return drizzle_con_select_db(con, result, db, ret_ptr);
403
 
}
404
 
 
405
 
drizzle_result_st *drizzle_con_shutdown(drizzle_con_st *con,
406
 
                                        drizzle_result_st *result,
407
 
                                        drizzle_return_t *ret_ptr)
408
 
{
409
 
  if (con->options & DRIZZLE_CON_MYSQL)
410
 
  {
411
 
    return drizzle_con_command_write(con, result, DRIZZLE_COMMAND_SHUTDOWN,
412
 
                                     "0", 1, 1, ret_ptr);
413
 
  }
414
 
 
415
 
  return drizzle_con_command_write(con, result, DRIZZLE_COMMAND_SHUTDOWN, NULL,
416
 
                                   0, 0, ret_ptr);
417
 
}
418
 
 
419
 
drizzle_result_st *drizzle_shutdown(drizzle_con_st *con,
420
 
                                    drizzle_result_st *result, uint32_t level,
421
 
                                    drizzle_return_t *ret_ptr)
422
 
{
423
 
  (void) level;
424
 
  return drizzle_con_shutdown(con, result, ret_ptr);
425
 
}
426
 
 
427
 
drizzle_result_st *drizzle_con_ping(drizzle_con_st *con,
428
 
                                    drizzle_result_st *result,
429
 
                                    drizzle_return_t *ret_ptr)
430
 
{
431
 
  return drizzle_con_command_write(con, result, DRIZZLE_COMMAND_PING, NULL, 0,
432
 
                                   0, ret_ptr);
433
 
}
434
 
 
435
 
drizzle_result_st *drizzle_ping(drizzle_con_st *con,
436
 
                                drizzle_result_st *result,
437
 
                                drizzle_return_t *ret_ptr)
438
 
{
439
 
  return drizzle_con_ping(con, result, ret_ptr);
440
 
}
441
 
 
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,
446
 
                                             size_t total,
447
 
                                             drizzle_return_t *ret_ptr)
448
 
{
449
 
  if (!(con->options & DRIZZLE_CON_READY))
450
 
  {
451
 
    if (con->options & DRIZZLE_CON_RAW_PACKET)
452
 
    {
453
 
      drizzle_set_error(con->drizzle, "drizzle_command_write",
454
 
                        "connection not ready");
455
 
      *ret_ptr= DRIZZLE_RETURN_NOT_READY;
456
 
      return result;
457
 
    }
458
 
 
459
 
    *ret_ptr= drizzle_con_connect(con);
460
 
    if (*ret_ptr != DRIZZLE_RETURN_OK)
461
 
      return result;
462
 
  }
463
 
 
464
 
  if (drizzle_state_none(con))
465
 
  {
466
 
    if (con->options & (DRIZZLE_CON_RAW_PACKET | DRIZZLE_CON_NO_RESULT_READ))
467
 
      con->result= NULL;
468
 
    else
469
 
    {
470
 
      con->result= drizzle_result_create(con, result);
471
 
      if (con->result == NULL)
472
 
      {
473
 
        *ret_ptr= DRIZZLE_RETURN_MEMORY;
474
 
        return NULL;
475
 
      }
476
 
    }
477
 
 
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;
483
 
 
484
 
    drizzle_state_push(con, drizzle_state_command_write);
485
 
  }
486
 
  else if (con->command_data == NULL)
487
 
  {
488
 
    con->command_data= (uint8_t *)data;
489
 
    con->command_size= size;
490
 
  }
491
 
 
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)
498
 
  {
499
 
    drizzle_result_free(con->result);
500
 
    con->result= result;
501
 
  }
502
 
 
503
 
  return con->result;
504
 
}
505
 
 
506
 
/*
507
 
 * Server Definitions
508
 
 */
509
 
 
510
 
drizzle_return_t drizzle_con_listen(drizzle_con_st *con)
511
 
{
512
 
  if (con->options & DRIZZLE_CON_READY)
513
 
    return DRIZZLE_RETURN_OK;
514
 
 
515
 
  if (drizzle_state_none(con))
516
 
  {
517
 
    drizzle_state_push(con, drizzle_state_listen);
518
 
    drizzle_state_push(con, drizzle_state_addrinfo);
519
 
  }
520
 
 
521
 
  return drizzle_state_loop(con);
522
 
}
523
 
 
524
 
int drizzle_con_backlog(const drizzle_con_st *con)
525
 
{
526
 
  return con->backlog;
527
 
}
528
 
 
529
 
void drizzle_con_set_backlog(drizzle_con_st *con, int backlog)
530
 
{
531
 
  con->backlog= backlog;
532
 
}
533
 
 
534
 
void drizzle_con_set_protocol_version(drizzle_con_st *con,
535
 
                                      uint8_t protocol_version)
536
 
{
537
 
  con->protocol_version= protocol_version;
538
 
}
539
 
 
540
 
void drizzle_con_set_server_version(drizzle_con_st *con,
541
 
                                    const char *server_version)
542
 
{
543
 
  if (server_version == NULL)
544
 
    con->server_version[0]= 0;
545
 
  else
546
 
  {
547
 
    strncpy(con->server_version, server_version,
548
 
            DRIZZLE_MAX_SERVER_VERSION_SIZE);
549
 
    con->server_version[DRIZZLE_MAX_SERVER_VERSION_SIZE - 1]= 0;
550
 
  }
551
 
}
552
 
 
553
 
void drizzle_con_set_thread_id(drizzle_con_st *con, uint32_t thread_id)
554
 
{
555
 
  con->thread_id= thread_id;
556
 
}
557
 
 
558
 
void drizzle_con_set_scramble(drizzle_con_st *con, const uint8_t *scramble)
559
 
{
560
 
  if (scramble == NULL)
561
 
    con->scramble= NULL;
562
 
  else
563
 
  {
564
 
    con->scramble= con->scramble_buffer;
565
 
    memcpy(con->scramble, scramble, DRIZZLE_MAX_SCRAMBLE_SIZE);
566
 
  }
567
 
}
568
 
 
569
 
void drizzle_con_set_capabilities(drizzle_con_st *con,
570
 
                                  drizzle_capabilities_t capabilities)
571
 
{
572
 
  con->capabilities= capabilities;
573
 
}
574
 
 
575
 
void drizzle_con_set_charset(drizzle_con_st *con, drizzle_charset_t charset)
576
 
{
577
 
  con->charset= charset;
578
 
}
579
 
 
580
 
void drizzle_con_set_status(drizzle_con_st *con, drizzle_con_status_t status)
581
 
{
582
 
  con->status= status;
583
 
}
584
 
 
585
 
void drizzle_con_set_max_packet_size(drizzle_con_st *con,
586
 
                                     uint32_t max_packet_size)
587
 
{
588
 
  con->max_packet_size= max_packet_size;
589
 
}
590
 
 
591
 
void drizzle_con_copy_handshake(drizzle_con_st *con, drizzle_con_st *from)
592
 
{
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);
604
 
}
605
 
 
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)
610
 
{
611
 
  if (drizzle_state_none(con))
612
 
  {
613
 
    con->packet_number= 0;
614
 
    con->command_offset= 0;
615
 
    con->command_total= 0;
616
 
 
617
 
    drizzle_state_push(con, drizzle_state_command_read);
618
 
    drizzle_state_push(con, drizzle_state_packet_read);
619
 
  }
620
 
 
621
 
  *offset= con->command_offset;
622
 
 
623
 
  *ret_ptr= drizzle_state_loop(con);
624
 
  if (*ret_ptr == DRIZZLE_RETURN_PAUSE)
625
 
    *ret_ptr= DRIZZLE_RETURN_OK;
626
 
 
627
 
  *command= con->command;
628
 
  *size= con->command_size;
629
 
  *total= con->command_total;
630
 
 
631
 
  return con->command_data;
632
 
}
633
 
 
634
 
void *drizzle_con_command_buffer(drizzle_con_st *con,
635
 
                                 drizzle_command_t *command, size_t *total,
636
 
                                 drizzle_return_t *ret_ptr)
637
 
{
638
 
  uint8_t *command_data;
639
 
  size_t offset= 0;
640
 
  size_t size= 0;
641
 
 
642
 
  command_data= drizzle_con_command_read(con, command, &offset, &size, total,
643
 
                                         ret_ptr);
644
 
  if (*ret_ptr != DRIZZLE_RETURN_OK)
645
 
    return NULL;
646
 
 
647
 
  if (command_data == NULL)
648
 
  {
649
 
    *total= 0;
650
 
    return NULL;
651
 
  }
652
 
 
653
 
  if (con->command_buffer == NULL)
654
 
  {
655
 
    con->command_buffer= malloc((*total) + 1);
656
 
    if (con->command_buffer == NULL)
657
 
    {
658
 
      drizzle_set_error(con->drizzle, "drizzle_command_buffer", "malloc");
659
 
      *ret_ptr= DRIZZLE_RETURN_MEMORY;
660
 
      return NULL;
661
 
    }
662
 
  }
663
 
 
664
 
  memcpy(con->command_buffer + offset, command_data, size);
665
 
 
666
 
  while ((offset + size) != (*total))
667
 
  {
668
 
    command_data= drizzle_con_command_read(con, command, &offset, &size, total,
669
 
                                           ret_ptr);
670
 
    if (*ret_ptr != DRIZZLE_RETURN_OK)
671
 
      return NULL;
672
 
 
673
 
    memcpy(con->command_buffer + offset, command_data, size);
674
 
  }
675
 
 
676
 
  command_data= con->command_buffer;
677
 
  con->command_buffer= NULL;
678
 
  command_data[*total]= 0;
679
 
 
680
 
  return command_data;
681
 
}
682
 
 
683
 
/*
684
 
 * Local Definitions
685
 
 */
686
 
 
687
 
void drizzle_con_reset_addrinfo(drizzle_con_st *con)
688
 
{
689
 
  switch (con->socket_type)
690
 
  {
691
 
  case DRIZZLE_CON_SOCKET_TCP:
692
 
    if (con->socket.tcp.addrinfo != NULL)
693
 
    {
694
 
      freeaddrinfo(con->socket.tcp.addrinfo);
695
 
      con->socket.tcp.addrinfo= NULL;
696
 
    }
697
 
    break;
698
 
 
699
 
  case DRIZZLE_CON_SOCKET_UDS:
700
 
    con->socket.uds.addrinfo.ai_addr= NULL;
701
 
    break;
702
 
 
703
 
  default:
704
 
    break;
705
 
  }
706
 
 
707
 
  con->addrinfo_next= NULL;
708
 
}
709
 
 
710
 
/*
711
 
 * State Definitions
712
 
 */
713
 
 
714
 
drizzle_return_t drizzle_state_addrinfo(drizzle_con_st *con)
715
 
{
716
 
  drizzle_con_tcp_st *tcp;
717
 
  const char *host;
718
 
  char port[NI_MAXSERV];
719
 
  struct addrinfo ai;
720
 
  int ret;
721
 
 
722
 
  drizzle_log_debug(con->drizzle, "drizzle_state_addrinfo");
723
 
 
724
 
  switch (con->socket_type)
725
 
  {
726
 
  case DRIZZLE_CON_SOCKET_TCP:
727
 
    tcp= &(con->socket.tcp);
728
 
 
729
 
    if (tcp->addrinfo != NULL)
730
 
    {
731
 
      freeaddrinfo(tcp->addrinfo);
732
 
      tcp->addrinfo= NULL;
733
 
    }
734
 
 
735
 
    if (tcp->port != 0)
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);
739
 
    else
740
 
      snprintf(port, NI_MAXSERV, "%u", DRIZZLE_DEFAULT_TCP_PORT);
741
 
 
742
 
    memset(&ai, 0, sizeof(struct addrinfo));
743
 
    ai.ai_socktype= SOCK_STREAM;
744
 
    ai.ai_protocol= IPPROTO_TCP;
745
 
 
746
 
    if (con->options & DRIZZLE_CON_LISTEN)
747
 
    {
748
 
      ai.ai_flags = AI_PASSIVE;
749
 
      ai.ai_family = AF_UNSPEC;
750
 
      host= tcp->host;
751
 
    }
752
 
    else
753
 
    {
754
 
      if (tcp->host == NULL)
755
 
        host= DRIZZLE_DEFAULT_TCP_HOST;
756
 
      else
757
 
        host= tcp->host;
758
 
    }
759
 
 
760
 
    ret= getaddrinfo(host, port, &ai, &(tcp->addrinfo));
761
 
    if (ret != 0)
762
 
    {
763
 
      drizzle_set_error(con->drizzle, "drizzle_state_addrinfo",
764
 
                        "getaddrinfo:%s", gai_strerror(ret));
765
 
      return DRIZZLE_RETURN_GETADDRINFO;
766
 
    }
767
 
 
768
 
    con->addrinfo_next= tcp->addrinfo;
769
 
 
770
 
    break;
771
 
 
772
 
  case DRIZZLE_CON_SOCKET_UDS:
773
 
    con->addrinfo_next= &(con->socket.uds.addrinfo);
774
 
    break;
775
 
 
776
 
  default:
777
 
    break;
778
 
  }
779
 
 
780
 
  drizzle_state_pop(con);
781
 
  return DRIZZLE_RETURN_OK;
782
 
}
783
 
 
784
 
drizzle_return_t drizzle_state_connect(drizzle_con_st *con)
785
 
{
786
 
  int ret;
787
 
  drizzle_return_t dret;
788
 
 
789
 
  drizzle_log_debug(con->drizzle, "drizzle_state_connect");
790
 
 
791
 
  if (con->fd != -1)
792
 
  {
793
 
    (void)close(con->fd);
794
 
    con->fd= -1;
795
 
  }
796
 
 
797
 
  if (con->addrinfo_next == NULL)
798
 
  {
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;
803
 
  }
804
 
 
805
 
  con->fd= socket(con->addrinfo_next->ai_family,
806
 
                  con->addrinfo_next->ai_socktype,
807
 
                  con->addrinfo_next->ai_protocol);
808
 
  if (con->fd == -1)
809
 
  {
810
 
    drizzle_set_error(con->drizzle, "drizzle_state_connect", "socket:%d",
811
 
                      errno);
812
 
    con->drizzle->last_errno= errno;
813
 
    return DRIZZLE_RETURN_ERRNO;
814
 
  }
815
 
 
816
 
  dret= _con_setsockopt(con);
817
 
  if (dret != DRIZZLE_RETURN_OK)
818
 
  {
819
 
    con->drizzle->last_errno= errno;
820
 
    return dret;
821
 
  }
822
 
 
823
 
  while (1)
824
 
  {
825
 
    ret= connect(con->fd, con->addrinfo_next->ai_addr,
826
 
                 con->addrinfo_next->ai_addrlen);
827
 
 
828
 
#ifdef _WIN32
829
 
    /*Mapping windows specific error codes to Posix*/
830
 
    errno = WSAGetLastError();
831
 
    switch(errno) {
832
 
    case WSAEINVAL:
833
 
    case WSAEALREADY:
834
 
    case WSAEWOULDBLOCK:
835
 
      errno = EINPROGRESS;
836
 
      break;
837
 
    default:
838
 
      break;
839
 
    }
840
 
#endif /* _WIN32 */
841
 
        
842
 
    drizzle_log_crazy(con->drizzle, "connect return=%d errno=%d", ret, errno);
843
 
 
844
 
    if (ret == 0)
845
 
    {
846
 
      con->addrinfo_next= NULL;
847
 
      break;
848
 
    }
849
 
 
850
 
    if (errno == EAGAIN || errno == EINTR)
851
 
      continue;
852
 
 
853
 
    if (errno == EINPROGRESS)
854
 
    {
855
 
      drizzle_state_pop(con);
856
 
      drizzle_state_push(con, drizzle_state_connecting);
857
 
      return DRIZZLE_RETURN_OK;
858
 
    }
859
 
 
860
 
    if (errno == ECONNREFUSED || errno == ENETUNREACH || errno == ETIMEDOUT)
861
 
    {
862
 
      con->addrinfo_next= con->addrinfo_next->ai_next;
863
 
      return DRIZZLE_RETURN_OK;
864
 
    }
865
 
 
866
 
    drizzle_set_error(con->drizzle, "drizzle_state_connect", "connect:%d",
867
 
                      errno);
868
 
    con->drizzle->last_errno= errno;
869
 
    return DRIZZLE_RETURN_ERRNO;
870
 
  }
871
 
 
872
 
  drizzle_state_pop(con);
873
 
  return DRIZZLE_RETURN_OK;
874
 
}
875
 
 
876
 
drizzle_return_t drizzle_state_connecting(drizzle_con_st *con)
877
 
{
878
 
  drizzle_return_t ret;
879
 
 
880
 
  drizzle_log_debug(con->drizzle, "drizzle_state_connecting");
881
 
 
882
 
  while (1)
883
 
  {
884
 
    if (con->revents & POLLOUT)
885
 
    {
886
 
      drizzle_state_pop(con);
887
 
      return DRIZZLE_RETURN_OK;
888
 
    }
889
 
    else if (con->revents & (POLLERR | POLLHUP | POLLNVAL))
890
 
    {
891
 
      con->revents= 0;
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;
896
 
    }
897
 
 
898
 
    ret= drizzle_con_set_events(con, POLLOUT);
899
 
    if (ret != DRIZZLE_RETURN_OK)
900
 
      return ret;
901
 
 
902
 
    if (con->drizzle->options & DRIZZLE_NON_BLOCKING)
903
 
      return DRIZZLE_RETURN_IO_WAIT;
904
 
 
905
 
    ret= drizzle_con_wait(con->drizzle);
906
 
    if (ret != DRIZZLE_RETURN_OK)
907
 
      return ret;
908
 
  }
909
 
}
910
 
 
911
 
drizzle_return_t drizzle_state_read(drizzle_con_st *con)
912
 
{
913
 
  drizzle_return_t ret;
914
 
  ssize_t read_size;
915
 
 
916
 
  drizzle_log_debug(con->drizzle, "drizzle_state_read");
917
 
 
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))
921
 
  {
922
 
    memmove(con->buffer, con->buffer_ptr, con->buffer_size);
923
 
    con->buffer_ptr= con->buffer;
924
 
  }
925
 
 
926
 
  while (1)
927
 
  {
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); 
932
 
#ifdef _WIN32
933
 
    /*Get windows error codes and map it to Posix*/
934
 
    errno = WSAGetLastError();
935
 
    switch(errno) {
936
 
    case WSAEWOULDBLOCK:
937
 
    case 10057:
938
 
      errno = EAGAIN;
939
 
      break;
940
 
    default:
941
 
      break;
942
 
    }
943
 
#endif /* _WIN32 */     
944
 
    drizzle_log_crazy(con->drizzle, "read fd=%d return=%zd errno=%d", con->fd,
945
 
                      read_size, errno);
946
 
 
947
 
    if (read_size == 0)
948
 
    {
949
 
      drizzle_set_error(con->drizzle, "drizzle_state_read",
950
 
                        "lost connection to server (EOF)");
951
 
      return DRIZZLE_RETURN_LOST_CONNECTION;
952
 
    }
953
 
    else if (read_size == -1)
954
 
    {
955
 
      if (errno == EAGAIN)
956
 
      {
957
 
        ret= drizzle_con_set_events(con, POLLIN);
958
 
        if (ret != DRIZZLE_RETURN_OK)
959
 
          return 0;
960
 
 
961
 
        if (con->drizzle->options & DRIZZLE_NON_BLOCKING)
962
 
          return DRIZZLE_RETURN_IO_WAIT;
963
 
 
964
 
        ret= drizzle_con_wait(con->drizzle);
965
 
        if (ret != DRIZZLE_RETURN_OK)
966
 
          return ret;
967
 
 
968
 
        continue;
969
 
      }
970
 
      else if (errno == ECONNREFUSED)
971
 
      {
972
 
        con->revents= 0;
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;
977
 
      }
978
 
      else if (errno == EINTR)
979
 
        continue;
980
 
      else if (errno == EPIPE || errno == ECONNRESET)
981
 
      {
982
 
        drizzle_set_error(con->drizzle, "drizzle_state_read",
983
 
                          "lost connection to server (%d)", errno);
984
 
        return DRIZZLE_RETURN_LOST_CONNECTION;
985
 
      }
986
 
 
987
 
      drizzle_set_error(con->drizzle, "drizzle_state_read", "read:%d", errno);
988
 
      con->drizzle->last_errno= errno;
989
 
      return DRIZZLE_RETURN_ERRNO;
990
 
    }
991
 
 
992
 
    con->buffer_size+= (size_t)read_size;
993
 
    break;
994
 
  }
995
 
 
996
 
  drizzle_state_pop(con);;
997
 
  return DRIZZLE_RETURN_OK;
998
 
}
999
 
 
1000
 
drizzle_return_t drizzle_state_write(drizzle_con_st *con)
1001
 
{
1002
 
  drizzle_return_t ret;
1003
 
  ssize_t write_size;
1004
 
 
1005
 
  drizzle_log_debug(con->drizzle, "drizzle_state_write");
1006
 
 
1007
 
  while (con->buffer_size != 0)
1008
 
  {
1009
 
  
1010
 
    write_size = send(con->fd,(char *) con->buffer_ptr, con->buffer_size,0);
1011
 
 
1012
 
    drizzle_log_crazy(con->drizzle, "write fd=%d return=%zd errno=%d", con->fd,
1013
 
                      write_size, errno);
1014
 
 
1015
 
    if (write_size == 0)
1016
 
    {
1017
 
      drizzle_set_error(con->drizzle, "drizzle_state_write",
1018
 
                        "lost connection to server (EOF)");
1019
 
      return DRIZZLE_RETURN_LOST_CONNECTION;
1020
 
    }
1021
 
    else if (write_size == -1)
1022
 
    {
1023
 
      if (errno == EAGAIN)
1024
 
      {
1025
 
        ret= drizzle_con_set_events(con, POLLOUT);
1026
 
        if (ret != DRIZZLE_RETURN_OK)
1027
 
          return ret;
1028
 
 
1029
 
        if (con->drizzle->options & DRIZZLE_NON_BLOCKING)
1030
 
          return DRIZZLE_RETURN_IO_WAIT;
1031
 
 
1032
 
        ret= drizzle_con_wait(con->drizzle);
1033
 
        if (ret != DRIZZLE_RETURN_OK)
1034
 
          return ret;
1035
 
 
1036
 
        continue;
1037
 
      }
1038
 
      else if (errno == EINTR)
1039
 
        continue;
1040
 
      else if (errno == EPIPE || errno == ECONNRESET)
1041
 
      {
1042
 
        drizzle_set_error(con->drizzle, "drizzle_state_write",
1043
 
                          "lost connection to server (%d)", errno);
1044
 
        return DRIZZLE_RETURN_LOST_CONNECTION;
1045
 
      }
1046
 
 
1047
 
      drizzle_set_error(con->drizzle, "drizzle_state_write", "write:%d", errno);
1048
 
      con->drizzle->last_errno= errno;
1049
 
      return DRIZZLE_RETURN_ERRNO;
1050
 
    }
1051
 
 
1052
 
    con->buffer_ptr+= write_size;
1053
 
    con->buffer_size-= (size_t)write_size;
1054
 
    if (con->buffer_size == 0)
1055
 
      break;
1056
 
  }
1057
 
 
1058
 
  con->buffer_ptr= con->buffer;
1059
 
 
1060
 
  drizzle_state_pop(con);
1061
 
  return DRIZZLE_RETURN_OK;
1062
 
}
1063
 
 
1064
 
drizzle_return_t drizzle_state_listen(drizzle_con_st *con)
1065
 
{
1066
 
  char host[NI_MAXHOST];
1067
 
  char port[NI_MAXSERV];
1068
 
  int ret;
1069
 
  int fd;
1070
 
  int opt;
1071
 
  drizzle_con_st *new_con;
1072
 
 
1073
 
  for (; con->addrinfo_next != NULL;
1074
 
       con->addrinfo_next= con->addrinfo_next->ai_next)
1075
 
  {
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);
1079
 
    if (ret != 0)
1080
 
    {
1081
 
      drizzle_set_error(con->drizzle, "drizzle_state_listen", "getnameinfo:%s",
1082
 
                        gai_strerror(ret));
1083
 
      return DRIZZLE_RETURN_GETADDRINFO;
1084
 
    }
1085
 
 
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);
1089
 
    if (fd == -1)
1090
 
    {
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",
1093
 
                        errno);
1094
 
      continue;
1095
 
    }
1096
 
        
1097
 
        opt= 1;
1098
 
#ifdef _WIN32
1099
 
        ret= setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,(const char*) &opt, sizeof(opt));
1100
 
#else
1101
 
        ret= setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
1102
 
#endif /* _WIN32 */
1103
 
    if (ret == -1)
1104
 
    {
1105
 
      close(fd);
1106
 
      drizzle_set_error(con->drizzle, "drizzle_state_listen", "setsockopt:%d",
1107
 
                        errno);
1108
 
      return DRIZZLE_RETURN_ERRNO;
1109
 
    }
1110
 
 
1111
 
    ret= bind(fd, con->addrinfo_next->ai_addr, con->addrinfo_next->ai_addrlen);
1112
 
    if (ret == -1)
1113
 
    {
1114
 
      close(fd);
1115
 
      drizzle_set_error(con->drizzle, "drizzle_state_listen", "bind:%d", errno);
1116
 
      if (errno == EADDRINUSE)
1117
 
      {
1118
 
        if (con->fd == -1)
1119
 
        {
1120
 
          drizzle_log_info(con->drizzle, "could not listen on %s:%s", host,
1121
 
                           port);
1122
 
        }
1123
 
 
1124
 
        continue;
1125
 
      }
1126
 
 
1127
 
      return DRIZZLE_RETURN_ERRNO;
1128
 
    }
1129
 
 
1130
 
    if (listen(fd, con->backlog) == -1)
1131
 
    {
1132
 
      close(fd);
1133
 
      drizzle_set_error(con->drizzle, "drizzle_state_listen", "listen:%d",
1134
 
                        errno);
1135
 
      return DRIZZLE_RETURN_ERRNO;
1136
 
    }
1137
 
 
1138
 
    if (con->fd == -1)
1139
 
    {
1140
 
      con->fd= fd;
1141
 
      new_con= con;
1142
 
    }
1143
 
    else
1144
 
    {
1145
 
      new_con= drizzle_con_clone(con->drizzle, NULL, con);
1146
 
      if (new_con == NULL)
1147
 
      {
1148
 
        close(fd);
1149
 
        return DRIZZLE_RETURN_MEMORY;
1150
 
      }
1151
 
 
1152
 
      new_con->fd= fd;
1153
 
    }
1154
 
 
1155
 
    /* Wait for read events on the listening socket. */
1156
 
    ret= drizzle_con_set_events(new_con, POLLIN);
1157
 
    if (ret != DRIZZLE_RETURN_OK)
1158
 
    {
1159
 
      drizzle_con_free(new_con);
1160
 
      return ret;
1161
 
    }
1162
 
 
1163
 
    drizzle_log_info(con->drizzle, "listening on %s:%s", host, port);
1164
 
  }
1165
 
 
1166
 
  /* Report last socket() error if we couldn't find an address to bind. */
1167
 
  if (con->fd == -1)
1168
 
    return DRIZZLE_RETURN_ERRNO;
1169
 
 
1170
 
  drizzle_state_pop(con);
1171
 
  return DRIZZLE_RETURN_OK;
1172
 
}
1173
 
 
1174
 
/*
1175
 
 * Static Definitions
1176
 
 */
1177
 
 
1178
 
static drizzle_return_t _con_setsockopt(drizzle_con_st *con)
1179
 
{
1180
 
  int ret;
1181
 
  struct linger linger;
1182
 
  struct timeval waittime;
1183
 
 
1184
 
  ret= 1;
1185
 
 
1186
 
#ifdef _WIN32
1187
 
  ret= setsockopt(con->fd, IPPROTO_TCP, TCP_NODELAY, (const char*)&ret,
1188
 
                  (socklen_t)sizeof(int));
1189
 
#else
1190
 
  ret= setsockopt(con->fd, IPPROTO_TCP, TCP_NODELAY, &ret,
1191
 
                  (socklen_t)sizeof(int));
1192
 
#endif /* _WIN32 */
1193
 
 
1194
 
  if (ret == -1 && errno != EOPNOTSUPP)
1195
 
  {
1196
 
    drizzle_set_error(con->drizzle, "_con_setsockopt",
1197
 
                      "setsockopt:TCP_NODELAY:%d", errno);
1198
 
    return DRIZZLE_RETURN_ERRNO;
1199
 
  }
1200
 
 
1201
 
  linger.l_onoff= 1;
1202
 
  linger.l_linger= DRIZZLE_DEFAULT_SOCKET_TIMEOUT;
1203
 
 
1204
 
#ifdef _WIN32
1205
 
  ret= setsockopt(con->fd, SOL_SOCKET, SO_LINGER, (const char*)&linger,
1206
 
                  (socklen_t)sizeof(struct linger));
1207
 
#else
1208
 
  ret= setsockopt(con->fd, SOL_SOCKET, SO_LINGER, &linger,
1209
 
                  (socklen_t)sizeof(struct linger));
1210
 
#endif /* _WIN32 */
1211
 
 
1212
 
  if (ret == -1)
1213
 
  {
1214
 
    drizzle_set_error(con->drizzle, "_con_setsockopt",
1215
 
                      "setsockopt:SO_LINGER:%d", errno);
1216
 
    return DRIZZLE_RETURN_ERRNO;
1217
 
  }
1218
 
 
1219
 
  waittime.tv_sec= DRIZZLE_DEFAULT_SOCKET_TIMEOUT;
1220
 
  waittime.tv_usec= 0;
1221
 
 
1222
 
#ifdef _WIN32
1223
 
  ret= setsockopt(con->fd, SOL_SOCKET, SO_SNDTIMEO, (const char*)&waittime,
1224
 
                  (socklen_t)sizeof(struct timeval));
1225
 
#else
1226
 
  ret= setsockopt(con->fd, SOL_SOCKET, SO_SNDTIMEO, &waittime,
1227
 
                  (socklen_t)sizeof(struct timeval));
1228
 
#endif /* _WIN32 */
1229
 
 
1230
 
  if (ret == -1 && errno != ENOPROTOOPT)
1231
 
  {
1232
 
    drizzle_set_error(con->drizzle, "_con_setsockopt",
1233
 
                      "setsockopt:SO_SNDTIMEO:%d", errno);
1234
 
    return DRIZZLE_RETURN_ERRNO;
1235
 
  }
1236
 
 
1237
 
#ifdef _WIN32
1238
 
  ret= setsockopt(con->fd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&waittime,
1239
 
                  (socklen_t)sizeof(struct timeval));
1240
 
#else
1241
 
  ret= setsockopt(con->fd, SOL_SOCKET, SO_RCVTIMEO, &waittime,
1242
 
                  (socklen_t)sizeof(struct timeval));
1243
 
#endif /* _WIN32 */
1244
 
 
1245
 
  if (ret == -1 && errno != ENOPROTOOPT)
1246
 
  {
1247
 
    drizzle_set_error(con->drizzle, "_con_setsockopt",
1248
 
                      "setsockopt:SO_RCVTIMEO:%d", errno);
1249
 
    return DRIZZLE_RETURN_ERRNO;
1250
 
  }
1251
 
 
1252
 
  ret= DRIZZLE_DEFAULT_SOCKET_SEND_SIZE;
1253
 
#ifdef _WIN32
1254
 
  ret= setsockopt(con->fd, SOL_SOCKET, SO_SNDBUF, (const char*)&ret, (socklen_t)sizeof(int));
1255
 
#else
1256
 
  ret= setsockopt(con->fd, SOL_SOCKET, SO_SNDBUF, &ret, (socklen_t)sizeof(int));
1257
 
#endif /* _WIN32 */
1258
 
  if (ret == -1)
1259
 
  {
1260
 
    drizzle_set_error(con->drizzle, "_con_setsockopt",
1261
 
                      "setsockopt:SO_SNDBUF:%d", errno);
1262
 
    return DRIZZLE_RETURN_ERRNO;
1263
 
  }
1264
 
 
1265
 
  ret= DRIZZLE_DEFAULT_SOCKET_RECV_SIZE;
1266
 
#ifdef _WIN32
1267
 
  ret= setsockopt(con->fd, SOL_SOCKET, SO_RCVBUF, (const char*)&ret, (socklen_t)sizeof(int));
1268
 
#else
1269
 
  ret= setsockopt(con->fd, SOL_SOCKET, SO_RCVBUF, &ret, (socklen_t)sizeof(int));
1270
 
#endif /* _WIN32 */
1271
 
  if (ret == -1)
1272
 
  {
1273
 
    drizzle_set_error(con->drizzle, "_con_setsockopt",
1274
 
                      "setsockopt:SO_RCVBUF:%d", errno);
1275
 
    return DRIZZLE_RETURN_ERRNO;
1276
 
  }
1277
 
 
1278
 
#if defined (_WIN32)
1279
 
  unsigned long asyncmode = 1;
1280
 
  ioctlsocket(con->fd, FIONBIO, &asyncmode);
1281
 
#else
1282
 
  ret= fcntl(con->fd, F_GETFL, 0);
1283
 
  if (ret == -1)
1284
 
  {
1285
 
    drizzle_set_error(con->drizzle, "_con_setsockopt", "fcntl:F_GETFL:%d",
1286
 
                      errno);
1287
 
    return DRIZZLE_RETURN_ERRNO;
1288
 
  }
1289
 
 
1290
 
  ret= fcntl(con->fd, F_SETFL, ret | O_NONBLOCK);
1291
 
  if (ret == -1)
1292
 
  {
1293
 
    drizzle_set_error(con->drizzle, "_con_setsockopt", "fcntl:F_SETFL:%d",
1294
 
                      errno);
1295
 
    return DRIZZLE_RETURN_ERRNO;
1296
 
  }
1297
 
#endif
1298
 
 
1299
 
  return DRIZZLE_RETURN_OK;
1300
 
}