~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to libdrizzle/drizzle.c

  • Committer: Andrew Hutchings
  • Date: 2010-11-01 22:14:18 UTC
  • mto: This revision was merged to the branch mainline in revision 1907.
  • Revision ID: andrew@linuxjedi.co.uk-20101101221418-9n9gmm4ms7fl8vo5
Fix copyright

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