~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to libdrizzle/drizzle.c

  • Committer: Monty Taylor
  • Date: 2008-08-05 19:01:20 UTC
  • mto: (266.1.1 codestyle)
  • mto: This revision was merged to the branch mainline in revision 266.
  • Revision ID: monty@inaugust.com-20080805190120-tsuziqz2mfqcw7pe
Removed libmysyslt.la, made mysys a noinst_ and made everything use it. It's
not a standalone lib, there's no reason to pretend otherwise.

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