~drizzle-trunk/drizzle/development

2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
1
/*
2
 * Drizzle Client & Protocol Library
3
 *
4
 * Copyright (C) 2008 Eric Day (eday@oddments.org)
5
 * All rights reserved.
6
 *
7
 * Redistribution and use in source and binary forms, with or without
8
 * modification, are permitted provided that the following conditions are
9
 * met:
10
 *
11
 *     * Redistributions of source code must retain the above copyright
12
 * notice, this list of conditions and the following disclaimer.
13
 *
14
 *     * Redistributions in binary form must reproduce the above
15
 * copyright notice, this list of conditions and the following disclaimer
16
 * in the documentation and/or other materials provided with the
17
 * distribution.
18
 *
19
 *     * The names of its contributors may not be used to endorse or
20
 * promote products derived from this software without specific prior
21
 * written permission.
22
 *
23
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
 *
35
 */
36
37
/**
38
 * @file
39
 * @brief Drizzle Definitions
40
 */
41
42
#include "libdrizzle/common.h"
43
44
/**
45
 * @addtogroup drizzle_static Static Drizzle Declarations
46
 * @ingroup drizzle
47
 * @{
48
 */
49
50
/**
51
 * Names of the verbose levels provided.
52
 */
53
static const char *_verbose_name[DRIZZLE_VERBOSE_MAX]=
54
{
55
  "NEVER",
56
  "FATAL",
57
  "ERROR",
58
  "INFO",
59
  "DEBUG",
60
  "CRAZY"
61
};
62
63
/** @} */
64
65
/*
66
 * Common Definitions
67
 */
68
2318.5.28 by Olaf van der Spek
Refactor
69
const char *drizzle_version()
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
70
{
71
  return PACKAGE_VERSION;
72
}
73
2318.5.28 by Olaf van der Spek
Refactor
74
const char *drizzle_bugreport()
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
75
{
76
  return PACKAGE_BUGREPORT;
77
}
78
79
const char *drizzle_verbose_name(drizzle_verbose_t verbose)
80
{
81
  if (verbose >= DRIZZLE_VERBOSE_MAX)
82
    return "UNKNOWN";
83
84
  return _verbose_name[verbose];
85
}
86
87
drizzle_st *drizzle_create(drizzle_st *drizzle)
88
{
89
#if defined(_WIN32)
90
  /* if it is MS windows, invoke WSAStartup */
91
  WSADATA wsaData;
92
  if ( WSAStartup( MAKEWORD(2,2), &wsaData ) != 0 )
93
    printf("Error at WSAStartup()\n");
94
#else
95
  struct sigaction act;
96
  memset(&act, 0, sizeof(act));
97
98
  act.sa_handler = SIG_IGN;
99
  sigaction(SIGPIPE, &act, NULL);
100
#endif
101
102
  if (drizzle == NULL)
103
  {
104
    drizzle= new drizzle_st;
105
    drizzle->options= DRIZZLE_ALLOCATED;
106
  }
107
  else
108
    drizzle->options= DRIZZLE_NONE;
109
110
  /* @todo remove this default free flag with new API. */
111
  drizzle->options|= DRIZZLE_FREE_OBJECTS;
112
  drizzle->error_code= 0;
113
  /* drizzle->options set above */
114
  drizzle->verbose= DRIZZLE_VERBOSE_NEVER;
115
  drizzle->con_count= 0;
116
  drizzle->pfds_size= 0;
117
  drizzle->query_count= 0;
118
  drizzle->query_new= 0;
119
  drizzle->query_running= 0;
120
  drizzle->last_errno= 0;
121
  drizzle->timeout= -1;
122
  drizzle->con_list= NULL;
123
  drizzle->context= NULL;
124
  drizzle->context_free_fn= NULL;
125
  drizzle->event_watch_fn= NULL;
126
  drizzle->event_watch_context= NULL;
127
  drizzle->log_fn= NULL;
128
  drizzle->log_context= NULL;
129
  drizzle->pfds= NULL;
130
  drizzle->query_list= NULL;
131
  drizzle->sqlstate[0]= 0;
132
  drizzle->last_error[0]= 0;
133
134
  return drizzle;
135
}
136
137
drizzle_st *drizzle_clone(drizzle_st *drizzle, const drizzle_st *from)
138
{
139
  drizzle= drizzle_create(drizzle);
140
  if (drizzle == NULL)
141
    return NULL;
142
143
  drizzle->options|= (from->options & ~DRIZZLE_ALLOCATED);
144
2318.5.28 by Olaf van der Spek
Refactor
145
  for (drizzle_con_st* con= from->con_list; con != NULL; con= con->next)
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
146
  {
147
    if (drizzle_con_clone(drizzle, NULL, con) == NULL)
148
    {
149
      drizzle_free(drizzle);
150
      return NULL;
151
    }
152
  }
153
154
  return drizzle;
155
}
156
157
void drizzle_free(drizzle_st *drizzle)
158
{
159
  if (drizzle->context != NULL && drizzle->context_free_fn != NULL)
160
    drizzle->context_free_fn(drizzle, drizzle->context);
161
162
  if (drizzle->options & DRIZZLE_FREE_OBJECTS)
163
  {
164
    drizzle_con_free_all(drizzle);
165
    drizzle_query_free_all(drizzle);
166
  }
167
  else if (drizzle->options & DRIZZLE_ASSERT_DANGLING)
168
  {
169
    assert(drizzle->con_list == NULL);
2318.5.28 by Olaf van der Spek
Refactor
170
    assert(drizzle->query_list == NULL);
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
171
  }
172
2353.3.1 by Mark Atwood
fix cppcheck redundantIfDelete0 warnings. It is safe to deallocate a NULL pointer
173
  free(drizzle->pfds);
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
174
175
  if (drizzle->options & DRIZZLE_ALLOCATED)
176
    delete drizzle;
177
#if defined(_WIN32)
178
  /* if it is MS windows, invoke WSACleanup() at the end*/
179
  WSACleanup();
180
#endif
181
}
182
183
const char *drizzle_error(const drizzle_st *drizzle)
184
{
2318.5.28 by Olaf van der Spek
Refactor
185
  return drizzle->last_error;
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
186
}
187
188
int drizzle_errno(const drizzle_st *drizzle)
189
{
190
  return drizzle->last_errno;
191
}
192
193
uint16_t drizzle_error_code(const drizzle_st *drizzle)
194
{
195
  return drizzle->error_code;
196
}
197
198
const char *drizzle_sqlstate(const drizzle_st *drizzle)
199
{
200
  return drizzle->sqlstate;
201
}
202
203
int drizzle_options(const drizzle_st *drizzle)
204
{
205
  return drizzle->options;
206
}
207
208
void drizzle_set_options(drizzle_st *drizzle, int options)
209
{
210
  drizzle->options= options;
211
}
212
213
void drizzle_add_options(drizzle_st *drizzle, int options)
214
{
215
  drizzle->options|= options;
216
}
217
218
void drizzle_remove_options(drizzle_st *drizzle, drizzle_options_t options)
219
{
220
  drizzle->options&= ~options;
221
}
222
223
void *drizzle_context(const drizzle_st *drizzle)
224
{
225
  return drizzle->context;
226
}
227
228
void drizzle_set_context(drizzle_st *drizzle, void *context)
229
{
230
  drizzle->context= context;
231
}
232
233
void drizzle_set_context_free_fn(drizzle_st *drizzle,
234
                                 drizzle_context_free_fn *function)
235
{
236
  drizzle->context_free_fn= function;
237
}
238
239
int drizzle_timeout(const drizzle_st *drizzle)
240
{
241
  return drizzle->timeout;
242
}
243
244
void drizzle_set_timeout(drizzle_st *drizzle, int timeout)
245
{
246
  drizzle->timeout= timeout;
247
}
248
249
drizzle_verbose_t drizzle_verbose(const drizzle_st *drizzle)
250
{
251
  return drizzle->verbose;
252
}
253
254
void drizzle_set_verbose(drizzle_st *drizzle, drizzle_verbose_t verbose)
255
{
256
  drizzle->verbose= verbose;
257
}
258
259
void drizzle_set_log_fn(drizzle_st *drizzle, drizzle_log_fn *function,
260
                        void *context)
261
{
262
  drizzle->log_fn= function;
263
  drizzle->log_context= context;
264
}
265
266
void drizzle_set_event_watch_fn(drizzle_st *drizzle,
267
                                drizzle_event_watch_fn *function,
268
                                void *context)
269
{
270
  drizzle->event_watch_fn= function;
271
  drizzle->event_watch_context= context;
272
}
273
274
drizzle_con_st *drizzle_con_create(drizzle_st *drizzle, drizzle_con_st *con)
275
{
276
  if (con == NULL)
277
  {
278
    con= new drizzle_con_st;
279
    con->options= DRIZZLE_CON_ALLOCATED;
280
  }
281
  else
282
    con->options= 0;
283
284
  if (drizzle->con_list != NULL)
285
    drizzle->con_list->prev= con;
286
  con->next= drizzle->con_list;
287
  con->prev= NULL;
288
  drizzle->con_list= con;
289
  drizzle->con_count++;
290
291
  con->packet_number= 0;
292
  con->protocol_version= 0;
293
  con->state_current= 0;
294
  con->events= 0;
295
  con->revents= 0;
296
  con->capabilities= DRIZZLE_CAPABILITIES_NONE;
297
  con->charset= 0;
298
  con->command= DRIZZLE_COMMAND_SLEEP;
299
  con->options|= DRIZZLE_CON_MYSQL;
300
  con->socket_type= DRIZZLE_CON_SOCKET_TCP;
301
  con->status= DRIZZLE_CON_STATUS_NONE;
302
  con->max_packet_size= DRIZZLE_MAX_PACKET_SIZE;
303
  con->result_count= 0;
304
  con->thread_id= 0;
305
  con->backlog= DRIZZLE_DEFAULT_BACKLOG;
306
  con->fd= -1;
307
  con->buffer_size= 0;
308
  con->command_offset= 0;
309
  con->command_size= 0;
310
  con->command_total= 0;
311
  con->packet_size= 0;
312
  con->addrinfo_next= NULL;
313
  con->buffer_ptr= con->buffer;
314
  con->command_buffer= NULL;
315
  con->command_data= NULL;
316
  con->context= NULL;
317
  con->context_free_fn= NULL;
318
  con->drizzle= drizzle;
319
  /* con->next set above */
320
  /* con->prev set above */
321
  con->query= NULL;
322
  /* con->result doesn't need to be set */
323
  con->result_list= NULL;
324
  con->scramble= NULL;
325
  con->socket.tcp.addrinfo= NULL;
326
  con->socket.tcp.host= NULL;
327
  con->socket.tcp.port= 0;
328
  /* con->buffer doesn't need to be set */
329
  con->db[0]= 0;
330
  con->password[0]= 0;
331
  /* con->scramble_buffer doesn't need to be set */
332
  con->server_version[0]= 0;
333
  /* con->state_stack doesn't need to be set */
334
  con->user[0]= 0;
335
336
  return con;
337
}
338
339
drizzle_con_st *drizzle_con_clone(drizzle_st *drizzle, drizzle_con_st *con,
340
                                  const drizzle_con_st *from)
341
{
342
  con= drizzle_con_create(drizzle, con);
343
  if (con == NULL)
344
    return NULL;
345
346
  /* Clear "operational" options such as IO status. */
347
  con->options|= (from->options & ~(DRIZZLE_CON_ALLOCATED|DRIZZLE_CON_READY|
348
                  DRIZZLE_CON_NO_RESULT_READ|DRIZZLE_CON_IO_READY|
349
                  DRIZZLE_CON_LISTEN));
350
  con->backlog= from->backlog;
351
  strcpy(con->db, from->db);
352
  strcpy(con->password, from->password);
353
  strcpy(con->user, from->user);
354
355
  switch (from->socket_type)
356
  {
357
  case DRIZZLE_CON_SOCKET_TCP:
358
    drizzle_con_set_tcp(con, from->socket.tcp.host, from->socket.tcp.port);
359
    break;
360
361
  case DRIZZLE_CON_SOCKET_UDS:
362
    drizzle_con_set_uds(con, from->socket.uds.sockaddr.sun_path);
363
    break;
364
  }
365
366
  return con;
367
}
368
369
void drizzle_con_free(drizzle_con_st *con)
370
{
371
  if (con->context != NULL && con->context_free_fn != NULL)
372
    con->context_free_fn(con, con->context);
373
374
  if (con->drizzle->options & DRIZZLE_FREE_OBJECTS)
375
    drizzle_result_free_all(con);
376
  else if (con->drizzle->options & DRIZZLE_ASSERT_DANGLING)
377
    assert(con->result_list == NULL);
378
379
  if (con->fd != -1)
380
    drizzle_con_close(con);
381
382
  drizzle_con_reset_addrinfo(con);
383
384
  if (con->drizzle->con_list == con)
385
    con->drizzle->con_list= con->next;
386
  if (con->prev != NULL)
387
    con->prev->next= con->next;
388
  if (con->next != NULL)
389
    con->next->prev= con->prev;
390
  con->drizzle->con_count--;
391
392
  if (con->options & DRIZZLE_CON_ALLOCATED)
393
    delete con;
394
}
395
396
void drizzle_con_free_all(drizzle_st *drizzle)
397
{
398
  while (drizzle->con_list != NULL)
399
    drizzle_con_free(drizzle->con_list);
400
}
401
402
drizzle_return_t drizzle_con_wait(drizzle_st *drizzle)
403
{
404
  struct pollfd *pfds;
405
  int ret;
406
  drizzle_return_t dret;
407
408
  if (drizzle->pfds_size < drizzle->con_count)
409
  {
410
    pfds= (struct pollfd *)realloc(drizzle->pfds, drizzle->con_count * sizeof(struct pollfd));
411
    if (pfds == NULL)
412
    {
413
      drizzle_set_error(drizzle, "drizzle_con_wait", "realloc");
414
      return DRIZZLE_RETURN_MEMORY;
415
    }
416
417
    drizzle->pfds= pfds;
418
    drizzle->pfds_size= drizzle->con_count;
419
  }
420
  else
421
    pfds= drizzle->pfds;
422
2318.5.28 by Olaf van der Spek
Refactor
423
  uint32_t x= 0;
424
  for (drizzle_con_st* con= drizzle->con_list; con != NULL; con= con->next)
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
425
  {
426
    if (con->events == 0)
427
      continue;
428
429
    pfds[x].fd= con->fd;
430
    pfds[x].events= con->events;
431
    pfds[x].revents= 0;
432
    x++;
433
  }
434
435
  if (x == 0)
436
  {
437
    drizzle_set_error(drizzle, "drizzle_con_wait",
438
                      "no active file descriptors");
439
    return DRIZZLE_RETURN_NO_ACTIVE_CONNECTIONS;
440
  }
441
442
  while (1)
443
  {
444
    drizzle_log_crazy(drizzle, "poll count=%d timeout=%d", x,
445
                      drizzle->timeout);
446
447
    ret= poll(pfds, x, drizzle->timeout);
448
449
    drizzle_log_crazy(drizzle, "poll return=%d errno=%d", ret, errno);
450
451
    if (ret == -1)
452
    {
453
      if (errno == EINTR)
454
        continue;
455
456
      drizzle_set_error(drizzle, "drizzle_con_wait", "poll:%d", errno);
457
      drizzle->last_errno= errno;
458
      return DRIZZLE_RETURN_ERRNO;
459
    }
460
461
    break;
462
  }
463
464
  if (ret == 0)
465
  {
466
    drizzle_set_error(drizzle, "drizzle_con_wait", "timeout reached");
467
    return DRIZZLE_RETURN_TIMEOUT;
468
  }
469
470
  x= 0;
2318.5.28 by Olaf van der Spek
Refactor
471
  for (drizzle_con_st* con= drizzle->con_list; con != NULL; con= con->next)
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
472
  {
473
    if (con->events == 0)
474
      continue;
475
476
    dret= drizzle_con_set_revents(con, pfds[x].revents);
477
    if (dret != DRIZZLE_RETURN_OK)
478
      return dret;
479
480
    x++;
481
  }
482
483
  return DRIZZLE_RETURN_OK;
484
}
485
486
drizzle_con_st *drizzle_con_ready(drizzle_st *drizzle)
487
{
488
  /* We can't keep state between calls since connections may be removed during
489
     processing. If this list ever gets big, we may want something faster. */
490
2318.5.28 by Olaf van der Spek
Refactor
491
  for (drizzle_con_st* con= drizzle->con_list; con != NULL; con= con->next)
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
492
  {
493
    if (con->options & DRIZZLE_CON_IO_READY)
494
    {
495
      con->options&= ~DRIZZLE_CON_IO_READY;
496
      return con;
497
    }
498
  }
499
  return NULL;
500
}
501
502
drizzle_con_st *drizzle_con_ready_listen(drizzle_st *drizzle)
503
{
504
  /* We can't keep state between calls since connections may be removed during
505
     processing. If this list ever gets big, we may want something faster. */
506
2318.5.28 by Olaf van der Spek
Refactor
507
  for (drizzle_con_st* con= drizzle->con_list; con != NULL; con= con->next)
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
508
  {
509
    if ((con->options & (DRIZZLE_CON_IO_READY | DRIZZLE_CON_LISTEN)) ==
510
        (DRIZZLE_CON_IO_READY | DRIZZLE_CON_LISTEN))
511
    {
512
      con->options&= ~DRIZZLE_CON_IO_READY;
513
      return con;
514
    }
515
  }
516
  return NULL;
517
}
518
519
/*
520
 * Client Definitions
521
 */
522
523
drizzle_con_st *drizzle_con_add_tcp(drizzle_st *drizzle, drizzle_con_st *con,
524
                                    const char *host, in_port_t port,
525
                                    const char *user, const char *password,
526
                                    const char *db,
527
                                    drizzle_con_options_t options)
528
{
529
  con= drizzle_con_create(drizzle, con);
530
  if (con == NULL)
531
    return NULL;
532
533
  drizzle_con_set_tcp(con, host, port);
534
  drizzle_con_set_auth(con, user, password);
535
  drizzle_con_set_db(con, db);
536
  drizzle_con_add_options(con, options);
537
538
  return con;
539
}
540
541
drizzle_con_st *drizzle_con_add_uds(drizzle_st *drizzle, drizzle_con_st *con,
542
                                    const char *uds, const char *user,
543
                                    const char *password, const char *db,
544
                                    drizzle_con_options_t options)
545
{
546
  con= drizzle_con_create(drizzle, con);
547
  if (con == NULL)
548
    return NULL;
549
550
  drizzle_con_set_uds(con, uds);
551
  drizzle_con_set_auth(con, user, password);
552
  drizzle_con_set_db(con, db);
553
  drizzle_con_add_options(con, options);
554
555
  return con;
556
}
557
558
/*
559
 * Server Definitions
560
 */
561
562
drizzle_con_st *drizzle_con_add_tcp_listen(drizzle_st *drizzle,
563
                                           drizzle_con_st *con,
564
                                           const char *host, in_port_t port,
565
                                           int backlog,
566
                                           drizzle_con_options_t options)
567
{
568
  con= drizzle_con_create(drizzle, con);
569
  if (con == NULL)
570
    return NULL;
571
572
  drizzle_con_set_tcp(con, host, port);
573
  drizzle_con_set_backlog(con, backlog);
574
  drizzle_con_add_options(con, options | DRIZZLE_CON_LISTEN);
575
576
  return con;
577
}
578
579
drizzle_con_st *drizzle_con_add_uds_listen(drizzle_st *drizzle,
580
                                           drizzle_con_st *con,
581
                                           const char *uds, int backlog,
582
                                           drizzle_con_options_t options)
583
{
584
  con= drizzle_con_create(drizzle, con);
585
  if (con == NULL)
586
    return NULL;
587
588
  drizzle_con_set_uds(con, uds);
589
  drizzle_con_set_backlog(con, backlog);
590
  drizzle_con_add_options(con, options | DRIZZLE_CON_LISTEN);
591
592
  return con;
593
}
594
595
drizzle_con_st *drizzle_con_accept(drizzle_st *drizzle, drizzle_con_st *con,
596
                                   drizzle_return_t *ret_ptr)
597
{
598
  while (1)
599
  {
2318.5.28 by Olaf van der Spek
Refactor
600
    if (drizzle_con_st* ready= drizzle_con_ready_listen(drizzle))
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
601
    {
2318.5.28 by Olaf van der Spek
Refactor
602
      int fd= accept(ready->fd, NULL, NULL);
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
603
604
      con= drizzle_con_create(drizzle, con);
605
      if (con == NULL)
606
      {
2269.2.1 by Marc Isambart
Various libdrizzle Windows fixes, including closesocket() instead of close(), snprintf handling and WSAECONNREFUSED mapping
607
        (void)closesocket(fd);
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
608
        *ret_ptr= DRIZZLE_RETURN_MEMORY;
609
        return NULL;
610
      }
611
612
      *ret_ptr= drizzle_con_set_fd(con, fd);
613
      if (*ret_ptr != DRIZZLE_RETURN_OK)
614
      {
2269.2.1 by Marc Isambart
Various libdrizzle Windows fixes, including closesocket() instead of close(), snprintf handling and WSAECONNREFUSED mapping
615
        (void)closesocket(fd);
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
616
        return NULL;
617
      }
618
619
      if (ready->options & DRIZZLE_CON_MYSQL)
620
        drizzle_con_add_options(con, DRIZZLE_CON_MYSQL);
621
622
      *ret_ptr= DRIZZLE_RETURN_OK;
623
      return con;
624
    }
625
626
    if (drizzle->options & DRIZZLE_NON_BLOCKING)
627
    {
628
      *ret_ptr= DRIZZLE_RETURN_IO_WAIT;
629
      return NULL;
630
    }
631
2318.5.28 by Olaf van der Spek
Refactor
632
    for (drizzle_con_st* ready= drizzle->con_list; ready != NULL; ready= ready->next)
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
633
    {
634
      if (ready->options & DRIZZLE_CON_LISTEN)
635
        drizzle_con_set_events(ready, POLLIN);
636
    }
637
638
    *ret_ptr= drizzle_con_wait(drizzle);
639
    if (*ret_ptr != DRIZZLE_RETURN_OK)
640
      return NULL;
641
  }
642
}
643
644
/*
645
 * Local Definitions
646
 */
647
648
void drizzle_set_error(drizzle_st *drizzle, const char *function,
649
                       const char *format, ...)
650
{
651
  char log_buffer[DRIZZLE_MAX_ERROR_SIZE];
652
2318.5.28 by Olaf van der Spek
Refactor
653
  size_t size= strlen(function);
654
  char* ptr= (char *)memcpy(log_buffer, function, size);
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
655
  ptr+= size;
656
  ptr[0]= ':';
657
  size++;
658
  ptr++;
659
2318.5.28 by Olaf van der Spek
Refactor
660
  va_list args;
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
661
  va_start(args, format);
2318.5.28 by Olaf van der Spek
Refactor
662
  int written= vsnprintf(ptr, DRIZZLE_MAX_ERROR_SIZE - size, format, args);
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
663
  va_end(args);
664
2269.2.1 by Marc Isambart
Various libdrizzle Windows fixes, including closesocket() instead of close(), snprintf handling and WSAECONNREFUSED mapping
665
  if (written < 0) size= DRIZZLE_MAX_ERROR_SIZE;
666
  else size+= written;
667
  if (size >= DRIZZLE_MAX_ERROR_SIZE)
668
    size= DRIZZLE_MAX_ERROR_SIZE - 1;
669
  log_buffer[size]= 0;
670
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
671
  if (drizzle->log_fn == NULL)
672
    memcpy(drizzle->last_error, log_buffer, size + 1);
673
  else
674
    drizzle->log_fn(log_buffer, DRIZZLE_VERBOSE_ERROR, drizzle->log_context);
675
}
676
677
void drizzle_log(drizzle_st *drizzle, drizzle_verbose_t verbose,
678
                 const char *format, va_list args)
679
{
680
  char log_buffer[DRIZZLE_MAX_ERROR_SIZE];
681
682
  if (drizzle->log_fn == NULL)
683
  {
684
    printf("%5s: ", drizzle_verbose_name(verbose));
685
    vprintf(format, args);
686
    printf("\n");
687
  }
688
  else
689
  {
690
    vsnprintf(log_buffer, DRIZZLE_MAX_ERROR_SIZE, format, args);
2269.2.1 by Marc Isambart
Various libdrizzle Windows fixes, including closesocket() instead of close(), snprintf handling and WSAECONNREFUSED mapping
691
    log_buffer[DRIZZLE_MAX_ERROR_SIZE-1]= 0;
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
692
    drizzle->log_fn(log_buffer, verbose, drizzle->log_context);
693
  }
694
}