~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to libdrizzle/client.c

  • Committer: Brian Aker
  • Date: 2008-07-10 18:40:16 UTC
  • mfrom: (77.1.63 codestyle)
  • Revision ID: brian@tangent.org-20080710184016-9dbmgqzl1diwrj82
Merge.

Show diffs side-by-side

added added

removed removed

Lines of Context:
44
44
#undef max_allowed_packet
45
45
#undef net_buffer_length
46
46
 
47
 
#ifdef EMBEDDED_LIBRARY
48
 
 
49
 
#undef MYSQL_SERVER
50
 
 
51
 
#ifndef MYSQL_CLIENT
52
 
#define MYSQL_CLIENT
53
 
#endif
54
 
 
55
 
#define CLI_MYSQL_REAL_CONNECT STDCALL cli_mysql_real_connect
56
 
 
57
 
#undef net_flush
58
 
my_bool net_flush(NET *net);
59
 
 
60
 
#else  /*EMBEDDED_LIBRARY*/
61
47
#define CLI_MYSQL_REAL_CONNECT STDCALL mysql_real_connect
62
 
#endif /*EMBEDDED_LIBRARY*/
 
48
 
63
49
#include <my_sys.h>
64
50
#include <mysys_err.h>
65
51
#include <m_string.h>
88
74
#include <sys/select.h>
89
75
#endif
90
76
 
91
 
#ifdef HAVE_SYS_UN_H
92
 
#  include <sys/un.h>
93
 
#endif
 
77
#include <sys/un.h>
94
78
 
95
79
#include <errno.h>
96
80
#define SOCKET_ERROR -1
97
81
 
98
 
#ifdef __WIN__
99
 
#define CONNECT_TIMEOUT 20
100
 
#else
101
82
#define CONNECT_TIMEOUT 0
102
 
#endif
103
83
 
104
84
#include "client_settings.h"
105
85
#include <sql_common.h>
109
89
const char      *unknown_sqlstate= "HY000";
110
90
const char      *not_error_sqlstate= "00000";
111
91
const char      *cant_connect_sqlstate= "08001";
112
 
#ifdef HAVE_SMEM
113
 
char             *shared_memory_base_name= 0;
114
 
const char      *def_shared_memory_base_name= default_shared_memory_base_name;
115
 
#endif
116
92
 
117
93
static void mysql_close_free_options(MYSQL *mysql);
118
94
static void mysql_close_free(MYSQL *mysql);
119
95
 
120
 
#if !(defined(__WIN__) || defined(__NETWARE__))
121
96
static int wait_for_data(my_socket fd, uint timeout);
122
 
#endif
123
97
 
124
98
CHARSET_INFO *default_client_charset_info = &my_charset_latin1;
125
99
 
139
113
int my_connect(my_socket fd, const struct sockaddr *name, uint namelen,
140
114
               uint timeout)
141
115
{
142
 
#if defined(__WIN__) || defined(__NETWARE__)
143
 
  return connect(fd, (struct sockaddr*) name, namelen);
144
 
#else
145
116
  int flags, res, s_err;
146
117
 
147
118
  /*
168
139
  if (res == 0)                         /* Connected quickly! */
169
140
    return(0);
170
141
  return wait_for_data(fd, timeout);
171
 
#endif
172
142
}
173
143
 
174
144
 
179
149
  If not, we will use select()
180
150
*/
181
151
 
182
 
#if !(defined(__WIN__) || defined(__NETWARE__))
183
 
 
184
152
static int wait_for_data(my_socket fd, uint timeout)
185
153
{
186
154
#ifdef HAVE_POLL
270
238
  return (0);                                   /* ok */
271
239
#endif /* HAVE_POLL */
272
240
}
273
 
#endif /* defined(__WIN__) || defined(__NETWARE__) */
274
241
 
275
242
/**
276
243
  Set the internal error message to mysql handler
348
315
  DBUG_VOID_RETURN;
349
316
}
350
317
 
351
 
 
352
 
 
353
 
/*
354
 
  Create a named pipe connection
355
 
*/
356
 
 
357
 
#ifdef __WIN__
358
 
 
359
 
HANDLE create_named_pipe(MYSQL *mysql, uint connect_timeout, char **arg_host,
360
 
                         char **arg_unix_socket)
361
 
{
362
 
  HANDLE hPipe=INVALID_HANDLE_VALUE;
363
 
  char pipe_name[1024];
364
 
  DWORD dwMode;
365
 
  int i;
366
 
  my_bool testing_named_pipes=0;
367
 
  char *host= *arg_host, *unix_socket= *arg_unix_socket;
368
 
 
369
 
  if ( ! unix_socket || (unix_socket)[0] == 0x00)
370
 
    unix_socket = mysql_unix_port;
371
 
  if (!host || !strcmp(host,LOCAL_HOST))
372
 
    host=LOCAL_HOST_NAMEDPIPE;
373
 
 
374
 
  
375
 
  pipe_name[sizeof(pipe_name)-1]= 0;            /* Safety if too long string */
376
 
  strxnmov(pipe_name, sizeof(pipe_name)-1, "\\\\", host, "\\pipe\\",
377
 
           unix_socket, NullS);
378
 
  DBUG_PRINT("info",("Server name: '%s'.  Named Pipe: %s", host, unix_socket));
379
 
 
380
 
  for (i=0 ; i < 100 ; i++)                     /* Don't retry forever */
381
 
  {
382
 
    if ((hPipe = CreateFile(pipe_name,
383
 
                            GENERIC_READ | GENERIC_WRITE,
384
 
                            0,
385
 
                            NULL,
386
 
                            OPEN_EXISTING,
387
 
                            0,
388
 
                            NULL )) != INVALID_HANDLE_VALUE)
389
 
      break;
390
 
    if (GetLastError() != ERROR_PIPE_BUSY)
391
 
    {
392
 
      set_mysql_extended_error(mysql, CR_NAMEDPIPEOPEN_ERROR,
393
 
                               unknown_sqlstate, ER(CR_NAMEDPIPEOPEN_ERROR),
394
 
                               host, unix_socket, (ulong) GetLastError());
395
 
      return INVALID_HANDLE_VALUE;
396
 
    }
397
 
    /* wait for for an other instance */
398
 
    if (! WaitNamedPipe(pipe_name, connect_timeout*1000) )
399
 
    {
400
 
      set_mysql_extended_error(mysql, CR_NAMEDPIPEWAIT_ERROR, unknown_sqlstate,
401
 
                               ER(CR_NAMEDPIPEWAIT_ERROR),
402
 
                               host, unix_socket, (ulong) GetLastError());
403
 
      return INVALID_HANDLE_VALUE;
404
 
    }
405
 
  }
406
 
  if (hPipe == INVALID_HANDLE_VALUE)
407
 
  {
408
 
    set_mysql_extended_error(mysql, CR_NAMEDPIPEOPEN_ERROR, unknown_sqlstate,
409
 
                             ER(CR_NAMEDPIPEOPEN_ERROR), host, unix_socket,
410
 
                             (ulong) GetLastError());
411
 
    return INVALID_HANDLE_VALUE;
412
 
  }
413
 
  dwMode = PIPE_READMODE_BYTE | PIPE_WAIT;
414
 
  if ( !SetNamedPipeHandleState(hPipe, &dwMode, NULL, NULL) )
415
 
  {
416
 
    CloseHandle( hPipe );
417
 
    set_mysql_extended_error(mysql, CR_NAMEDPIPESETSTATE_ERROR,
418
 
                             unknown_sqlstate, ER(CR_NAMEDPIPESETSTATE_ERROR),
419
 
                             host, unix_socket, (ulong) GetLastError());
420
 
    return INVALID_HANDLE_VALUE;
421
 
  }
422
 
  *arg_host=host ; *arg_unix_socket=unix_socket;        /* connect arg */
423
 
  return (hPipe);
424
 
}
425
 
#endif
426
 
 
427
 
 
428
 
/*
429
 
  Create new shared memory connection, return handler of connection
430
 
 
431
 
  SYNOPSIS
432
 
    create_shared_memory()
433
 
    mysql               Pointer of mysql structure
434
 
    net                 Pointer of net structure
435
 
    connect_timeout     Timeout of connection
436
 
*/
437
 
 
438
 
#ifdef HAVE_SMEM
439
 
HANDLE create_shared_memory(MYSQL *mysql,NET *net, uint connect_timeout)
440
 
{
441
 
  ulong smem_buffer_length = shared_memory_buffer_length + 4;
442
 
  /*
443
 
    event_connect_request is event object for start connection actions
444
 
    event_connect_answer is event object for confirm, that server put data
445
 
    handle_connect_file_map is file-mapping object, use for create shared
446
 
    memory
447
 
    handle_connect_map is pointer on shared memory
448
 
    handle_map is pointer on shared memory for client
449
 
    event_server_wrote,
450
 
    event_server_read,
451
 
    event_client_wrote,
452
 
    event_client_read are events for transfer data between server and client
453
 
    handle_file_map is file-mapping object, use for create shared memory
454
 
  */
455
 
  HANDLE event_connect_request = NULL;
456
 
  HANDLE event_connect_answer = NULL;
457
 
  HANDLE handle_connect_file_map = NULL;
458
 
  char *handle_connect_map = NULL;
459
 
 
460
 
  char *handle_map = NULL;
461
 
  HANDLE event_server_wrote = NULL;
462
 
  HANDLE event_server_read = NULL;
463
 
  HANDLE event_client_wrote = NULL;
464
 
  HANDLE event_client_read = NULL;
465
 
  HANDLE event_conn_closed = NULL;
466
 
  HANDLE handle_file_map = NULL;
467
 
  ulong connect_number;
468
 
  char connect_number_char[22], *p;
469
 
  char *tmp= NULL;
470
 
  char *suffix_pos;
471
 
  DWORD error_allow = 0;
472
 
  DWORD error_code = 0;
473
 
  DWORD event_access_rights= SYNCHRONIZE | EVENT_MODIFY_STATE;
474
 
  char *shared_memory_base_name = mysql->options.shared_memory_base_name;
475
 
 
476
 
  /*
477
 
     get enough space base-name + '_' + longest suffix we might ever send
478
 
   */
479
 
  if (!(tmp= (char *)my_malloc(strlen(shared_memory_base_name) + 32L, MYF(MY_FAE))))
480
 
    goto err;
481
 
 
482
 
  /*
483
 
    The name of event and file-mapping events create agree next rule:
484
 
    shared_memory_base_name+unique_part
485
 
    Where:
486
 
    shared_memory_base_name is unique value for each server
487
 
    unique_part is uniquel value for each object (events and file-mapping)
488
 
  */
489
 
  suffix_pos = strxmov(tmp, "Global\\", shared_memory_base_name, "_", NullS);
490
 
  strmov(suffix_pos, "CONNECT_REQUEST");
491
 
  if (!(event_connect_request= OpenEvent(event_access_rights, FALSE, tmp)))
492
 
  {
493
 
    error_allow = CR_SHARED_MEMORY_CONNECT_REQUEST_ERROR;
494
 
    goto err;
495
 
  }
496
 
  strmov(suffix_pos, "CONNECT_ANSWER");
497
 
  if (!(event_connect_answer= OpenEvent(event_access_rights,FALSE,tmp)))
498
 
  {
499
 
    error_allow = CR_SHARED_MEMORY_CONNECT_ANSWER_ERROR;
500
 
    goto err;
501
 
  }
502
 
  strmov(suffix_pos, "CONNECT_DATA");
503
 
  if (!(handle_connect_file_map= OpenFileMapping(FILE_MAP_WRITE,FALSE,tmp)))
504
 
  {
505
 
    error_allow = CR_SHARED_MEMORY_CONNECT_FILE_MAP_ERROR;
506
 
    goto err;
507
 
  }
508
 
  if (!(handle_connect_map= MapViewOfFile(handle_connect_file_map,
509
 
                                          FILE_MAP_WRITE,0,0,sizeof(DWORD))))
510
 
  {
511
 
    error_allow = CR_SHARED_MEMORY_CONNECT_MAP_ERROR;
512
 
    goto err;
513
 
  }
514
 
 
515
 
  /* Send to server request of connection */
516
 
  if (!SetEvent(event_connect_request))
517
 
  {
518
 
    error_allow = CR_SHARED_MEMORY_CONNECT_SET_ERROR;
519
 
    goto err;
520
 
  }
521
 
 
522
 
  /* Wait of answer from server */
523
 
  if (WaitForSingleObject(event_connect_answer,connect_timeout*1000) !=
524
 
      WAIT_OBJECT_0)
525
 
  {
526
 
    error_allow = CR_SHARED_MEMORY_CONNECT_ABANDONED_ERROR;
527
 
    goto err;
528
 
  }
529
 
 
530
 
  /* Get number of connection */
531
 
  connect_number = uint4korr(handle_connect_map);/*WAX2*/
532
 
  p= int10_to_str(connect_number, connect_number_char, 10);
533
 
 
534
 
  /*
535
 
    The name of event and file-mapping events create agree next rule:
536
 
    shared_memory_base_name+unique_part+number_of_connection
537
 
 
538
 
    Where:
539
 
    shared_memory_base_name is uniquel value for each server
540
 
    unique_part is uniquel value for each object (events and file-mapping)
541
 
    number_of_connection is number of connection between server and client
542
 
  */
543
 
  suffix_pos = strxmov(tmp, "Global\\", shared_memory_base_name, "_", connect_number_char,
544
 
                       "_", NullS);
545
 
  strmov(suffix_pos, "DATA");
546
 
  if ((handle_file_map = OpenFileMapping(FILE_MAP_WRITE,FALSE,tmp)) == NULL)
547
 
  {
548
 
    error_allow = CR_SHARED_MEMORY_FILE_MAP_ERROR;
549
 
    goto err2;
550
 
  }
551
 
  if ((handle_map = MapViewOfFile(handle_file_map,FILE_MAP_WRITE,0,0,
552
 
                                  smem_buffer_length)) == NULL)
553
 
  {
554
 
    error_allow = CR_SHARED_MEMORY_MAP_ERROR;
555
 
    goto err2;
556
 
  }
557
 
 
558
 
  strmov(suffix_pos, "SERVER_WROTE");
559
 
  if ((event_server_wrote = OpenEvent(event_access_rights,FALSE,tmp)) == NULL)
560
 
  {
561
 
    error_allow = CR_SHARED_MEMORY_EVENT_ERROR;
562
 
    goto err2;
563
 
  }
564
 
 
565
 
  strmov(suffix_pos, "SERVER_READ");
566
 
  if ((event_server_read = OpenEvent(event_access_rights,FALSE,tmp)) == NULL)
567
 
  {
568
 
    error_allow = CR_SHARED_MEMORY_EVENT_ERROR;
569
 
    goto err2;
570
 
  }
571
 
 
572
 
  strmov(suffix_pos, "CLIENT_WROTE");
573
 
  if ((event_client_wrote = OpenEvent(event_access_rights,FALSE,tmp)) == NULL)
574
 
  {
575
 
    error_allow = CR_SHARED_MEMORY_EVENT_ERROR;
576
 
    goto err2;
577
 
  }
578
 
 
579
 
  strmov(suffix_pos, "CLIENT_READ");
580
 
  if ((event_client_read = OpenEvent(event_access_rights,FALSE,tmp)) == NULL)
581
 
  {
582
 
    error_allow = CR_SHARED_MEMORY_EVENT_ERROR;
583
 
    goto err2;
584
 
  }
585
 
 
586
 
  strmov(suffix_pos, "CONNECTION_CLOSED");
587
 
  if ((event_conn_closed = OpenEvent(event_access_rights,FALSE,tmp)) == NULL)
588
 
  {
589
 
    error_allow = CR_SHARED_MEMORY_EVENT_ERROR;
590
 
    goto err2;
591
 
  }
592
 
  /*
593
 
    Set event that server should send data
594
 
  */
595
 
  SetEvent(event_server_read);
596
 
 
597
 
err2:
598
 
  if (error_allow == 0)
599
 
  {
600
 
    net->vio= vio_new_win32shared_memory(net,handle_file_map,handle_map,
601
 
                                         event_server_wrote,
602
 
                                         event_server_read,event_client_wrote,
603
 
                                         event_client_read,event_conn_closed);
604
 
  }
605
 
  else
606
 
  {
607
 
    error_code = GetLastError();
608
 
    if (event_server_read)
609
 
      CloseHandle(event_server_read);
610
 
    if (event_server_wrote)
611
 
      CloseHandle(event_server_wrote);
612
 
    if (event_client_read)
613
 
      CloseHandle(event_client_read);
614
 
    if (event_client_wrote)
615
 
      CloseHandle(event_client_wrote);
616
 
    if (event_conn_closed)
617
 
      CloseHandle(event_conn_closed);
618
 
    if (handle_map)
619
 
      UnmapViewOfFile(handle_map);
620
 
    if (handle_file_map)
621
 
      CloseHandle(handle_file_map);
622
 
  }
623
 
err:
624
 
  if (tmp)
625
 
    my_free(tmp, MYF(0));
626
 
  if (error_allow)
627
 
    error_code = GetLastError();
628
 
  if (event_connect_request)
629
 
    CloseHandle(event_connect_request);
630
 
  if (event_connect_answer)
631
 
    CloseHandle(event_connect_answer);
632
 
  if (handle_connect_map)
633
 
    UnmapViewOfFile(handle_connect_map);
634
 
  if (handle_connect_file_map)
635
 
    CloseHandle(handle_connect_file_map);
636
 
  if (error_allow)
637
 
  {
638
 
    if (error_allow == CR_SHARED_MEMORY_EVENT_ERROR)
639
 
      set_mysql_extended_error(mysql, error_allow, unknown_sqlstate,
640
 
                               ER(error_allow), suffix_pos, error_code);
641
 
    else
642
 
      set_mysql_extended_error(mysql, error_allow, unknown_sqlstate,
643
 
                               ER(error_allow), error_code);
644
 
    return(INVALID_HANDLE_VALUE);
645
 
  }
646
 
  return(handle_map);
647
 
}
648
 
#endif
649
 
 
650
318
/*****************************************************************************
651
319
  Read a packet from server. Give error message if socket was down
652
320
  or packet is an error message
844
512
}
845
513
 
846
514
 
847
 
#ifdef __WIN__
848
 
static my_bool is_NT(void)
849
 
{
850
 
  char *os=getenv("OS");
851
 
  return (os && !strcmp(os, "Windows_NT")) ? 1 : 0;
852
 
}
853
 
#endif
854
 
 
855
515
 
856
516
#ifdef CHECK_LICENSE
857
517
/**
1683
1343
  char          *end,*host_info;
1684
1344
  ulong         pkt_length;
1685
1345
  NET           *net= &mysql->net;
1686
 
#ifdef MYSQL_SERVER
1687
 
  thr_alarm_t   alarmed;
1688
 
  ALARM         alarm_buff;
1689
 
#endif
1690
 
#ifdef __WIN__
1691
 
  HANDLE        hPipe=INVALID_HANDLE_VALUE;
1692
 
#endif
1693
 
#ifdef HAVE_SYS_UN_H
1694
1346
  struct        sockaddr_un UNIXaddr;
1695
 
#endif
1696
1347
  init_sigpipe_variables
1697
1348
  DBUG_ENTER("mysql_real_connect");
1698
1349
 
1731
1382
  if (!passwd)
1732
1383
  {
1733
1384
    passwd=mysql->options.password;
1734
 
#if !defined(DONT_USE_MYSQL_PWD) && !defined(MYSQL_SERVER)
1735
 
    if (!passwd)
1736
 
      passwd=getenv("MYSQL_PWD");               /* get it from environment */
1737
 
#endif
1738
1385
    if (!passwd)
1739
1386
      passwd= "";
1740
1387
  }
1784
1431
    }
1785
1432
  }
1786
1433
#endif /* HAVE_SMEM */
1787
 
#if defined(HAVE_SYS_UN_H)
1788
1434
  if (!net->vio &&
1789
1435
      (!mysql->options.protocol ||
1790
1436
       mysql->options.protocol == MYSQL_PROTOCOL_SOCKET) &&
1836
1482
    }
1837
1483
    mysql->options.protocol=MYSQL_PROTOCOL_SOCKET;
1838
1484
  }
1839
 
#elif defined(__WIN__)
1840
 
  if (!net->vio &&
1841
 
      (mysql->options.protocol == MYSQL_PROTOCOL_PIPE ||
1842
 
       (host && !strcmp(host,LOCAL_HOST_NAMEDPIPE)) ||
1843
 
       (! have_tcpip && (unix_socket || !host && is_NT()))))
1844
 
  {
1845
 
    if ((hPipe= create_named_pipe(mysql, mysql->options.connect_timeout,
1846
 
                                  (char**) &host, (char**) &unix_socket)) ==
1847
 
        INVALID_HANDLE_VALUE)
1848
 
    {
1849
 
      DBUG_PRINT("error",
1850
 
                 ("host: '%s'  socket: '%s'  have_tcpip: %d",
1851
 
                  host ? host : "<null>",
1852
 
                  unix_socket ? unix_socket : "<null>",
1853
 
                  (int) have_tcpip));
1854
 
      if (mysql->options.protocol == MYSQL_PROTOCOL_PIPE ||
1855
 
          (host && !strcmp(host,LOCAL_HOST_NAMEDPIPE)) ||
1856
 
          (unix_socket && !strcmp(unix_socket,MYSQL_NAMEDPIPE)))
1857
 
        goto error;
1858
 
      /* Try also with TCP/IP */
1859
 
    }
1860
 
    else
1861
 
    {
1862
 
      net->vio=vio_new_win32pipe(hPipe);
1863
 
      snprintf(host_info=buff, sizeof(buff)-1,
1864
 
               ER(CR_NAMEDPIPE_CONNECTION), unix_socket);
1865
 
    }
1866
 
  }
1867
 
#endif
1868
1485
  if (!net->vio &&
1869
1486
      (!mysql->options.protocol ||
1870
1487
       mysql->options.protocol == MYSQL_PROTOCOL_TCP))
1883
1500
 
1884
1501
    snprintf(host_info=buff, sizeof(buff)-1, ER(CR_TCP_CONNECTION), host);
1885
1502
    DBUG_PRINT("info",("Server name: '%s'.  TCP sock: %d", host, port));
1886
 
#ifdef MYSQL_SERVER
1887
 
    thr_alarm_init(&alarmed);
1888
 
    thr_alarm(&alarmed, mysql->options.connect_timeout, &alarm_buff);
1889
 
#endif
1890
 
 
1891
 
    DBUG_PRINT("info",("IP '%s'", "client"));
1892
 
 
1893
 
#ifdef MYSQL_SERVER
1894
 
    thr_end_alarm(&alarmed);
1895
 
#endif
1896
1503
 
1897
1504
    memset(&hints, 0, sizeof(hints));
1898
1505
    hints.ai_socktype= SOCK_STREAM;