home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 January / Chip_2001-01_cd1.bin / tema / mysql / mysql-3.23.28g-win-source.exe / sql / mysqld.cpp < prev    next >
C/C++ Source or Header  |  2000-11-22  |  120KB  |  3,827 lines

  1. /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
  2.  
  3.    This program is free software; you can redistribute it and/or modify
  4.    it under the terms of the GNU General Public License as published by
  5.    the Free Software Foundation; either version 2 of the License, or
  6.    (at your option) any later version.
  7.  
  8.    This program is distributed in the hope that it will be useful,
  9.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.    GNU General Public License for more details.
  12.  
  13.    You should have received a copy of the GNU General Public License
  14.    along with this program; if not, write to the Free Software
  15.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  16.  
  17. #include "mysql_priv.h"
  18. #include <mysql.h>
  19. #include <m_ctype.h>
  20. #include "sql_acl.h"
  21. #include "slave.h"
  22. #ifdef HAVE_BERKELEY_DB
  23. #include "ha_berkeley.h"
  24. #endif
  25. #ifdef HAVE_INNOBASE_DB
  26. #include "ha_innobase.h"
  27. #endif
  28. #include "ha_myisam.h"
  29. #include <nisam.h>
  30. #include <thr_alarm.h>
  31. #include <ft_global.h>
  32.  
  33. #ifndef DBUG_OFF
  34. #define ONE_THREAD
  35. #endif
  36.  
  37. #ifdef    __cplusplus
  38. extern "C" {                    // Because of SCO 3.2V4.2
  39. #endif
  40. #include <errno.h>
  41. #include <sys/stat.h>
  42. #ifndef __GNU_LIBRARY__
  43. #define __GNU_LIBRARY__                // Skip warnings in getopt.h
  44. #endif
  45. #include <getopt.h>
  46. #ifdef HAVE_SYSENT_H
  47. #include <sysent.h>
  48. #endif
  49. #ifdef HAVE_PWD_H
  50. #include <pwd.h>                // For getpwent
  51. #endif
  52. #ifdef HAVE_GRP_H
  53. #include <grp.h>
  54. #endif
  55.  
  56. #ifndef __WIN__
  57. #include <sys/resource.h>
  58. #ifdef HAVE_SYS_UN_H
  59. #  include <sys/un.h>
  60. #endif
  61. #include <netdb.h>
  62. #ifdef HAVE_SELECT_H
  63. #  include <select.h>
  64. #endif
  65. #ifdef HAVE_SYS_SELECT_H
  66. #include <sys/select.h>
  67. #endif
  68. #include <sys/utsname.h>
  69. #else
  70. #include <windows.h>
  71. #endif // __WIN__
  72.  
  73. #ifdef HAVE_LIBWRAP
  74. #include <tcpd.h>
  75. #include <syslog.h>
  76. #ifdef NEED_SYS_SYSLOG_H
  77. #include <sys/syslog.h>
  78. #endif /* NEED_SYS_SYSLOG_H */
  79. int allow_severity = LOG_INFO;
  80. int deny_severity = LOG_WARNING;
  81. #endif /* HAVE_LIBWRAP */
  82.  
  83. #ifdef HAVE_SYS_MMAN_H
  84. #include <sys/mman.h>
  85. #endif
  86.  
  87. #if defined(__FreeBSD__) && defined(HAVE_IEEEFP_H)
  88. #include <ieeefp.h>
  89. #ifdef HAVE_FP_EXCEPT                // Fix type conflict
  90. typedef fp_except fp_except_t;
  91. #endif
  92.  
  93.   /* We can't handle floating point expections with threads, so disable
  94.      this on freebsd
  95.   */
  96.  
  97. inline void reset_floating_point_exceptions()
  98. {
  99.   /* Don't fall for overflow, underflow,divide-by-zero or loss of precision */
  100.   fpsetmask(~(FP_X_INV | FP_X_DNML | FP_X_OFL | FP_X_UFL |
  101.           FP_X_DZ | FP_X_IMP));
  102. }
  103. #else
  104. #define reset_floating_point_exceptions()
  105. #endif /* __FreeBSD__ && HAVE_IEEEFP_H */
  106.  
  107. #ifdef    __cplusplus
  108. }
  109. #endif
  110.  
  111. #if defined(HAVE_LINUXTHREADS)
  112. #define THR_KILL_SIGNAL SIGINT
  113. #else
  114. #define THR_KILL_SIGNAL SIGUSR2        // Can't use this with LinuxThreads
  115. #endif
  116.  
  117. #ifdef HAVE_GLIBC2_STYLE_GETHOSTBYNAME_R
  118. #include <sys/types.h>
  119. #else
  120. #include <my_pthread.h>            // For thr_setconcurency()
  121. #endif
  122. #if defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE) && !defined(__linux__) && !defined(HAVE_mit_thread)
  123. #define SET_RLIMIT_NOFILE
  124. #endif
  125.  
  126. #ifdef SOLARIS
  127. extern "C" int gethostname(char *name, int namelen);
  128. #endif
  129.  
  130. #define MYSQL_KILL_SIGNAL SIGTERM
  131.  
  132. #ifndef DBUG_OFF
  133. static const char* default_dbug_option=IF_WIN("d:t:i:O,\\mysqld.trace",
  134.                           "d:t:i:o,/tmp/mysqld.trace");
  135. #endif
  136.  
  137. #ifdef __NT__
  138. static char szPipeName [ 257 ];
  139. static SECURITY_ATTRIBUTES saPipeSecurity;
  140. static SECURITY_DESCRIPTOR sdPipeDescriptor;
  141. static HANDLE hPipe = INVALID_HANDLE_VALUE;
  142. static pthread_cond_t COND_handler_count;
  143. static uint handler_count;
  144. #endif
  145. #ifdef __WIN__
  146. static bool opt_console=0;
  147. #endif
  148.  
  149. static bool opt_skip_slave_start = 0; // if set, slave is not autostarted
  150. static ulong opt_specialflag=SPECIAL_ENGLISH;
  151. static my_socket unix_sock= INVALID_SOCKET,ip_sock= INVALID_SOCKET;
  152. static ulong back_log,connect_timeout,concurrency;
  153. static my_string opt_logname=0,opt_update_logname=0,
  154.        opt_binlog_index_name = 0,opt_slow_logname=0;
  155. static char mysql_home[FN_REFLEN],pidfile_name[FN_REFLEN];
  156. static pthread_t select_thread;
  157. static pthread_t flush_thread;            // Used when debugging
  158. static bool opt_log,opt_update_log,opt_bin_log,opt_slow_log,opt_noacl,
  159.             opt_disable_networking=0, opt_bootstrap=0,opt_skip_show_db=0,
  160.         opt_ansi_mode=0,opt_myisam_log=0, opt_large_files=sizeof(my_off_t) > 4;
  161. bool opt_sql_bin_update = 0, opt_log_slave_updates = 0;
  162. extern MASTER_INFO glob_mi;
  163. extern int init_master_info(MASTER_INFO* mi);
  164.  
  165. // if sql_bin_update is true, SQL_LOG_UPDATE and SQL_LOG_BIN are kept in sync, and are
  166. // treated as aliases for each other
  167.  
  168. static bool kill_in_progress=FALSE;
  169. static struct rand_struct sql_rand;
  170. static int cleanup_done;
  171. static char **defaults_argv,time_zone[30];
  172. static const char *default_table_type_name;
  173.  
  174. #ifdef HAVE_OPENSSL
  175. static bool opt_use_ssl = FALSE;
  176. static char *opt_ssl_key = 0;
  177. static char *opt_ssl_cert = 0;
  178. static char *opt_ssl_ca = 0;
  179. static char *opt_ssl_capath = 0;
  180. static VioSSLAcceptorFd* ssl_acceptor_fd = 0;
  181. #endif /* HAVE_OPENSSL */
  182.  
  183.  
  184. I_List <i_string_pair> replicate_rewrite_db;
  185. I_List<i_string> replicate_do_db, replicate_ignore_db;
  186. // allow the user to tell us which db to replicate and which to ignore
  187. I_List<i_string> binlog_do_db, binlog_ignore_db;
  188.  
  189. uint32 server_id = 0; // server id for replication
  190. uint mysql_port;
  191. uint test_flags, select_errors=0, dropping_tables=0,ha_open_options=0;
  192. uint volatile thread_count=0, thread_running=0, kill_cached_threads=0,
  193.           wake_thread=0, global_read_lock=0;
  194. ulong thd_startup_options=(OPTION_UPDATE_LOG | OPTION_AUTO_IS_NULL |
  195.                OPTION_BIN_LOG | OPTION_AUTO_COMMIT |
  196.                OPTION_QUOTE_SHOW_CREATE );
  197. uint protocol_version=PROTOCOL_VERSION;
  198. ulong keybuff_size,sortbuff_size,max_item_sort_length,table_cache_size,
  199.       max_join_size,join_buff_size,tmp_table_size,thread_stack,
  200.       thread_stack_min,net_wait_timeout,what_to_log= ~ (1L << (uint) COM_TIME),
  201.       query_buff_size, lower_case_table_names, mysqld_net_retry_count,
  202.       net_interactive_timeout, slow_launch_time = 2L,
  203.       net_read_timeout,net_write_timeout;
  204. ulong thread_cache_size=0;
  205. volatile ulong cached_thread_count=0;
  206.  
  207. // replication parameters, if master_host is not NULL, we are slaving off the master
  208. my_string master_user = (char*) "test", master_password = 0, master_host=0,
  209.   master_info_file = (char*) "master.info";
  210. const char *localhost=LOCAL_HOST;
  211. uint master_port = MYSQL_PORT, master_connect_retry = 60;
  212.  
  213. ulong max_tmp_tables,max_heap_table_size;
  214. ulong bytes_sent = 0L, bytes_received = 0L;
  215.  
  216. bool opt_endinfo,using_udf_functions,low_priority_updates, locked_in_memory;
  217. bool volatile abort_loop,select_thread_in_use,flush_thread_in_use,grant_option;
  218. bool volatile ready_to_exit,shutdown_in_progress;
  219. ulong refresh_version=1L,flush_version=1L;    /* Increments on each reload */
  220. ulong query_id=1L,long_query_count,long_query_time,aborted_threads,
  221.       aborted_connects,delayed_insert_timeout,delayed_insert_limit,
  222.       delayed_queue_size,delayed_insert_threads,delayed_insert_writes,
  223.       delayed_rows_in_use,delayed_insert_errors,flush_time;
  224. ulong filesort_rows, filesort_range_count, filesort_scan_count;
  225. ulong filesort_merge_passes;
  226. ulong select_range_check_count, select_range_count, select_scan_count;
  227. ulong select_full_range_join_count,select_full_join_count;
  228. ulong specialflag=0,opened_tables=0,created_tmp_tables=0,
  229.       created_tmp_disk_tables=0;
  230. ulong max_connections,max_insert_delayed_threads,max_used_connections,
  231.       max_connect_errors;
  232. ulong thread_id=1L,current_pid;
  233. ulong slow_launch_threads = 0;
  234. char mysql_real_data_home[FN_REFLEN],
  235.      mysql_data_home[2],language[LIBLEN],reg_ext[FN_EXTLEN],
  236.      default_charset[LIBLEN],mysql_charsets_dir[FN_REFLEN], *charsets_list,
  237.      blob_newline,f_fyllchar,max_sort_char,*mysqld_user,*mysqld_chroot,
  238.      *opt_init_file;
  239. char *opt_bin_logname = 0; // this one needs to be seen in sql_parse.cc
  240. char server_version[50]=MYSQL_SERVER_VERSION;
  241. const char *first_keyword="first";
  242. const char **errmesg;            /* Error messages */
  243. const char *myisam_recover_options_str="OFF";
  244. byte last_ref[MAX_REFLENGTH];        /* Index ref of keys */
  245. my_string mysql_unix_port=NULL,mysql_tmpdir=NULL;
  246. ulong my_bind_addr;            /* the address we bind to */
  247. DATE_FORMAT dayord;
  248. double log_10[32];            /* 10 potences */
  249. I_List<THD> threads,thread_cache;
  250. time_t start_time;
  251.  
  252.  
  253. pthread_key(MEM_ROOT*,THR_MALLOC);
  254. pthread_key(THD*, THR_THD);
  255. pthread_key(NET*, THR_NET);
  256. pthread_mutex_t LOCK_mysql_create_db, LOCK_Acl, LOCK_open, LOCK_thread_count,
  257.         LOCK_mapped_file, LOCK_status, LOCK_grant,
  258.         LOCK_error_log,
  259.         LOCK_delayed_insert, LOCK_delayed_status, LOCK_delayed_create,
  260.         LOCK_flush, LOCK_crypt, LOCK_bytes_sent, LOCK_bytes_received,
  261.                 LOCK_binlog_update, LOCK_slave, LOCK_server_id;
  262.  
  263. pthread_cond_t COND_refresh,COND_thread_count,COND_flush, COND_binlog_update,
  264.   COND_slave_stopped;
  265. pthread_cond_t COND_thread_cache,COND_flush_thread_cache;
  266. pthread_t signal_thread;
  267. pthread_attr_t connection_attrib;
  268. enum db_type default_table_type=DB_TYPE_MYISAM;
  269.  
  270. #ifdef __WIN__
  271. #undef     getpid
  272. #include <process.h>
  273. HANDLE hEventShutdown;
  274. #include "nt_servc.h"
  275. static     NTService  Service;          // Service object for WinNT
  276. #endif
  277.  
  278. static void *signal_hand(void *arg);
  279. static void set_options(void);
  280. static void get_options(int argc,char **argv);
  281. static char *get_relative_path(const char *path);
  282. static void fix_paths(void);
  283. static pthread_handler_decl(handle_connections_sockets,arg);
  284. static int bootstrap(FILE *file);
  285. static bool read_init_file(char *file_name);
  286. #ifdef __NT__
  287. static pthread_handler_decl(handle_connections_namedpipes,arg);
  288. #endif
  289. #ifdef __WIN__
  290. static int get_service_parameters();
  291. #endif
  292. static pthread_handler_decl(handle_flush,arg);
  293. extern pthread_handler_decl(handle_slave,arg);
  294. #ifdef SET_RLIMIT_NOFILE
  295. static uint set_maximum_open_files(uint max_file_limit);
  296. #endif
  297. static ulong find_bit_type(const char *x, TYPELIB *bit_lib);
  298.  
  299. /****************************************************************************
  300. ** Code to end mysqld
  301. ****************************************************************************/
  302.  
  303. static void close_connections(void)
  304. {
  305. #ifdef EXTRA_DEBUG
  306.   int count=0;
  307. #endif
  308.   NET net;
  309.   DBUG_ENTER("close_connections");
  310.  
  311.   /* Clear thread cache */
  312.   kill_cached_threads++;
  313.   flush_thread_cache();
  314.  
  315.   /* kill flush thread */
  316.   (void) pthread_mutex_lock(&LOCK_flush);
  317.   if (flush_thread_in_use)
  318.   {
  319.     DBUG_PRINT("quit",("killing flush thread: %lx",flush_thread));
  320.    (void) pthread_cond_signal(&COND_flush);
  321.   }
  322.   (void) pthread_mutex_unlock(&LOCK_flush);
  323.  
  324.   /* kill connection thread */
  325. #if !defined(__WIN__) && !defined(__EMX__)
  326.   DBUG_PRINT("quit",("waiting for select thread: %lx",select_thread));
  327.   (void) pthread_mutex_lock(&LOCK_thread_count);
  328.  
  329.   while (select_thread_in_use)
  330.   {
  331.     struct timespec abstime;
  332.     int error;
  333.     LINT_INIT(error);
  334. #ifndef DONT_USE_THR_ALARM
  335.     if (pthread_kill(select_thread,THR_CLIENT_ALARM))
  336.       break;                    // allready dead
  337. #endif
  338. #ifdef HAVE_TIMESPEC_TS_SEC
  339.     abstime.ts_sec=time(NULL)+2;        // Bsd 2.1
  340.     abstime.ts_nsec=0;
  341. #else
  342.     struct timeval tv;
  343.     gettimeofday(&tv,0);
  344.     abstime.tv_sec=tv.tv_sec+2;
  345.     abstime.tv_nsec=tv.tv_usec*1000;
  346. #endif
  347.     for (uint tmp=0 ; tmp < 10 ; tmp++)
  348.     {
  349.       error=pthread_cond_timedwait(&COND_thread_count,&LOCK_thread_count,
  350.                    &abstime);
  351.       if (error != EINTR)
  352.     break;
  353.     }
  354. #ifdef EXTRA_DEBUG
  355.     if (error != 0 && !count++)
  356.       sql_print_error("Got error %d from pthread_cond_timedwait",error);
  357. #endif
  358. #if defined(AIX_3_2) || defined(HAVE_DEC_3_2_THREADS)
  359.     if (ip_sock != INVALID_SOCKET)
  360.     {
  361.       VOID(shutdown(ip_sock,2));
  362.       VOID(closesocket(ip_sock));
  363.       VOID(shutdown(unix_sock,2));
  364.       VOID(closesocket(unix_sock));
  365.       VOID(unlink(mysql_unix_port));
  366.       ip_sock=unix_sock= INVALID_SOCKET;
  367.     }
  368. #endif
  369.   }
  370.   (void) pthread_mutex_unlock(&LOCK_thread_count);
  371. #endif /* __WIN__ */
  372.  
  373.  
  374.   /* Abort listening to new connections */
  375.   DBUG_PRINT("quit",("Closing sockets"));
  376.   if ( !opt_disable_networking )
  377.   {
  378.     if (ip_sock != INVALID_SOCKET)
  379.     {
  380.       (void) shutdown(ip_sock,2);
  381.       (void) closesocket(ip_sock);
  382.       ip_sock= INVALID_SOCKET;
  383.     }
  384.   }
  385. #ifdef __NT__
  386.   if ( hPipe != INVALID_HANDLE_VALUE )
  387.   {
  388.     HANDLE hTempPipe = hPipe;
  389.     DBUG_PRINT( "quit", ("Closing named pipes") );
  390.     hPipe = INVALID_HANDLE_VALUE;
  391.     CancelIo( hTempPipe );
  392.     DisconnectNamedPipe( hTempPipe );
  393.     CloseHandle( hTempPipe );
  394.   }
  395. #endif
  396. #ifdef HAVE_SYS_UN_H
  397.   if (unix_sock != INVALID_SOCKET)
  398.   {
  399.     (void) shutdown(unix_sock,2);
  400.     (void) closesocket(unix_sock);
  401.     (void) unlink(mysql_unix_port);
  402.     unix_sock= INVALID_SOCKET;
  403.   }
  404. #endif
  405.   end_thr_alarm();             // Don't allow alarms
  406.  
  407.   /* First signal all threads that it's time to die */
  408.  
  409.   THD *tmp;
  410.   (void) pthread_mutex_lock(&LOCK_thread_count); // For unlink from list
  411.  
  412.   I_List_iterator<THD> it(threads);
  413.   while ((tmp=it++))
  414.   {
  415.     DBUG_PRINT("quit",("Informing thread %ld that it's time to die",
  416.                tmp->thread_id));
  417.     tmp->killed=1;
  418.     if (tmp->mysys_var)
  419.     {
  420.       tmp->mysys_var->abort=1;
  421.       if (tmp->mysys_var->current_mutex)
  422.       {
  423.     pthread_mutex_lock(tmp->mysys_var->current_mutex);
  424.     pthread_cond_broadcast(tmp->mysys_var->current_cond);
  425.     pthread_mutex_unlock(tmp->mysys_var->current_mutex);
  426.       }
  427.     }
  428.   }
  429.   (void) pthread_mutex_unlock(&LOCK_thread_count); // For unlink from list
  430.  
  431.   if (thread_count)
  432.   {
  433.     sleep(1);                    // Give threads time to die
  434.   }
  435.  
  436.   /* Force remaining threads to die by closing the connection to the client */
  437.  
  438.   (void) my_net_init(&net, (Vio*) 0);
  439.   for (;;)
  440.   {
  441.     DBUG_PRINT("quit",("Locking LOCK_thread_count"));
  442.     (void) pthread_mutex_lock(&LOCK_thread_count); // For unlink from list
  443.     if (!(tmp=threads.get()))
  444.     {
  445.       DBUG_PRINT("quit",("Unlocking LOCK_thread_count"));
  446.       (void) pthread_mutex_unlock(&LOCK_thread_count);
  447.       break;
  448.     }
  449. #ifndef __bsdi__                // Bug in BSDI kernel
  450.     if ((net.vio=tmp->net.vio) != 0)
  451.     {
  452.       sql_print_error(ER(ER_FORCING_CLOSE),my_progname,
  453.               tmp->thread_id,tmp->user ? tmp->user : "");
  454.       close_connection(&net,0,0);
  455.     }
  456. #endif
  457.     DBUG_PRINT("quit",("Unlocking LOCK_thread_count"));
  458.     (void) pthread_mutex_unlock(&LOCK_thread_count);
  459.   }
  460.   net_end(&net);
  461.   /* All threads has now been aborted */
  462.   DBUG_PRINT("quit",("Waiting for threads to die (count=%u)",thread_count));
  463.   (void) pthread_mutex_lock(&LOCK_thread_count);
  464.   while (thread_count)
  465.   {
  466.     (void) pthread_cond_wait(&COND_thread_count,&LOCK_thread_count);
  467.     DBUG_PRINT("quit",("One thread died (count=%u)",thread_count));
  468.   }
  469.   (void) pthread_mutex_unlock(&LOCK_thread_count);
  470.  
  471.   mysql_log.close();
  472.   mysql_update_log.close();
  473.   mysql_bin_log.close();
  474.   my_free(charsets_list, MYF(0));
  475.   DBUG_PRINT("quit",("close_connections thread"));
  476.   DBUG_VOID_RETURN;
  477. }
  478.  
  479. void kill_mysql(void)
  480. {
  481.   DBUG_ENTER("kill_mysql");
  482.  
  483. #if defined(__WIN__)
  484.   {
  485.     if (!SetEvent(hEventShutdown))
  486.     {
  487.       DBUG_PRINT("error",("Got error: %ld from SetEvent",GetLastError()));
  488.     }
  489.     // or:
  490.     // HANDLE hEvent=OpenEvent(0, FALSE, "MySqlShutdown");
  491.     // SetEvent(hEventShutdown);
  492.     // CloseHandle(hEvent);
  493.   }
  494. #elif defined(HAVE_PTHREAD_KILL)
  495.     if (pthread_kill(signal_thread,SIGTERM))    /* End everything nicely */
  496.     {
  497.       DBUG_PRINT("error",("Got error %d from pthread_kill",errno)); /* purecov: inspected */
  498.     }
  499. #else
  500.     kill(current_pid,SIGTERM);
  501. #endif
  502.     DBUG_PRINT("quit",("After pthread_kill"));
  503.     shutdown_in_progress=1;            // Safety if kill didn't work
  504.     DBUG_VOID_RETURN;
  505. }
  506.  
  507.  
  508.     /* Force server down. kill all connections and threads and exit */
  509.  
  510. #ifndef __WIN__
  511. static void *kill_server(void *sig_ptr)
  512. #define RETURN_FROM_KILL_SERVER return 0
  513. #else
  514. static void __cdecl kill_server(int sig_ptr)
  515. #define RETURN_FROM_KILL_SERVER return
  516. #endif
  517. {
  518.   int sig=(int) (long) sig_ptr;            // This is passed a int
  519.   DBUG_ENTER("kill_server");
  520.  
  521.   // if there is a signal during the kill in progress, we do not need
  522.   // another one
  523.   if (kill_in_progress)                // Safety
  524.     RETURN_FROM_KILL_SERVER;
  525.   kill_in_progress=TRUE;
  526.   abort_loop=1;                    // This should be set
  527.   signal(sig,SIG_IGN);
  528.   if (sig == MYSQL_KILL_SIGNAL || sig == 0)
  529.     sql_print_error(ER(ER_NORMAL_SHUTDOWN),my_progname);
  530.   else
  531.     sql_print_error(ER(ER_GOT_SIGNAL),my_progname,sig); /* purecov: inspected */
  532.  
  533. #if defined(USE_ONE_SIGNAL_HAND) && !defined(__WIN__)
  534.   my_thread_init();                // If this is a new thread
  535. #endif
  536.   close_connections();
  537.   sql_print_error(ER(ER_SHUTDOWN_COMPLETE),my_progname);
  538.   if (sig != MYSQL_KILL_SIGNAL && sig != 0)
  539.     unireg_abort(1);                /* purecov: inspected */
  540.   else
  541.     unireg_end(0);
  542.   pthread_exit(0);                /* purecov: deadcode */
  543.   RETURN_FROM_KILL_SERVER;
  544. }
  545.  
  546.  
  547. #ifdef USE_ONE_SIGNAL_HAND
  548. pthread_handler_decl(kill_server_thread,arg __attribute__((unused)))
  549. {
  550.   my_thread_init();                // Initialize new thread
  551.   kill_server(0);
  552.   my_thread_end();                // Normally never reached
  553.   return 0;
  554. }
  555. #endif
  556.  
  557. static sig_handler print_signal_warning(int sig)
  558. {
  559.   sql_print_error("Warning: Got signal %d from thread %d",
  560.           sig,my_thread_id());
  561. #ifdef DONT_REMEMBER_SIGNAL
  562.   sigset(sig,print_signal_warning);        /* int. thread system calls */
  563. #endif
  564. #ifndef __WIN__
  565.   if (sig == SIGALRM)
  566.     alarm(2);                    /* reschedule alarm */
  567. #endif
  568. }
  569.  
  570.  
  571. void unireg_end(int signal_number __attribute__((unused)))
  572. {
  573.   clean_up();
  574.   pthread_exit(0);                // Exit is in main thread
  575. }
  576.  
  577.  
  578. void unireg_abort(int exit_code)
  579. {
  580.   if (exit_code)
  581.     sql_print_error("Aborting\n");
  582.   clean_up(); /* purecov: inspected */
  583.   exit(exit_code); /* purecov: inspected */
  584. }
  585.  
  586.  
  587. void clean_up(void)
  588. {
  589.   DBUG_PRINT("exit",("clean_up"));
  590.   if (cleanup_done++)
  591.     return; /* purecov: inspected */
  592.   acl_free(1);
  593.   grant_free();
  594.   sql_cache_free();
  595.   table_cache_free();
  596.   hostname_cache_free();
  597.   item_user_lock_free();
  598.   lex_free();                /* Free some memory */
  599. #ifdef HAVE_DLOPEN
  600.   if (!opt_noacl)
  601.     udf_free();
  602. #endif
  603.   end_key_cache();            /* This is usually freed automaticly */
  604.   (void) ha_panic(HA_PANIC_CLOSE);    /* close all tables and logs */
  605. #ifdef USE_RAID
  606.   end_raid();
  607. #endif
  608.   x_free((gptr) errmsg[ERRMAPP]);    /* Free messages */
  609.   free_defaults(defaults_argv);
  610.   my_free(mysql_tmpdir,MYF(0));
  611.   x_free(opt_bin_logname);
  612.   (void) my_delete(pidfile_name,MYF(0));    // This may not always exist
  613.   my_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0);
  614.  
  615.   /* Tell main we are ready */
  616.   (void) pthread_mutex_lock(&LOCK_thread_count);
  617.   ready_to_exit=1;
  618.   (void) pthread_cond_broadcast(&COND_thread_count);
  619.   (void) pthread_mutex_unlock(&LOCK_thread_count);
  620. } /* clean_up */
  621.  
  622.  
  623.  
  624. /****************************************************************************
  625. ** Init IP and UNIX socket
  626. ****************************************************************************/
  627.  
  628. static void set_ports()
  629. {
  630.   char    *env;
  631.   if (!mysql_port)
  632.   {                    // Get port if not from commandline
  633.     struct  servent *serv_ptr;
  634.     mysql_port = MYSQL_PORT;
  635.     if ((serv_ptr = getservbyname("mysql", "tcp")))
  636.       mysql_port = ntohs((u_short) serv_ptr->s_port); /* purecov: inspected */
  637.     if ((env = getenv("MYSQL_TCP_PORT")))
  638.       mysql_port = (uint) atoi(env);        /* purecov: inspected */
  639.   }
  640.   if (!mysql_unix_port)
  641.   {
  642. #ifdef __WIN__
  643.     mysql_unix_port = (char*) MYSQL_NAMEDPIPE;
  644. #else
  645.     mysql_unix_port = (char*) MYSQL_UNIX_ADDR;
  646. #endif
  647.     if ((env = getenv("MYSQL_UNIX_PORT")))
  648.       mysql_unix_port = env;            /* purecov: inspected */
  649.   }
  650. }
  651.  
  652. /* Change to run as another user if started with --user */
  653.  
  654. static void set_user(const char *user)
  655. {
  656. #ifndef __WIN__
  657.     struct passwd *ent;
  658.  
  659.   // don't bother if we aren't superuser
  660.   if (geteuid())
  661.   {
  662.     if (user)
  663.       fprintf(stderr,
  664.           "Warning: One can only use the --user switch if running as root\n");
  665.     return;
  666.   }
  667.   else if (!user)
  668.   {
  669.     if (!opt_bootstrap)
  670.     {
  671.       fprintf(stderr,"Fatal error: Please read \"Security\" section of the manual to find out how to run mysqld as root!\n");
  672.       unireg_abort(1);
  673.     }
  674.     return;
  675.   }
  676.   if (!strcmp(user,"root"))
  677.     return;                // Avoid problem with dynamic libraries
  678.  
  679.   if (!(ent = getpwnam(user)))
  680.   {
  681.     fprintf(stderr,"Fatal error: Can't change to run as user '%s' ;  Please check that the user exists!\n",user);
  682.     unireg_abort(1);
  683.   }
  684. #ifdef HAVE_INITGROUPS
  685.   initgroups((char*) user,ent->pw_gid);
  686. #endif
  687.   if (setgid(ent->pw_gid) == -1)
  688.   {
  689.     sql_perror("setgid");
  690.     unireg_abort(1);
  691.   }
  692.   if (setuid(ent->pw_uid) == -1)
  693.   {
  694.     sql_perror("setuid");
  695.     unireg_abort(1);
  696.   }
  697. #endif
  698. }
  699.  
  700. /* Change root user if started with  --chroot */
  701.  
  702. static void set_root(const char *path)
  703. {
  704. #if !defined(__WIN__) && !defined(__EMX__)
  705.   if (chroot(path) == -1)
  706.   {
  707.     sql_perror("chroot");
  708.     unireg_abort(1);
  709.   }
  710. #endif
  711. }
  712.  
  713. static void server_init(void)
  714. {
  715.   struct sockaddr_in    IPaddr;
  716. #ifdef HAVE_SYS_UN_H
  717.   struct sockaddr_un    UNIXaddr;
  718. #endif
  719.   int    arg=1;
  720.   DBUG_ENTER("server_init");
  721.  
  722. #ifdef    __WIN__
  723.   if ( !opt_disable_networking )
  724.   {
  725.     WSADATA WsaData;
  726.     if (SOCKET_ERROR == WSAStartup (0x0101, &WsaData))
  727.     {
  728.       my_message(0,"WSAStartup Failed\n",MYF(0));
  729.       unireg_abort(1);
  730.     }
  731.   }
  732. #endif /* __WIN__ */
  733.  
  734.   set_ports();
  735.  
  736.   if (mysql_port != 0 && !opt_disable_networking && !opt_bootstrap)
  737.   {
  738.     DBUG_PRINT("general",("IP Socket is %d",mysql_port));
  739.     ip_sock = socket(AF_INET, SOCK_STREAM, 0);
  740.     if (ip_sock == INVALID_SOCKET)
  741.     {
  742.       DBUG_PRINT("error",("Got error: %d from socket()",socket_errno));
  743.       sql_perror(ER(ER_IPSOCK_ERROR));        /* purecov: tested */
  744.       unireg_abort(1);                /* purecov: tested */
  745.     }
  746.     bzero((char*) &IPaddr, sizeof(IPaddr));
  747.     IPaddr.sin_family = AF_INET;
  748.     IPaddr.sin_addr.s_addr = my_bind_addr;
  749.     IPaddr.sin_port = (unsigned short) htons((unsigned short) mysql_port);
  750.     (void) setsockopt(ip_sock,SOL_SOCKET,SO_REUSEADDR,(char*)&arg,sizeof(arg));
  751.     for(;;)
  752.     {
  753.       if (bind(ip_sock, my_reinterpret_cast(struct sockaddr *) (&IPaddr),
  754.            sizeof(IPaddr)) >= 0)
  755.     break;
  756.       DBUG_PRINT("error",("Got error: %d from bind",socket_errno));
  757.       sql_perror("Can't start server: Bind on TCP/IP port");/* Had a loop here */
  758.       sql_print_error("Do you already have another mysqld server running on port: %d ?",mysql_port);
  759.       unireg_abort(1);
  760.     }
  761.     (void) listen(ip_sock,(int) back_log);
  762.   }
  763.  
  764.   if (mysqld_chroot)
  765.     set_root(mysqld_chroot);
  766.  
  767.   set_user(mysqld_user); // set_user now takes care of mysqld_user==NULL
  768.  
  769. #ifdef __NT__
  770.   /* create named pipe */
  771.   if (Service.IsNT() && mysql_unix_port[0] && !opt_bootstrap)
  772.   {
  773.     sprintf( szPipeName, "\\\\.\\pipe\\%s", mysql_unix_port );
  774.     ZeroMemory( &saPipeSecurity, sizeof(saPipeSecurity) );
  775.     ZeroMemory( &sdPipeDescriptor, sizeof(sdPipeDescriptor) );
  776.     if ( !InitializeSecurityDescriptor(&sdPipeDescriptor,
  777.                        SECURITY_DESCRIPTOR_REVISION) )
  778.     {
  779.       sql_perror("Can't start server : Initialize security descriptor");
  780.       unireg_abort(1);
  781.     }
  782.     if (!SetSecurityDescriptorDacl(&sdPipeDescriptor, TRUE, NULL, FALSE))
  783.     {
  784.       sql_perror("Can't start server : Set security descriptor");
  785.       unireg_abort(1);
  786.     }
  787.     saPipeSecurity.nLength = sizeof( SECURITY_ATTRIBUTES );
  788.     saPipeSecurity.lpSecurityDescriptor = &sdPipeDescriptor;
  789.     saPipeSecurity.bInheritHandle = FALSE;
  790.     if ((hPipe = CreateNamedPipe(szPipeName,
  791.                  PIPE_ACCESS_DUPLEX,
  792.                  PIPE_TYPE_BYTE |
  793.                  PIPE_READMODE_BYTE |
  794.                  PIPE_WAIT,
  795.                  PIPE_UNLIMITED_INSTANCES,
  796.                  (int) net_buffer_length,
  797.                  (int) net_buffer_length,
  798.                  NMPWAIT_USE_DEFAULT_WAIT,
  799.                  &saPipeSecurity )) == INVALID_HANDLE_VALUE)
  800.       {
  801.     LPVOID lpMsgBuf;
  802.     int error=GetLastError();
  803.     FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
  804.               FORMAT_MESSAGE_FROM_SYSTEM,
  805.               NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  806.               (LPTSTR) &lpMsgBuf, 0, NULL );
  807.     MessageBox( NULL, (LPTSTR) lpMsgBuf, "Error from CreateNamedPipe",
  808.             MB_OK|MB_ICONINFORMATION );
  809.     LocalFree( lpMsgBuf );
  810.     unireg_abort(1);
  811.       }
  812.   }
  813. #endif
  814.  
  815. #if defined(HAVE_SYS_UN_H)
  816.   /*
  817.   ** Create the UNIX socket
  818.   */
  819.   if (mysql_unix_port[0] && !opt_bootstrap)
  820.   {
  821.     DBUG_PRINT("general",("UNIX Socket is %s",mysql_unix_port));
  822.  
  823.     if ((unix_sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
  824.     {
  825.       sql_perror("Can't start server : UNIX Socket "); /* purecov: inspected */
  826.       unireg_abort(1);                /* purecov: inspected */
  827.     }
  828.     bzero((char*) &UNIXaddr, sizeof(UNIXaddr));
  829.     UNIXaddr.sun_family = AF_UNIX;
  830.     strmov(UNIXaddr.sun_path, mysql_unix_port);
  831.     (void) unlink(mysql_unix_port);
  832.     (void) setsockopt(unix_sock,SOL_SOCKET,SO_REUSEADDR,(char*)&arg,
  833.               sizeof(arg));
  834.     umask(0);
  835.     if (bind(unix_sock, my_reinterpret_cast(struct sockaddr *) (&UNIXaddr),
  836.          sizeof(UNIXaddr)) < 0)
  837.     {
  838.       sql_perror("Can't start server : Bind on unix socket"); /* purecov: tested */
  839.       sql_print_error("Do you already have another mysqld server running on socket: %s ?",mysql_unix_port);
  840.       unireg_abort(1);                    /* purecov: tested */
  841.     }
  842.     umask(((~my_umask) & 0666));
  843. #if defined(S_IFSOCK) && defined(SECURE_SOCKETS)
  844.     (void) chmod(mysql_unix_port,S_IFSOCK);    /* Fix solaris 2.6 bug */
  845. #endif
  846.     (void) listen(unix_sock,(int) back_log);
  847.   }
  848. #endif
  849.   DBUG_PRINT("info",("server started"));
  850.   DBUG_VOID_RETURN;
  851. }
  852.  
  853.  
  854. void yyerror(const char *s)
  855. {
  856.   NET *net=my_pthread_getspecific_ptr(NET*,THR_NET);
  857.   char *yytext=(char*) current_lex->tok_start;
  858.   if (!strcmp(s,"parse error"))
  859.     s=ER(ER_SYNTAX_ERROR);
  860.   net_printf(net,ER_PARSE_ERROR, s, yytext ? (char*) yytext : "",
  861.          current_lex->yylineno);
  862. }
  863.  
  864.  
  865. void close_connection(NET *net,uint errcode,bool lock)
  866. {
  867.   Vio* vio;
  868.   DBUG_ENTER("close_connection");
  869.   DBUG_PRINT("enter",("fd: %s  error: '%s'",
  870.                     net->vio? vio_description(net->vio):"(not connected)",
  871.                     errcode ? ER(errcode) : ""));
  872.   if (lock)
  873.     (void) pthread_mutex_lock(&LOCK_thread_count);
  874.   if ((vio=net->vio) != 0)
  875.   {
  876.     if (errcode)
  877.       send_error(net,errcode,ER(errcode));    /* purecov: inspected */
  878.     vio_close(vio);            /* vio is freed in delete thd */
  879.   }
  880.   if (lock)
  881.     (void) pthread_mutex_unlock(&LOCK_thread_count);
  882.   DBUG_VOID_RETURN;
  883. }
  884.  
  885.     /* Called when a thread is aborted */
  886.     /* ARGSUSED */
  887.  
  888. sig_handler end_thread_signal(int sig __attribute__((unused)))
  889. {
  890.   THD *thd=current_thd;
  891.   DBUG_ENTER("end_thread_signal");
  892.   if (thd)
  893.     end_thread(thd,0);
  894.   DBUG_VOID_RETURN;                /* purecov: deadcode */
  895. }
  896.  
  897.  
  898. void end_thread(THD *thd, bool put_in_cache)
  899. {
  900.   DBUG_ENTER("end_thread");
  901.   (void) pthread_mutex_lock(&LOCK_thread_count);
  902.   thread_count--;
  903.   delete thd;
  904.  
  905.   if (put_in_cache && cached_thread_count < thread_cache_size &&
  906.       ! abort_loop && !kill_cached_threads)
  907.   {
  908.     /* Don't kill the thread, just put it in cache for reuse */
  909.     DBUG_PRINT("info", ("Adding thread to cache"))
  910.     cached_thread_count++;
  911.     while (!abort_loop && ! wake_thread && ! kill_cached_threads)
  912.       (void) pthread_cond_wait(&COND_thread_cache, &LOCK_thread_count);
  913.     cached_thread_count--;
  914.     if (kill_cached_threads)
  915.       pthread_cond_signal(&COND_flush_thread_cache);
  916.     if (wake_thread)
  917.     {
  918.       wake_thread--;
  919.       thd=thread_cache.get();
  920.       thd->real_id=pthread_self();
  921.       (void) thd->store_globals();
  922.       threads.append(thd);
  923.       pthread_mutex_unlock(&LOCK_thread_count);
  924.       DBUG_VOID_RETURN;
  925.     }
  926.   }
  927.  
  928.   DBUG_PRINT("info", ("sending a broadcast"))
  929.  
  930.   /* Tell main we are ready */
  931.   (void) pthread_cond_broadcast(&COND_thread_count);
  932.   (void) pthread_mutex_unlock(&LOCK_thread_count);
  933.   DBUG_PRINT("info", ("unlocked thread_count mutex"))
  934. #ifdef ONE_THREAD
  935.   if (!(test_flags & TEST_NO_THREADS))    // For debugging under Linux
  936. #endif
  937.   {
  938.     my_thread_end();
  939.     pthread_exit(0);
  940.   }
  941.   DBUG_VOID_RETURN;
  942. }
  943.  
  944.  
  945. /* Start a cached thread. LOCK_thread_count is locked on entry */
  946.  
  947. static void start_cached_thread(THD *thd)
  948. {
  949.   thread_cache.append(thd);
  950.   wake_thread++;
  951.   thread_count++;
  952.   pthread_cond_signal(&COND_thread_cache);
  953. }
  954.  
  955.  
  956. void flush_thread_cache()
  957. {
  958.   (void) pthread_mutex_lock(&LOCK_thread_count);
  959.   kill_cached_threads++;
  960.   while (cached_thread_count)
  961.   {
  962.     pthread_cond_broadcast(&COND_thread_cache);
  963.     pthread_cond_wait(&COND_flush_thread_cache,&LOCK_thread_count);
  964.   }
  965.   kill_cached_threads--;
  966.   (void) pthread_mutex_unlock(&LOCK_thread_count);
  967. }
  968.  
  969.  
  970.     /*
  971.     ** Aborts a thread nicely. Commes here on SIGPIPE
  972.     ** TODO: One should have to fix that thr_alarm know about this
  973.     ** thread too
  974.     */
  975.  
  976. #ifdef THREAD_SPECIFIC_SIGPIPE
  977. static sig_handler abort_thread(int sig __attribute__((unused)))
  978. {
  979.   THD *thd=current_thd;
  980.   DBUG_ENTER("abort_thread");
  981.   if (thd)
  982.     thd->killed=1;
  983.   DBUG_VOID_RETURN;
  984. }
  985. #endif
  986.  
  987. /******************************************************************************
  988. ** Setup a signal thread with handles all signals
  989. ** Because linux doesn't support scemas use a mutex to check that
  990. ** the signal thread is ready before continuing
  991. ******************************************************************************/
  992.  
  993. #ifdef __WIN__
  994. static void init_signals(void)
  995. {
  996.   int signals[] = {SIGINT,SIGILL,SIGFPE,SIGSEGV,SIGTERM,SIGABRT } ;
  997.   for (uint i=0 ; i < sizeof(signals)/sizeof(int) ; i++)
  998.     signal( signals[i], kill_server) ;
  999.   signal(SIGBREAK,SIG_IGN);    //ignore SIGBREAK for NT
  1000. }
  1001.  
  1002. #elif defined(__EMX__)
  1003. static void sig_reload(int signo)
  1004. {
  1005.   reload_acl_and_cache(~0);        // Flush everything
  1006.   signal(signo, SIG_ACK);
  1007. }
  1008.  
  1009. static void sig_kill(int signo)
  1010. {
  1011.   if (!abort_loop)
  1012.   {
  1013.     abort_loop=1;                // mark abort for threads
  1014.     kill_server((void*) signo);
  1015.   }
  1016.   signal(signo, SIG_ACK);
  1017. }
  1018.  
  1019. static void init_signals(void)
  1020. {
  1021.   signal(SIGQUIT, sig_kill);
  1022.   signal(SIGKILL, sig_kill);
  1023.   signal(SIGTERM, sig_kill);
  1024.   signal(SIGINT,  sig_kill);
  1025.   signal(SIGHUP,  sig_reload);    // Flush everything
  1026.   signal(SIGALRM, SIG_IGN);
  1027.   signal(SIGBREAK,SIG_IGN);
  1028.   signal_thread = pthread_self();
  1029. }
  1030. #else
  1031.  
  1032. #ifdef HAVE_LINUXTHREADS
  1033.  
  1034. /* Produce a core for the thread */
  1035.  
  1036. static sig_handler write_core(int sig)
  1037. {
  1038.   fprintf(stderr,"Got signal %s in thread %d\n",sys_siglist[sig],getpid());
  1039.   signal(sig, SIG_DFL);
  1040.   if (fork() != 0) exit(1);            // Abort main program
  1041.   // Core will be written at exit
  1042. }
  1043. #endif
  1044.  
  1045.  
  1046. static void init_signals(void)
  1047. {
  1048.   sigset_t set;
  1049.   pthread_attr_t thr_attr;
  1050.   int error;
  1051.   DBUG_ENTER("init_signals");
  1052.  
  1053.   sigset(THR_KILL_SIGNAL,end_thread_signal);
  1054.   sigset(THR_SERVER_ALARM,print_signal_warning); // Should never be called!
  1055. #ifdef HAVE_LINUXTHREADS
  1056.   if (test_flags & TEST_CORE_ON_SIGNAL)
  1057.   {
  1058.     struct sigaction sa; sa.sa_flags = 0;
  1059.     sigemptyset(&sa.sa_mask);
  1060.     sigprocmask(SIG_SETMASK,&sa.sa_mask,NULL);
  1061.     sa.sa_handler=write_core;
  1062.     sigaction(SIGSEGV, &sa, NULL);
  1063.   }
  1064. #endif
  1065.   (void) sigemptyset(&set);
  1066. #ifdef THREAD_SPECIFIC_SIGPIPE
  1067.   sigset(SIGPIPE,abort_thread);
  1068.   sigaddset(&set,SIGPIPE);
  1069. #else
  1070.   (void) signal(SIGPIPE,SIG_IGN);        // Can't know which thread
  1071.   sigaddset(&set,SIGPIPE);
  1072. #endif
  1073.   sigaddset(&set,SIGINT);
  1074.   sigaddset(&set,SIGQUIT);
  1075.   sigaddset(&set,SIGTERM);
  1076.   sigaddset(&set,SIGHUP);
  1077.   signal(SIGTERM,SIG_DFL);            // If it's blocked by parent
  1078.   signal(SIGHUP,SIG_DFL);            // If it's blocked by parent
  1079. #ifdef SIGTSTP
  1080.   sigaddset(&set,SIGTSTP);
  1081. #endif
  1082.   sigaddset(&set,THR_SERVER_ALARM);
  1083.   sigdelset(&set,THR_KILL_SIGNAL);        // May be SIGINT
  1084.   sigdelset(&set,THR_CLIENT_ALARM);        // For alarms
  1085.   (void) pthread_sigmask(SIG_SETMASK,&set,NULL);
  1086.  
  1087.   (void) pthread_attr_init(&thr_attr);
  1088. #if !defined(HAVE_DEC_3_2_THREADS)
  1089.   pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_SYSTEM);
  1090.   (void) pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED);
  1091.   if (!(opt_specialflag & SPECIAL_NO_PRIOR))
  1092.     my_pthread_attr_setprio(&thr_attr,INTERRUPT_PRIOR);
  1093.   pthread_attr_setstacksize(&thr_attr,32768);
  1094. #endif
  1095.  
  1096.   (void) pthread_mutex_lock(&LOCK_thread_count);
  1097.   if ((error=pthread_create(&signal_thread,&thr_attr,signal_hand,0)))
  1098.   {
  1099.     sql_print_error("Can't create interrupt-thread (error %d, errno: %d)",
  1100.             error,errno);
  1101.     exit(1);
  1102.   }
  1103.   (void) pthread_cond_wait(&COND_thread_count,&LOCK_thread_count);
  1104.   pthread_mutex_unlock(&LOCK_thread_count);
  1105.  
  1106.   (void) pthread_attr_destroy(&thr_attr);
  1107.   DBUG_VOID_RETURN;
  1108. }
  1109.  
  1110.  
  1111. /*
  1112. ** This threads handles all signals and alarms
  1113. */
  1114.  
  1115. /* ARGSUSED */
  1116. static void *signal_hand(void *arg __attribute__((unused)))
  1117. {
  1118.   sigset_t set;
  1119.   int sig;
  1120.   my_thread_init();                // Init new thread
  1121.   DBUG_ENTER("signal_hand");
  1122.  
  1123.   /* Setup alarm handler */
  1124.   init_thr_alarm(max_connections+max_insert_delayed_threads);
  1125. #if SIGINT != THR_KILL_SIGNAL
  1126.   (void) sigemptyset(&set);            // Setup up SIGINT for debug
  1127.   (void) sigaddset(&set,SIGINT);        // For debugging
  1128.   (void) pthread_sigmask(SIG_UNBLOCK,&set,NULL);
  1129. #endif
  1130.   (void) sigemptyset(&set);            // Setup up SIGINT for debug
  1131. #ifdef USE_ONE_SIGNAL_HAND
  1132.   (void) sigaddset(&set,THR_SERVER_ALARM);    // For alarms
  1133. #endif
  1134.   (void) sigaddset(&set,SIGQUIT);
  1135.   (void) sigaddset(&set,SIGTERM);
  1136. #if THR_CLIENT_ALARM != SIGHUP
  1137.   (void) sigaddset(&set,SIGHUP);
  1138. #endif
  1139.   (void) sigaddset(&set,SIGTSTP);
  1140.  
  1141.   /* Save pid to this process (or thread on Linux) */
  1142.   {
  1143.     FILE    *pidFile;
  1144.     if ((pidFile = my_fopen(pidfile_name,O_WRONLY,MYF(MY_WME))))
  1145.     {
  1146.       fprintf(pidFile,"%lu",(ulong) getpid());
  1147.       (void) my_fclose(pidFile,MYF(0));
  1148.       (void) chmod(pidfile_name,0644);
  1149.     }
  1150.   }
  1151.  
  1152.   (void) pthread_mutex_lock(&LOCK_thread_count);
  1153.   (void) pthread_cond_signal(&COND_thread_count); /* continue init_signals */
  1154.   (void) pthread_mutex_unlock(&LOCK_thread_count);
  1155.  
  1156.   for (;;)
  1157.   {
  1158.     int error;                    // Used when debugging
  1159.     if (shutdown_in_progress && !abort_loop)
  1160.     {
  1161.       sig=SIGTERM;
  1162.       error=0;
  1163.     }
  1164.     else
  1165.       while ((error=my_sigwait(&set,&sig)) == EINTR) ;
  1166.     if (cleanup_done)
  1167.       pthread_exit(0);                // Safety
  1168.     switch (sig) {
  1169.     case SIGTERM:
  1170.     case SIGQUIT:
  1171.     case SIGKILL:
  1172. #ifdef EXTRA_DEBUG
  1173.       sql_print_error("Got signal %d to shutdown mysqld",sig);
  1174. #endif
  1175.       DBUG_PRINT("info",("Got signal: %d  abort_loop: %d",sig,abort_loop));
  1176.       if (!abort_loop)
  1177.       {
  1178.     abort_loop=1;                // mark abort for threads
  1179. #ifdef USE_ONE_SIGNAL_HAND
  1180.     pthread_t tmp;
  1181.     if (!(opt_specialflag & SPECIAL_NO_PRIOR))
  1182.       my_pthread_attr_setprio(&connection_attrib,INTERRUPT_PRIOR);
  1183.     if (pthread_create(&tmp,&connection_attrib, kill_server_thread,
  1184.                (void*) sig))
  1185.       sql_print_error("Error: Can't create thread to kill server");
  1186. #else
  1187.       kill_server((void*) sig);        // MIT THREAD has a alarm thread
  1188. #endif
  1189.       }
  1190.       break;
  1191.     case SIGHUP:
  1192.       reload_acl_and_cache((THD*) 0,~0, (TABLE_LIST*) 0); // Flush everything
  1193.       mysql_print_status((THD*) 0);        // Send debug some info
  1194.       break;
  1195. #ifdef USE_ONE_SIGNAL_HAND
  1196.     case THR_SERVER_ALARM:
  1197.       process_alarm(sig);            // Trigger alarms.
  1198.       break;
  1199. #endif
  1200.     default:
  1201. #ifdef EXTRA_DEBUG
  1202.       sql_print_error("Warning: Got signal: %d, error: %d",sig,error); /* purecov: tested */
  1203. #endif
  1204.       break;                    /* purecov: tested */
  1205.     }
  1206.   }
  1207.   return(0);                    /* purecov: deadcode */
  1208. }
  1209.  
  1210. #endif    /* __WIN__*/
  1211.  
  1212.  
  1213. /*
  1214. ** All global error messages are sent here where the first one is stored for
  1215. ** the client
  1216. */
  1217.  
  1218.  
  1219. /* ARGSUSED */
  1220. static int my_message_sql(uint error, const char *str,
  1221.               myf MyFlags __attribute__((unused)))
  1222. {
  1223.   NET *net;
  1224.   DBUG_ENTER("my_message_sql");
  1225.   DBUG_PRINT("error",("Message: '%s'",str));
  1226.   if ((net=my_pthread_getspecific_ptr(NET*,THR_NET)))
  1227.   {
  1228.     if (!net->last_error[0])            // Return only first message
  1229.     {
  1230.       strmake(net->last_error,str,sizeof(net->last_error)-1);
  1231.       net->last_errno=error ? error : ER_UNKNOWN_ERROR;
  1232.     }
  1233.   }
  1234.   else
  1235.     sql_print_error("%s: %s",my_progname,str); /* purecov: inspected */
  1236.   DBUG_RETURN(0);
  1237. }
  1238.  
  1239. #ifdef __WIN__
  1240. #undef errno
  1241. #undef EINTR
  1242. #define errno WSAGetLastError()
  1243. #define EINTR WSAEINTR
  1244.  
  1245. struct utsname
  1246. {
  1247.   char nodename[FN_REFLEN];
  1248. };
  1249.  
  1250. int uname(struct utsname *a)
  1251. {
  1252.   return -1;
  1253. }
  1254. #endif
  1255.  
  1256.  
  1257. #ifdef __WIN__
  1258. pthread_handler_decl(handle_shutdown,arg)
  1259. {
  1260.   MSG msg;
  1261.   my_thread_init();
  1262.  
  1263.   /* this call should create the message queue for this thread */
  1264.   PeekMessage(&msg, NULL, 1, 65534,PM_NOREMOVE);
  1265.  
  1266.   if (WaitForSingleObject(hEventShutdown,INFINITE)==WAIT_OBJECT_0)
  1267.      kill_server(MYSQL_KILL_SIGNAL);
  1268.   return 0;
  1269. }
  1270.  
  1271. int __stdcall handle_kill(ulong ctrl_type)
  1272. {
  1273.   if (ctrl_type == CTRL_CLOSE_EVENT ||
  1274.       ctrl_type == CTRL_SHUTDOWN_EVENT)
  1275.   {
  1276.     kill_server(MYSQL_KILL_SIGNAL);
  1277.     return TRUE;
  1278.   }
  1279.   return FALSE;
  1280. }
  1281. #endif
  1282.  
  1283. const char *load_default_groups[]= { "mysqld","server",0 };
  1284.  
  1285. #ifdef HAVE_LIBWRAP
  1286. char *libwrapName=NULL;
  1287. #endif
  1288.  
  1289. static void open_log(MYSQL_LOG *log, const char *hostname,
  1290.              const char *opt_name, const char *extension,
  1291.              enum_log_type type)
  1292. {
  1293.   char tmp[FN_REFLEN];
  1294.   if (!opt_name || !opt_name[0])
  1295.   {
  1296.     strnmov(tmp,hostname,FN_REFLEN-5);
  1297.     strmov(strcend(tmp,'.'),extension);
  1298.     opt_name=tmp;
  1299.   }
  1300.   log->open(opt_name,type);
  1301. }
  1302.  
  1303.  
  1304.  
  1305. #ifdef __WIN__
  1306. int win_main(int argc, char **argv)
  1307. #else
  1308. int main(int argc, char **argv)
  1309. #endif
  1310. {
  1311.   DEBUGGER_OFF;
  1312.   char hostname[FN_REFLEN];
  1313.  
  1314.   my_umask=0660;        // Default umask for new files
  1315.   my_umask_dir=0700;        // Default umask for new directories
  1316.   MY_INIT(argv[0]);        // init my_sys library & pthreads
  1317.   tzset();            // Set tzname
  1318.  
  1319.   start_time=time((time_t*) 0);
  1320. #ifdef HAVE_TZNAME
  1321. #if defined(HAVE_LOCALTIME_R) && defined(_REENTRANT)
  1322.   {
  1323.     struct tm tm_tmp;
  1324.     localtime_r(&start_time,&tm_tmp);
  1325.     strmov(time_zone,tzname[tm_tmp.tm_isdst == 1 ? 1 : 0]);
  1326.   }
  1327. #else
  1328.   {
  1329.     struct tm *start_tm;
  1330.     start_tm=localtime(&start_time);
  1331.     strmov(time_zone=tzname[start_tm->tm_isdst == 1 ? 1 : 0]);
  1332.   }
  1333. #endif
  1334. #endif
  1335.  
  1336.   if (gethostname(hostname,sizeof(hostname)-4) < 0)
  1337.     strmov(hostname,"mysql");
  1338.   strmov(pidfile_name,hostname);
  1339.   strmov(strcend(pidfile_name,'.'),".pid");    // Add extension
  1340. #ifdef DEMO_VERSION
  1341.   strcat(server_version,"-demo");
  1342. #endif
  1343. #ifdef SHAREWARE_VERSION
  1344.   strcat(server_version,"-shareware");
  1345. #endif
  1346. #ifndef DBUG_OFF
  1347.   strcat(server_version,"-debug");
  1348. #endif
  1349. #ifdef _CUSTOMSTARTUPCONFIG_
  1350.   if (_cust_check_startup())
  1351.   {
  1352.     /* _cust_check_startup will report startup failure error */
  1353.     exit( 1 );
  1354.   }
  1355. #endif
  1356.   load_defaults("my",load_default_groups,&argc,&argv);
  1357.   defaults_argv=argv;
  1358.   mysql_tmpdir=getenv("TMPDIR");    /* Use this if possible */
  1359. #ifdef __WIN__
  1360.   if (!mysql_tmpdir)
  1361.     mysql_tmpdir=getenv("TEMP");
  1362.   if (!mysql_tmpdir)
  1363.     mysql_tmpdir=getenv("TMP");
  1364. #endif
  1365.   if (!mysql_tmpdir || !mysql_tmpdir[0])
  1366.     mysql_tmpdir=(char*) P_tmpdir;        /* purecov: inspected */
  1367.  
  1368.   set_options();
  1369. #ifdef __WIN__
  1370.   /* service parameters can be overwritten by options */
  1371.   if (get_service_parameters())
  1372.   {
  1373.     my_message( 0, "Can't read MySQL service parameters", MYF(0) );
  1374.     exit( 1 );
  1375.   }
  1376. #endif
  1377.   get_options(argc,argv);
  1378.   if (opt_log || opt_update_log || opt_slow_log || opt_bin_log)
  1379.     strcat(server_version,"-log");
  1380.   DBUG_PRINT("info",("%s  Ver %s for %s on %s\n",my_progname,
  1381.              server_version, SYSTEM_TYPE,MACHINE_TYPE));
  1382.  
  1383.   /* These must be set early */
  1384.  
  1385.   (void) pthread_cond_init(&COND_thread_count,NULL);
  1386.   (void) pthread_mutex_init(&LOCK_mysql_create_db,NULL);
  1387.   (void) pthread_mutex_init(&LOCK_Acl,NULL);
  1388.   (void) pthread_mutex_init(&LOCK_grant,NULL);
  1389.   (void) pthread_mutex_init(&LOCK_open,NULL);
  1390.   (void) pthread_mutex_init(&LOCK_thread_count,NULL);
  1391.   (void) pthread_mutex_init(&LOCK_mapped_file,NULL);
  1392.   (void) pthread_mutex_init(&LOCK_status,NULL);
  1393.   (void) pthread_mutex_init(&LOCK_error_log,NULL);
  1394.   (void) pthread_mutex_init(&LOCK_delayed_insert,NULL);
  1395.   (void) pthread_mutex_init(&LOCK_delayed_status,NULL);
  1396.   (void) pthread_mutex_init(&LOCK_delayed_create,NULL);
  1397.   (void) pthread_cond_init(&COND_refresh,NULL);
  1398.   (void) pthread_cond_init(&COND_thread_cache,NULL);
  1399.   (void) pthread_cond_init(&COND_flush_thread_cache,NULL);
  1400.   (void) pthread_cond_init(&COND_flush,NULL);
  1401.   (void) pthread_mutex_init(&LOCK_flush,NULL);
  1402.   (void) pthread_mutex_init(&LOCK_crypt,NULL);
  1403.   (void) pthread_mutex_init(&LOCK_bytes_sent,NULL);
  1404.   (void) pthread_mutex_init(&LOCK_bytes_received,NULL);
  1405.   (void) pthread_mutex_init(&LOCK_timezone,NULL);
  1406.   (void) pthread_mutex_init(&LOCK_binlog_update, NULL);
  1407.   (void) pthread_mutex_init(&LOCK_slave, NULL);
  1408.   (void) pthread_mutex_init(&LOCK_server_id, NULL);
  1409.   (void) pthread_cond_init(&COND_binlog_update, NULL);
  1410.   (void) pthread_cond_init(&COND_slave_stopped, NULL);
  1411.  
  1412.   if (set_default_charset_by_name(default_charset, MYF(MY_WME)))
  1413.     unireg_abort(1);
  1414.   charsets_list = list_charsets(MYF(MY_COMPILED_SETS|MY_CONFIG_SETS));
  1415.  
  1416. #ifdef HAVE_OPENSSL
  1417.   if (opt_use_ssl)
  1418.   {
  1419.     ssl_acceptor_fd = VioSSLAcceptorFd_new(opt_ssl_key, opt_ssl_cert,
  1420.                        opt_ssl_ca, opt_ssl_capath);
  1421.     if (!ssl_acceptor_fd)
  1422.       opt_use_ssl=0;
  1423.     /* having ssl_acceptor_fd!=0 signals the use of SSL */
  1424.   }
  1425. #endif /* HAVE_OPENSSL */
  1426.  
  1427. #ifdef HAVE_LIBWRAP
  1428.   libwrapName= my_progname+dirname_length(my_progname);
  1429.   openlog(libwrapName, LOG_PID, LOG_AUTH);
  1430. #endif
  1431.  
  1432.   if (!(opt_specialflag & SPECIAL_NO_PRIOR))
  1433.     my_pthread_setprio(pthread_self(),CONNECT_PRIOR);
  1434.   /* Parameter for threads created for connections */
  1435.   (void) pthread_attr_init(&connection_attrib);
  1436.   (void) pthread_attr_setdetachstate(&connection_attrib,
  1437.                      PTHREAD_CREATE_DETACHED);
  1438.   pthread_attr_setstacksize(&connection_attrib,thread_stack);
  1439.  
  1440.   if (!(opt_specialflag & SPECIAL_NO_PRIOR))
  1441.     my_pthread_attr_setprio(&connection_attrib,WAIT_PRIOR);
  1442.   pthread_attr_setscope(&connection_attrib, PTHREAD_SCOPE_SYSTEM);
  1443.  
  1444. #ifdef SET_RLIMIT_NOFILE
  1445.   /* connections and databases neads lots of files */
  1446.   {
  1447.     uint wanted_files=10+(uint) max(max_connections*5,
  1448.                     max_connections+table_cache_size*2);
  1449.     uint files=set_maximum_open_files(wanted_files);
  1450.     if (files && files < wanted_files)        // Some systems return 0
  1451.     {
  1452.       max_connections=    (ulong) min((files-10),max_connections);
  1453.       table_cache_size= (ulong) max((files-10-max_connections)/2,64);
  1454.       DBUG_PRINT("warning",
  1455.          ("Changed limits: max_connections: %ld  table_cache: %ld",
  1456.           max_connections,table_cache_size));
  1457.       sql_print_error("Warning: Changed limits: max_connections: %ld  table_cache: %ld",max_connections,table_cache_size);
  1458.     }
  1459.   }
  1460. #endif
  1461.   unireg_init(opt_specialflag); /* Set up extern variabels */
  1462.   init_errmessage();        /* Read error messages from file */
  1463.   lex_init();
  1464.   item_init();
  1465.   mysys_uses_curses=0;
  1466. #ifdef USE_REGEX
  1467.   regex_init();
  1468. #endif
  1469.   select_thread=pthread_self();
  1470.   select_thread_in_use=1;
  1471.  
  1472.   /*
  1473.   ** We have enough space for fiddling with the argv, continue
  1474.   */
  1475.   umask(((~my_umask) & 0666));
  1476.   if (my_setwd(mysql_real_data_home,MYF(MY_WME)))
  1477.   {
  1478.     unireg_abort(1);                /* purecov: inspected */
  1479.   }
  1480.   mysql_data_home[0]=FN_CURLIB;        // all paths are relative from here
  1481.   mysql_data_home[1]=0;
  1482.   server_init();
  1483.   table_cache_init();
  1484.   hostname_cache_init();
  1485.   sql_cache_init();
  1486.   randominit(&sql_rand,(ulong) start_time,(ulong) start_time/2);
  1487.   reset_floating_point_exceptions();
  1488.   init_thr_lock();
  1489.  
  1490.   /* Setup log files */
  1491.   if (opt_log)
  1492.     open_log(&mysql_log, hostname, opt_logname, ".log", LOG_NORMAL);
  1493.   if (opt_update_log)
  1494.     open_log(&mysql_update_log, hostname, opt_update_logname, "",
  1495.          LOG_NEW);
  1496.   if (opt_bin_log)
  1497.   {
  1498.     if(server_id)
  1499.       {
  1500.     if (!opt_bin_logname)
  1501.       {
  1502.         char tmp[FN_REFLEN];
  1503.         strnmov(tmp,hostname,FN_REFLEN-5);
  1504.         strmov(strcend(tmp,'.'),"-bin");
  1505.         opt_bin_logname=my_strdup(tmp,MYF(MY_WME));
  1506.       }
  1507.     mysql_bin_log.set_index_file_name(opt_binlog_index_name);
  1508.     open_log(&mysql_bin_log, hostname, opt_bin_logname, "-bin",
  1509.          LOG_BIN);
  1510.       }
  1511.     else
  1512.       sql_print_error("Server id is not set - binary logging disabled");
  1513.   }
  1514.   
  1515.   if (opt_slow_log)
  1516.     open_log(&mysql_slow_log, hostname, opt_slow_logname, "-slow.log",
  1517.          LOG_NORMAL);
  1518.   if (ha_init())
  1519.   {
  1520.     sql_print_error("Can't init databases");
  1521.     exit(1);
  1522.   }
  1523. #if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT)
  1524.   if (locked_in_memory && !geteuid())
  1525.   {
  1526.     ha_key_cache();
  1527.     if (mlockall(MCL_CURRENT))
  1528.     {
  1529.       sql_print_error("Warning: Failed to lock memory. Errno: %d\n",errno);
  1530.     }
  1531.     else
  1532.       locked_in_memory=1;
  1533.   }
  1534. #else
  1535.   locked_in_memory=0;
  1536. #endif    
  1537.  
  1538.   if (opt_myisam_log)
  1539.     (void) mi_log( 1 );
  1540.   ft_init_stopwords(ft_precompiled_stopwords);       /* SerG */
  1541.  
  1542. #ifdef __WIN__
  1543. #define MYSQL_ERR_FILE "mysql.err"
  1544.   if (!opt_console)
  1545.   {
  1546.     freopen(MYSQL_ERR_FILE,"a+",stdout);
  1547.     freopen(MYSQL_ERR_FILE,"a+",stderr);
  1548.     FreeConsole();                // Remove window
  1549.   }
  1550. #endif
  1551.  
  1552.   /*
  1553.     init signals & alarm
  1554.     After this we can't quit by a simple unireg_abort
  1555.   */
  1556.   error_handler_hook = my_message_sql;
  1557.   if (pthread_key_create(&THR_THD,NULL) || pthread_key_create(&THR_NET,NULL) ||
  1558.       pthread_key_create(&THR_MALLOC,NULL))
  1559.   {
  1560.     sql_print_error("Can't create thread-keys");
  1561.     exit(1);
  1562.   }
  1563.   init_signals();                // Creates pidfile
  1564.   if (acl_init(opt_noacl))
  1565.   {
  1566.     select_thread_in_use=0;
  1567.     (void) pthread_kill(signal_thread,MYSQL_KILL_SIGNAL);
  1568. #ifndef __WIN__
  1569.     (void) my_delete(pidfile_name,MYF(MY_WME));        // Not neaded anymore
  1570. #endif
  1571.     exit(1);
  1572.   }
  1573.   if (!opt_noacl)
  1574.     (void) grant_init();
  1575.  
  1576. #ifdef HAVE_DLOPEN
  1577.   if (!opt_noacl)
  1578.     udf_init();
  1579. #endif
  1580.  
  1581.   if (opt_bootstrap)
  1582.   {
  1583.     int error=bootstrap(stdin);
  1584.     end_thr_alarm();                // Don't allow alarms
  1585.     unireg_abort(error ? 1 : 0);
  1586.   }
  1587.   if (opt_init_file)
  1588.   {
  1589.     if (read_init_file(opt_init_file))
  1590.     {
  1591.       end_thr_alarm();                // Don't allow alarms
  1592.       unireg_abort(1);
  1593.     }
  1594.   }
  1595.   (void) thr_setconcurrency(concurrency);    // 10 by default
  1596. #ifdef __WIN__                    //IRENA
  1597.   {
  1598.     hEventShutdown=CreateEvent(0, FALSE, FALSE, "MySqlShutdown");
  1599.     pthread_t hThread;
  1600.     if (pthread_create(&hThread,&connection_attrib,handle_shutdown,0))
  1601.       sql_print_error("Warning: Can't create thread to handle shutdown requests");
  1602.  
  1603.     // On "Stop Service" we have to do regular shutdown
  1604.     Service.SetShutdownEvent(hEventShutdown);
  1605.   }
  1606. #endif
  1607.  
  1608.   if (flush_time && flush_time != ~(ulong) 0L)
  1609.   {
  1610.     pthread_t hThread;
  1611.     if (pthread_create(&hThread,&connection_attrib,handle_flush,0))
  1612.       sql_print_error("Warning: Can't create thread to handle flush");
  1613.   }
  1614.  
  1615.   // slave thread
  1616.   if(master_host)
  1617.   {
  1618.     if(server_id)
  1619.       {
  1620.     pthread_t hThread;
  1621.     if(!opt_skip_slave_start &&
  1622.        pthread_create(&hThread, &connection_attrib, handle_slave, 0))
  1623.       sql_print_error("Warning: Can't create thread to handle slave");
  1624.     else if(opt_skip_slave_start)
  1625.       init_master_info(&glob_mi);
  1626.       }
  1627.     else
  1628.       sql_print_error("Server id is not set, slave thread will not be started");
  1629.   }
  1630.  
  1631.   printf(ER(ER_READY),my_progname,server_version,"");
  1632.   fflush(stdout);
  1633.  
  1634. #ifdef __NT__
  1635.   if (hPipe == INVALID_HANDLE_VALUE && !have_tcpip)
  1636.   {
  1637.     sql_print_error("TCP/IP must be installed on Win98 platforms");
  1638.   }
  1639.   else
  1640.   {
  1641.     pthread_mutex_lock(&LOCK_thread_count);
  1642.     (void) pthread_cond_init(&COND_handler_count,NULL);
  1643.     {
  1644.       pthread_t hThread;
  1645.       handler_count=0;
  1646.       if ( hPipe != INVALID_HANDLE_VALUE )
  1647.       {
  1648.     handler_count++;
  1649.     if (pthread_create(&hThread,&connection_attrib,
  1650.                handle_connections_namedpipes, 0))
  1651.     {
  1652.       sql_print_error("Warning: Can't create thread to handle named pipes");
  1653.       handler_count--;
  1654.     }
  1655.       }
  1656.       if (have_tcpip && !opt_disable_networking)
  1657.       {
  1658.     handler_count++;
  1659.     if (pthread_create(&hThread,&connection_attrib,
  1660.                handle_connections_sockets, 0))
  1661.     {
  1662.       sql_print_error("Warning: Can't create thread to handle named pipes");
  1663.       handler_count--;
  1664.     }
  1665.       }
  1666.       while (handler_count > 0)
  1667.       {
  1668.     pthread_cond_wait(&COND_handler_count,&LOCK_thread_count);
  1669.       }
  1670.     }
  1671.     pthread_mutex_unlock(&LOCK_thread_count);
  1672.   }
  1673. #else
  1674.   handle_connections_sockets(0);
  1675. #ifdef EXTRA_DEBUG
  1676.   sql_print_error("Exiting main thread");
  1677. #endif
  1678. #endif /* __NT__ */
  1679.  
  1680.   /* (void) pthread_attr_destroy(&connection_attrib); */
  1681.  
  1682.   DBUG_PRINT("quit",("Exiting main thread"));
  1683.  
  1684. #ifndef __WIN__
  1685. #ifdef EXTRA_DEBUG
  1686.   sql_print_error("Before Lock_thread_count");
  1687. #endif
  1688.   (void) pthread_mutex_lock(&LOCK_thread_count);
  1689.   select_thread_in_use=0;            // For close_connections
  1690.   (void) pthread_cond_broadcast(&COND_thread_count);
  1691.   (void) pthread_mutex_unlock(&LOCK_thread_count);
  1692. #ifdef EXTRA_DEBUG
  1693.   sql_print_error("After lock_thread_count");
  1694. #endif
  1695. #else
  1696.   // remove the event, because it will not be valid anymore
  1697.   Service.SetShutdownEvent(0);
  1698.   if(hEventShutdown) CloseHandle(hEventShutdown);
  1699.   // if it was started as service on NT try to stop the service
  1700.   if(Service.IsNT())
  1701.      Service.Stop();
  1702. #endif
  1703.  
  1704.   /* Wait until cleanup is done */
  1705.   (void) pthread_mutex_lock(&LOCK_thread_count);
  1706.   while (!ready_to_exit)
  1707.   {
  1708.     pthread_cond_wait(&COND_thread_count,&LOCK_thread_count);
  1709.   }
  1710.   (void) pthread_mutex_unlock(&LOCK_thread_count);
  1711. #ifndef __WIN__
  1712.   (void) my_delete(pidfile_name,MYF(0));    // Not neaded anymore
  1713. #endif
  1714.   my_thread_end();
  1715.   exit(0);
  1716.   return(0);                    /* purecov: deadcode */
  1717. }
  1718.  
  1719.  
  1720. #ifdef __WIN__
  1721. /* ------------------------------------------------------------------------
  1722.    main and thread entry function for Win32
  1723.    (all this is needed only to run mysqld as a service on WinNT)
  1724.  -------------------------------------------------------------------------- */
  1725. int mysql_service(void *p)
  1726. {
  1727.   win_main(Service.my_argc, Service.my_argv);
  1728.   return 0;
  1729. }
  1730.  
  1731. int main(int argc, char **argv)
  1732. {
  1733.   // check  environment variable OS
  1734.   if (Service.GetOS())    // "OS" defined; Should be NT
  1735.   {
  1736.     if (argc == 2)
  1737.     {
  1738.       if (!strcmp(argv[1],"-install") || !strcmp(argv[1],"--install"))
  1739.       {
  1740.     char path[FN_REFLEN];
  1741.     my_path(path, argv[0], "");           // Find name in path
  1742.     fn_format(path,argv[0],path,"",1+4+16);    // Force use of full path
  1743.     if (!Service.Install(MYSQL_SERVICENAME,MYSQL_SERVICENAME,path))
  1744.       MessageBox(NULL,"Failed to install Service",MYSQL_SERVICENAME,
  1745.              MB_OK|MB_ICONSTOP);
  1746.     return 0;
  1747.       }
  1748.       else if (!strcmp(argv[1],"-remove") || !strcmp(argv[1],"--remove"))
  1749.       {
  1750.     Service.Remove(MYSQL_SERVICENAME);
  1751.     return 0;
  1752.       }
  1753.     }
  1754.     else if (argc == 1)           // No arguments; start as a service
  1755.     {
  1756.       // init service
  1757.       long tmp=Service.Init(MYSQL_SERVICENAME,mysql_service);
  1758.       return 0;
  1759.     }
  1760.   }
  1761.  
  1762.   // This is a WIN95 machine or a start of mysqld as a standalone program
  1763.   // we have to pass the arguments, in case of NT-service this will be done
  1764.   // by ServiceMain()
  1765.  
  1766.   Service.my_argc=argc;
  1767.   Service.my_argv=argv;
  1768.   mysql_service(NULL);
  1769.   return 0;
  1770. }
  1771. /* ------------------------------------------------------------------------ */
  1772. #endif
  1773.  
  1774.  
  1775. static int bootstrap(FILE *file)
  1776. {
  1777.   THD *thd= new THD;
  1778.   int error;
  1779.   thd->bootstrap=1;
  1780.   thd->client_capabilities=0;
  1781.   my_net_init(&thd->net,(Vio*) 0);
  1782.   thd->max_packet_length=thd->net.max_packet;
  1783.   thd->master_access= ~0;
  1784.   thread_count++;
  1785.   thd->real_id=pthread_self();
  1786.   error=handle_bootstrap(thd,file);
  1787.   net_end(&thd->net);
  1788.   delete thd;
  1789.   return error;
  1790. }
  1791.  
  1792. static bool read_init_file(char *file_name)
  1793. {
  1794.   FILE *file;
  1795.   DBUG_ENTER("read_init_file");
  1796.   DBUG_PRINT("enter",("name: %s",file_name));
  1797.   if (!(file=my_fopen(file_name,O_RDONLY,MYF(MY_WME))))
  1798.     return(1);
  1799.   bootstrap(file);                /* Ignore errors from this */
  1800.   (void) my_fclose(file,MYF(MY_WME));
  1801.   return 0;
  1802. }
  1803.  
  1804.  
  1805. static void create_new_thread(THD *thd)
  1806. {
  1807.   DBUG_ENTER("create_new_thread");
  1808.  
  1809.   NET *net=&thd->net;                // For easy ref
  1810.   net->timeout = (uint) connect_timeout;    // Timeout for read
  1811.   if (protocol_version > 9)
  1812.     net->return_errno=1;
  1813.  
  1814.   /* don't allow too many connections */
  1815.   if (thread_count - delayed_insert_threads >= max_connections+1 || abort_loop)
  1816.   {
  1817.     DBUG_PRINT("error",("too many connections"));
  1818.     close_connection(net,ER_CON_COUNT_ERROR);
  1819.     delete thd;
  1820.     DBUG_VOID_RETURN;
  1821.   }
  1822.   if (pthread_mutex_lock(&LOCK_thread_count))
  1823.   {
  1824.     DBUG_PRINT("error",("Can't lock LOCK_thread_count"));
  1825.     close_connection(net,ER_OUT_OF_RESOURCES);
  1826.     delete thd;
  1827.     DBUG_VOID_RETURN;
  1828.   }
  1829.   if (thread_count-delayed_insert_threads > max_used_connections)
  1830.     max_used_connections=thread_count-delayed_insert_threads;
  1831.   thd->thread_id=thread_id++;
  1832.   for (uint i=0; i < 8 ; i++)            // Generate password teststring
  1833.     thd->scramble[i]= (char) (rnd(&sql_rand)*94+33);
  1834.   thd->scramble[8]=0;
  1835.   thd->rand=sql_rand;
  1836.   thd->real_id=pthread_self();            // Keep purify happy
  1837.  
  1838.   /* Start a new thread to handle connection */
  1839. #ifdef ONE_THREAD
  1840.   if (test_flags & TEST_NO_THREADS)        // For debugging under Linux
  1841.   {
  1842.     thread_cache_size=0;            // Safety
  1843.     thread_count++;
  1844.     threads.append(thd);
  1845.     thd->real_id=pthread_self();
  1846.     (void) pthread_mutex_unlock(&LOCK_thread_count);
  1847.     handle_one_connection((void*) thd);
  1848.   }
  1849.   else
  1850. #endif
  1851.   {
  1852.     if (cached_thread_count > wake_thread)
  1853.     {
  1854.       start_cached_thread(thd);
  1855.       (void) pthread_mutex_unlock(&LOCK_thread_count);
  1856.     }
  1857.     else
  1858.     {
  1859.       int error;
  1860.       thread_count++;
  1861.       threads.append(thd);
  1862.       DBUG_PRINT("info",(("creating thread %d"), thd->thread_id));
  1863.       thd->connect_time = time(NULL);
  1864.       (void) pthread_mutex_unlock(&LOCK_thread_count);
  1865.       if ((error=pthread_create(&thd->real_id,&connection_attrib,
  1866.                 handle_one_connection,
  1867.                 (void*) thd)))
  1868.       {
  1869.     DBUG_PRINT("error",
  1870.            ("Can't create thread to handle request (error %d)",
  1871.             error));
  1872.     (void) pthread_mutex_lock(&LOCK_thread_count);
  1873.     thread_count--;
  1874.     thd->killed=1;                // Safety
  1875.     (void) pthread_mutex_unlock(&LOCK_thread_count);
  1876.     net_printf(net,ER_CANT_CREATE_THREAD,error);
  1877.     (void) pthread_mutex_lock(&LOCK_thread_count);
  1878.     close_connection(net,0,0);
  1879.     delete thd;
  1880.     (void) pthread_mutex_unlock(&LOCK_thread_count);
  1881.     DBUG_VOID_RETURN;
  1882.       }
  1883.     }
  1884.   }
  1885.   DBUG_PRINT("info",(("Thread %d created"), thd->thread_id));
  1886.   DBUG_VOID_RETURN;
  1887. }
  1888.  
  1889.  
  1890.     /* Handle new connections and spawn new process to handle them */
  1891.  
  1892. pthread_handler_decl(handle_connections_sockets,arg __attribute__((unused)))
  1893. {
  1894.   my_socket sock,new_sock;
  1895.   uint error_count=0;
  1896.   uint max_used_connection= (uint) (max(ip_sock,unix_sock)+1);
  1897.   fd_set readFDs,clientFDs;
  1898.   THD *thd;
  1899.   struct sockaddr_in cAddr;
  1900.   int ip_flags=0,socket_flags=0,flags;
  1901.   Vio *vio_tmp;
  1902.   DBUG_ENTER("handle_connections_sockets");
  1903.  
  1904.   LINT_INIT(new_sock);
  1905.  
  1906.   (void) my_pthread_getprio(pthread_self());        // For debugging
  1907.  
  1908.   FD_ZERO(&clientFDs);
  1909.   if (ip_sock != INVALID_SOCKET)
  1910.   {
  1911.     FD_SET(ip_sock,&clientFDs);
  1912. #ifdef HAVE_FCNTL
  1913.     ip_flags = fcntl(ip_sock, F_GETFL, 0);
  1914. #endif
  1915.   }
  1916. #ifdef HAVE_SYS_UN_H
  1917.   FD_SET(unix_sock,&clientFDs);
  1918.   socket_flags=fcntl(unix_sock, F_GETFL, 0);
  1919. #endif
  1920.  
  1921.   DBUG_PRINT("general",("Waiting for connections."));
  1922.   while (!abort_loop)
  1923.   {
  1924.     readFDs=clientFDs;
  1925. #ifdef HPUX
  1926.     if (select(max_used_connection,(int*) &readFDs,0,0,0) < 0)
  1927.       continue;
  1928. #else
  1929.     if (select((int) max_used_connection,&readFDs,0,0,0) < 0)
  1930.     {
  1931.       if (errno != EINTR)
  1932.       {
  1933.     if (!select_errors++ && !abort_loop)    /* purecov: inspected */
  1934.       sql_print_error("mysqld: Got error %d from select",errno); /* purecov: inspected */
  1935.       }
  1936.       continue;
  1937.     }
  1938. #endif    /* HPUX */
  1939.     if (abort_loop)
  1940.       break;
  1941.  
  1942.     /*
  1943.     ** Is this a new connection request
  1944.     */
  1945.  
  1946. #ifdef HAVE_SYS_UN_H
  1947.     if (FD_ISSET(unix_sock,&readFDs))
  1948.     {
  1949.       sock = unix_sock;
  1950.       flags= socket_flags;
  1951.     }
  1952.     else
  1953. #endif
  1954.     {
  1955.       sock = ip_sock;
  1956.       flags= ip_flags;
  1957.     }
  1958.  
  1959. #if !defined(NO_FCNTL_NONBLOCK)
  1960.     if (!(test_flags & TEST_BLOCKING))
  1961.     {
  1962. #if defined(O_NONBLOCK)
  1963.       fcntl(sock, F_SETFL, flags | O_NONBLOCK);
  1964. #elif defined(O_NDELAY)
  1965.       fcntl(sock, F_SETFL, flags | O_NDELAY);
  1966. #endif
  1967.     }
  1968. #endif /* NO_FCNTL_NONBLOCK */
  1969.     for (uint retry=0; retry < MAX_ACCEPT_RETRY; retry++)
  1970.     {
  1971.       size_socket length=sizeof(struct sockaddr_in);
  1972.       new_sock = accept(sock, my_reinterpret_cast(struct sockaddr *) (&cAddr),
  1973.             &length);
  1974.       if (new_sock != INVALID_SOCKET || (errno != EINTR && errno != EAGAIN))
  1975.     break;
  1976. #if !defined(NO_FCNTL_NONBLOCK)
  1977.       if (!(test_flags & TEST_BLOCKING))
  1978.       {
  1979.     if (retry == MAX_ACCEPT_RETRY - 1)
  1980.       fcntl(sock, F_SETFL, flags);        // Try without O_NONBLOCK
  1981.       }
  1982. #endif
  1983.     }
  1984. #if !defined(NO_FCNTL_NONBLOCK)
  1985.     if (!(test_flags & TEST_BLOCKING))
  1986.       fcntl(sock, F_SETFL, flags);
  1987. #endif
  1988.     if (new_sock < 0)
  1989.     {
  1990.       if ((error_count++ & 255) == 0)        // This can happen often
  1991.     sql_perror("Error in accept");
  1992.       if (errno == ENFILE || errno == EMFILE)
  1993.     sleep(1);                // Give other threads some time
  1994.       continue;
  1995.     }
  1996.  
  1997. #ifdef HAVE_LIBWRAP
  1998.     {
  1999.       if (sock == ip_sock)
  2000.       {
  2001.     struct request_info req;
  2002.     signal(SIGCHLD, SIG_DFL);
  2003.     request_init(&req, RQ_DAEMON, libwrapName, RQ_FILE, new_sock, NULL);
  2004.     fromhost(&req);
  2005.     if (!hosts_access(&req))
  2006.     {
  2007.       // This may be stupid but refuse() includes an exit(0)
  2008.       // which we surely don't want...
  2009.       // clean_exit() - same stupid thing ...
  2010.       syslog(deny_severity, "refused connect from %s", eval_client(&req));
  2011.       if (req.sink)
  2012.         ((void (*)(int))req.sink)(req.fd);
  2013.  
  2014.       // C++ sucks (the gibberish in front just translates the supplied
  2015.       // sink function pointer in the req structure from a void (*sink)();
  2016.       // to a void(*sink)(int) if you omit the cast, the C++ compiler
  2017.       // will cry...
  2018.  
  2019.       (void) shutdown(new_sock,2);  // This looks fine to me...
  2020.       (void) closesocket(new_sock);
  2021.       continue;
  2022.     }
  2023.       }
  2024.     }
  2025. #endif /* HAVE_LIBWRAP */
  2026.  
  2027.     {
  2028.       size_socket dummyLen;
  2029.       struct sockaddr dummy;
  2030.       dummyLen = sizeof(struct sockaddr);
  2031.       if (getsockname(new_sock,&dummy, &dummyLen) < 0)
  2032.       {
  2033.     sql_perror("Error on new connection socket");
  2034.     (void) shutdown(new_sock,2);
  2035.     (void) closesocket(new_sock);
  2036.     continue;
  2037.       }
  2038.     }
  2039.  
  2040.     /*
  2041.     ** Don't allow too many connections
  2042.     */
  2043.  
  2044.     if (!(thd= new THD))
  2045.     {
  2046.       (void) shutdown(new_sock,2); VOID(closesocket(new_sock));
  2047.       continue;
  2048.     }
  2049.     if (!(vio_tmp=vio_new(new_sock,
  2050.               sock == unix_sock ? VIO_TYPE_SOCKET :
  2051.               VIO_TYPE_TCPIP,
  2052.               sock == unix_sock)) ||
  2053.     my_net_init(&thd->net,vio_tmp))
  2054.     {
  2055.       if (vio_tmp)
  2056.     vio_delete(vio_tmp);
  2057.       else
  2058.       {
  2059.     (void) shutdown(new_sock,2);
  2060.     (void) closesocket(new_sock);
  2061.       }
  2062.       delete thd;
  2063.       continue;
  2064.     }
  2065.     if (sock == unix_sock)
  2066.       thd->host=(char*) localhost;
  2067.     create_new_thread(thd);
  2068.   }
  2069.  
  2070. #ifdef __NT__
  2071.   pthread_mutex_lock(&LOCK_thread_count);
  2072.   handler_count--;
  2073.   pthread_cond_signal(&COND_handler_count);
  2074.   pthread_mutex_unlock(&LOCK_thread_count);
  2075. #endif
  2076.   DBUG_RETURN(0);
  2077. }
  2078.  
  2079.  
  2080. #ifdef __NT__
  2081. pthread_handler_decl(handle_connections_namedpipes,arg)
  2082. {
  2083.   HANDLE hConnectedPipe;
  2084.   BOOL fConnected;
  2085.   THD *thd;
  2086.   my_thread_init();
  2087.   DBUG_ENTER("handle_connections_namedpipes");
  2088.   (void) my_pthread_getprio(pthread_self());        // For debugging
  2089.  
  2090.   DBUG_PRINT("general",("Waiting for named pipe connections."));
  2091.   while (!abort_loop)
  2092.   {
  2093.     /* wait for named pipe connection */
  2094.     fConnected = ConnectNamedPipe( hPipe, NULL );
  2095.     if (abort_loop)
  2096.       break;
  2097.     if ( !fConnected )
  2098.       fConnected = GetLastError() == ERROR_PIPE_CONNECTED;
  2099.     if ( !fConnected )
  2100.     {
  2101.       CloseHandle( hPipe );
  2102.       if ((hPipe = CreateNamedPipe(szPipeName,
  2103.                    PIPE_ACCESS_DUPLEX,
  2104.                    PIPE_TYPE_BYTE |
  2105.                    PIPE_READMODE_BYTE |
  2106.                    PIPE_WAIT,
  2107.                    PIPE_UNLIMITED_INSTANCES,
  2108.                    (int) net_buffer_length,
  2109.                    (int) net_buffer_length,
  2110.                    NMPWAIT_USE_DEFAULT_WAIT,
  2111.                    &saPipeSecurity )) ==
  2112.       INVALID_HANDLE_VALUE )
  2113.       {
  2114.     sql_perror("Can't create new named pipe!");
  2115.     break;                    // Abort
  2116.       }
  2117.     }
  2118.     hConnectedPipe = hPipe;
  2119.     /* create new pipe for new connection */
  2120.     if ((hPipe = CreateNamedPipe(szPipeName,
  2121.                  PIPE_ACCESS_DUPLEX,
  2122.                  PIPE_TYPE_BYTE |
  2123.                  PIPE_READMODE_BYTE |
  2124.                  PIPE_WAIT,
  2125.                  PIPE_UNLIMITED_INSTANCES,
  2126.                  (int) net_buffer_length,
  2127.                  (int) net_buffer_length,
  2128.                  NMPWAIT_USE_DEFAULT_WAIT,
  2129.                  &saPipeSecurity)) ==
  2130.     INVALID_HANDLE_VALUE)
  2131.     {
  2132.       sql_perror("Can't create new named pipe!");
  2133.       hPipe=hConnectedPipe;
  2134.       continue;                    // We have to try again
  2135.     }
  2136.  
  2137.     if ( !(thd = new THD))
  2138.     {
  2139.       DisconnectNamedPipe( hConnectedPipe );
  2140.       CloseHandle( hConnectedPipe );
  2141.       continue;
  2142.     }
  2143.     if (!(thd->net.vio = vio_new_win32pipe(hConnectedPipe)) ||
  2144.     my_net_init(&thd->net, thd->net.vio))
  2145.     {
  2146.       close_connection(&thd->net,ER_OUT_OF_RESOURCES);
  2147.       delete thd;
  2148.       continue;
  2149.     }
  2150.     /* host name is unknown */
  2151.     thd->host = my_strdup("localhost",MYF(0)); /* Host is unknown */
  2152.     create_new_thread(thd);
  2153.   }
  2154.  
  2155.   pthread_mutex_lock(&LOCK_thread_count);
  2156.   handler_count--;
  2157.   pthread_cond_signal(&COND_handler_count);
  2158.   pthread_mutex_unlock(&LOCK_thread_count);
  2159.   DBUG_RETURN(0);
  2160. }
  2161. #endif /* __NT__ */
  2162.  
  2163. /****************************************************************************
  2164. **  Create thread that automaticly flush all tables after a given time
  2165. ****************************************************************************/
  2166.  
  2167. pthread_handler_decl(handle_flush,arg __attribute__((unused)))
  2168. {
  2169.   my_thread_init();
  2170.   DBUG_ENTER("handle_flush");
  2171.  
  2172.   pthread_detach_this_thread();
  2173.   flush_thread=pthread_self();
  2174.   flush_thread_in_use=1;
  2175.  
  2176.   pthread_mutex_lock(&LOCK_flush);
  2177.   while (flush_time)
  2178.   {
  2179.     struct timespec abstime;
  2180. #ifdef HAVE_TIMESPEC_TS_SEC
  2181.     abstime.ts_sec=time(NULL)+flush_time;    // Bsd 2.1
  2182.     abstime.ts_nsec=0;
  2183. #else
  2184.     abstime.tv_sec=time(NULL)+flush_time;    // Linux or Solairs
  2185.     abstime.tv_nsec=0;
  2186. #endif
  2187.     (void) pthread_cond_timedwait(&COND_flush,&LOCK_flush, &abstime);
  2188.     if (abort_loop)
  2189.       break;
  2190.     flush_tables();
  2191.   }
  2192.   flush_thread_in_use=0;
  2193.   pthread_mutex_unlock(&LOCK_flush);
  2194.   my_thread_end();
  2195.   DBUG_RETURN(0);
  2196. }
  2197.  
  2198.  
  2199. /******************************************************************************
  2200. ** handle start options
  2201. ******************************************************************************/
  2202.  
  2203. enum options {
  2204.                OPT_ISAM_LOG=256,         OPT_SKIP_NEW, 
  2205.                OPT_SKIP_GRANT,           OPT_SKIP_LOCK, 
  2206.                OPT_ENABLE_LOCK,          OPT_USE_LOCKING,
  2207.                OPT_SOCKET,               OPT_UPDATE_LOG, 
  2208.                OPT_BIN_LOG,              OPT_SKIP_RESOLVE, 
  2209.                OPT_SKIP_NETWORKING,      OPT_BIN_LOG_INDEX,
  2210.                OPT_BIND_ADDRESS,         OPT_PID_FILE,
  2211.                OPT_SKIP_PRIOR,           OPT_BIG_TABLES,    
  2212.                OPT_STANDALONE,           OPT_ONE_THREAD,
  2213.                OPT_CONSOLE,              OPT_LOW_PRIORITY_UPDATES,
  2214.                OPT_SKIP_HOST_CACHE,      OPT_LONG_FORMAT,   
  2215.                OPT_FLUSH,                OPT_SAFE, 
  2216.                OPT_BOOTSTRAP,            OPT_SKIP_SHOW_DB,
  2217.                OPT_TABLE_TYPE,           OPT_INIT_FILE,   
  2218.                OPT_DELAY_KEY_WRITE,      OPT_SLOW_QUERY_LOG, 
  2219.                OPT_SKIP_DELAY_KEY_WRITE, OPT_CHARSETS_DIR,
  2220.                OPT_BDB_HOME,             OPT_BDB_LOG,  
  2221.                OPT_BDB_TMP,              OPT_BDB_NOSYNC,
  2222.                OPT_BDB_LOCK,             OPT_BDB_SKIP, 
  2223.                OPT_BDB_RECOVER,          OPT_MASTER_HOST,  
  2224.                OPT_MASTER_USER,          OPT_MASTER_PASSWORD,
  2225.                OPT_MASTER_PORT,          OPT_MASTER_INFO_FILE,
  2226.                OPT_MASTER_CONNECT_RETRY, OPT_SQL_BIN_UPDATE_SAME,
  2227.                OPT_REPLICATE_DO_DB,      OPT_REPLICATE_IGNORE_DB, 
  2228.                OPT_LOG_SLAVE_UPDATES,    OPT_BINLOG_DO_DB, 
  2229.                OPT_BINLOG_IGNORE_DB,     OPT_WANT_CORE,
  2230.            OPT_SKIP_CONCURRENT_INSERT, OPT_MEMLOCK, OPT_MYISAM_RECOVER,
  2231.            OPT_REPLICATE_REWRITE_DB, OPT_SERVER_ID, OPT_SKIP_SLAVE_START,
  2232.            OPT_SKIP_INNOBASE,OPT_SAFEMALLOC_MEM_LIMIT,
  2233.            OPT_REPLICATE_DO_TABLE, OPT_REPLICATE_IGNORE_TABLE,
  2234.            OPT_REPLICATE_WILD_DO_TABLE, OPT_REPLICATE_WILD_IGNORE_TABLE,
  2235.            OPT_DISCONNECT_SLAVE_EVENT_COUNT
  2236. };
  2237.  
  2238. static struct option long_options[] = {
  2239.   {"ansi",                  no_argument,       0, 'a'},
  2240.   {"basedir",               required_argument, 0, 'b'},
  2241. #ifdef HAVE_BERKELEY_DB
  2242.   {"bdb-home",              required_argument, 0, (int) OPT_BDB_HOME},
  2243.   {"bdb-lock-detect",       required_argument, 0, (int) OPT_BDB_LOCK},
  2244.   {"bdb-logdir",            required_argument, 0, (int) OPT_BDB_LOG},
  2245.   {"bdb-recover",           no_argument,       0, (int) OPT_BDB_RECOVER},
  2246.   {"bdb-no-sync",           no_argument,       0, (int) OPT_BDB_NOSYNC},
  2247.   {"bdb-tmpdir",            required_argument, 0, (int) OPT_BDB_TMP},
  2248. #endif
  2249.   {"big-tables",            no_argument,       0, (int) OPT_BIG_TABLES},
  2250.   {"binlog-do-db",          required_argument, 0, (int) OPT_BINLOG_DO_DB},
  2251.   {"binlog-ignore-db",      required_argument, 0, (int) OPT_BINLOG_IGNORE_DB},
  2252.   {"bind-address",          required_argument, 0, (int) OPT_BIND_ADDRESS},
  2253.   {"bootstrap",             no_argument,       0, (int) OPT_BOOTSTRAP},
  2254. #ifdef __WIN__
  2255.   {"console",               no_argument,       0, (int) OPT_CONSOLE},
  2256. #endif
  2257.   {"core-file",             no_argument,       0, (int) OPT_WANT_CORE},
  2258.   {"chroot",                required_argument, 0, 'r'},
  2259.   {"character-sets-dir",    required_argument, 0, (int) OPT_CHARSETS_DIR},
  2260.   {"datadir",               required_argument, 0, 'h'},
  2261. #ifndef DBUG_OFF
  2262.   {"debug",                 optional_argument, 0, '#'},
  2263. #endif
  2264.   {"default-character-set", required_argument, 0, 'C'},
  2265.   {"default-table-type",    required_argument, 0, (int) OPT_TABLE_TYPE},
  2266.   {"delay-key-write-for-all-tables",
  2267.                             no_argument,       0, (int) OPT_DELAY_KEY_WRITE},
  2268.   {"enable-locking",        no_argument,       0, (int) OPT_ENABLE_LOCK},
  2269.   {"exit-info",             optional_argument, 0, 'T'},
  2270.   {"flush",                 no_argument,       0, (int) OPT_FLUSH},
  2271.   {"help",                  no_argument,       0, '?'},
  2272.   {"init-file",             required_argument, 0, (int) OPT_INIT_FILE},
  2273.   {"log",                   optional_argument, 0, 'l'},
  2274.   {"language",              required_argument, 0, 'L'},
  2275.   {"log-bin",               optional_argument, 0, (int) OPT_BIN_LOG},
  2276.   {"log-bin-index",         required_argument, 0, (int) OPT_BIN_LOG_INDEX},
  2277.   {"log-isam",              optional_argument, 0, (int) OPT_ISAM_LOG},
  2278.   {"log-update",            optional_argument, 0, (int) OPT_UPDATE_LOG},
  2279.   {"log-slow-queries",      optional_argument, 0, (int) OPT_SLOW_QUERY_LOG},
  2280.   {"log-long-format",       no_argument,       0, (int) OPT_LONG_FORMAT},
  2281.   {"log-slave-updates",     no_argument,       0, (int) OPT_LOG_SLAVE_UPDATES},
  2282.   {"low-priority-updates",  no_argument,       0, (int) OPT_LOW_PRIORITY_UPDATES},
  2283.   {"master-host",           required_argument, 0, (int) OPT_MASTER_HOST},
  2284.   {"master-user",           required_argument, 0, (int) OPT_MASTER_USER},
  2285.   {"master-password",       required_argument, 0, (int) OPT_MASTER_PASSWORD},
  2286.   {"master-port",           required_argument, 0, (int) OPT_MASTER_PORT},
  2287.   {"master-connect-retry",  required_argument, 0, (int) OPT_MASTER_CONNECT_RETRY},
  2288.   {"master-info-file",      required_argument, 0, (int) OPT_MASTER_INFO_FILE},
  2289.   {"myisam-recover",        optional_argument, 0, (int) OPT_MYISAM_RECOVER},
  2290.   {"memlock",            no_argument,       0, (int) OPT_MEMLOCK},
  2291.     // needs to be available for the test case to pass in non-debugging mode
  2292.     // is a no-op
  2293.   {"disconnect-slave-event-count",      required_argument, 0,
  2294.      (int) OPT_DISCONNECT_SLAVE_EVENT_COUNT},
  2295. #if !defined(DBUG_OFF) && defined(SAFEMALLOC)
  2296.   {"safemalloc-mem-limit",  required_argument, 0, (int)
  2297.      OPT_SAFEMALLOC_MEM_LIMIT},
  2298. #endif    
  2299.   {"new",                   no_argument,       0, 'n'},
  2300.   {"old-protocol",          no_argument,       0, 'o'},
  2301. #ifdef ONE_THREAD
  2302.   {"one-thread",            no_argument,       0, (int) OPT_ONE_THREAD},
  2303. #endif
  2304.   {"pid-file",              required_argument, 0, (int) OPT_PID_FILE},
  2305.   {"port",                  required_argument, 0, 'P'},
  2306.   {"replicate-do-db",       required_argument, 0, (int) OPT_REPLICATE_DO_DB},
  2307.   {"replicate-do-table",       required_argument, 0,
  2308.    (int) OPT_REPLICATE_DO_TABLE},
  2309.   {"replicate-wild-do-table",       required_argument, 0,
  2310.    (int) OPT_REPLICATE_WILD_DO_TABLE},
  2311.   {"replicate-ignore-db",   required_argument, 0,
  2312.    (int) OPT_REPLICATE_IGNORE_DB},
  2313.   {"replicate-ignore-table",   required_argument, 0,
  2314.    (int) OPT_REPLICATE_IGNORE_TABLE},
  2315.   {"replicate-wild-ignore-table",   required_argument, 0,
  2316.    (int) OPT_REPLICATE_WILD_IGNORE_TABLE},
  2317.   {"replicate-rewrite-db",   required_argument, 0,
  2318.      (int) OPT_REPLICATE_REWRITE_DB},
  2319.   {"safe-mode",             no_argument,       0, (int) OPT_SAFE},
  2320.   {"socket",                required_argument, 0, (int) OPT_SOCKET},
  2321.   {"server-id",            required_argument, 0, (int)OPT_SERVER_ID},
  2322.   {"set-variable",          required_argument, 0, 'O'},
  2323. #ifdef HAVE_BERKELEY_DB
  2324.   {"skip-bdb",              no_argument,       0, (int) OPT_BDB_SKIP},
  2325. #endif
  2326. #ifdef HAVE_INNOBASE_DB
  2327.   {"skip-innobase",         no_argument,       0, (int) OPT_INNOBASE_SKIP},
  2328. #endif
  2329.   {"skip-concurrent-insert", no_argument,      0, (int) OPT_SKIP_CONCURRENT_INSERT},
  2330.   {"skip-delay-key-write",  no_argument,       0, (int) OPT_SKIP_DELAY_KEY_WRITE},
  2331.   {"skip-grant-tables",     no_argument,       0, (int) OPT_SKIP_GRANT},
  2332.   {"skip-locking",          no_argument,       0, (int) OPT_SKIP_LOCK},
  2333.   {"skip-host-cache",       no_argument,       0, (int) OPT_SKIP_HOST_CACHE},
  2334.   {"skip-name-resolve",     no_argument,       0, (int) OPT_SKIP_RESOLVE},
  2335.   {"skip-new",              no_argument,       0, (int) OPT_SKIP_NEW},
  2336.   {"skip-show-database",    no_argument,       0, (int) OPT_SKIP_SHOW_DB},
  2337.   {"skip-slave-start",    no_argument,       0, (int) OPT_SKIP_SLAVE_START},
  2338.   {"skip-networking",       no_argument,       0, (int) OPT_SKIP_NETWORKING},
  2339.   {"skip-thread-priority",  no_argument,       0, (int) OPT_SKIP_PRIOR},
  2340.   {"sql-bin-update-same",   no_argument,       0, (int) OPT_SQL_BIN_UPDATE_SAME},
  2341. #include "sslopt-longopts.h"
  2342. #ifdef __WIN__
  2343.   {"standalone",            no_argument,       0, (int) OPT_STANDALONE},
  2344. #endif
  2345.   {"tmpdir",                required_argument, 0, 't'},
  2346.   {"use-locking",           no_argument,       0, (int) OPT_USE_LOCKING},
  2347. #ifdef USE_SYMDIR
  2348.   {"use-symbolic-links",    no_argument,       0, 's'},
  2349. #endif
  2350.   {"user",                  required_argument, 0, 'u'},
  2351.   {"version",               no_argument,       0, 'V'},
  2352.   {0, 0, 0, 0}
  2353. };
  2354.  
  2355. CHANGEABLE_VAR changeable_vars[] = {
  2356.   { "back_log",                (long*) &back_log, 
  2357.       50, 1, 65535, 0, 1 },
  2358. #ifdef HAVE_BERKELEY_DB
  2359.   { "bdb_cache_size",          (long*) &berkeley_cache_size, 
  2360.       KEY_CACHE_SIZE, 20*1024, (long) ~0, 0, IO_SIZE },
  2361.   { "bdb_lock_max",            (long*) &berkeley_lock_max, 
  2362.       1000, 0, (long) ~0, 0, 1 },
  2363. #endif
  2364.   { "connect_timeout",         (long*) &connect_timeout,
  2365.       CONNECT_TIMEOUT, 2, 65535, 0, 1 },
  2366.   { "delayed_insert_timeout", (long*) &delayed_insert_timeout, 
  2367.       DELAYED_WAIT_TIMEOUT, 1, ~0L, 0, 1 },
  2368.   { "delayed_insert_limit",    (long*) &delayed_insert_limit, 
  2369.       DELAYED_LIMIT, 1, ~0L, 0, 1 },
  2370.   { "delayed_queue_size",      (long*) &delayed_queue_size,
  2371.       DELAYED_QUEUE_SIZE, 1, ~0L, 0, 1 },
  2372.   { "flush_time",              (long*) &flush_time,
  2373.       FLUSH_TIME, 0, ~0L, 0, 1 },
  2374.   { "interactive_timeout",     (long*) &net_interactive_timeout,
  2375.       NET_WAIT_TIMEOUT, 1, 31*24*60*60, 0, 1 },
  2376.   { "join_buffer_size",        (long*) &join_buff_size,
  2377.       128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, ~0L, MALLOC_OVERHEAD, IO_SIZE },
  2378.   { "key_buffer_size",         (long*) &keybuff_size,
  2379.       KEY_CACHE_SIZE, MALLOC_OVERHEAD, (long) ~0, MALLOC_OVERHEAD, IO_SIZE },
  2380.   { "long_query_time",         (long*) &long_query_time,
  2381.       10, 1, ~0L, 0, 1 },
  2382.   { "lower_case_table_names",  (long*) &lower_case_table_names,
  2383.       IF_WIN(1,0), 0, 1, 0, 1 },
  2384.   { "max_allowed_packet",      (long*) &max_allowed_packet,
  2385.       1024*1024L, 80, 17*1024*1024L, MALLOC_OVERHEAD, 1024 },
  2386.   { "max_connections",         (long*) &max_connections,
  2387.       100, 1, 16384, 0, 1 },
  2388.   { "max_connect_errors",      (long*) &max_connect_errors,
  2389.       MAX_CONNECT_ERRORS, 1, ~0L, 0, 1 },
  2390.   { "max_delayed_threads",     (long*) &max_insert_delayed_threads,
  2391.       20, 1, 16384, 0, 1 },
  2392.   { "max_heap_table_size",     (long*) &max_heap_table_size,
  2393.       16*1024*1024L, 16384, ~0L, MALLOC_OVERHEAD, 1024 },
  2394.   { "max_join_size",           (long*) &max_join_size,
  2395.       ~0L, 1, ~0L, 0, 1 },
  2396.   { "max_sort_length",         (long*) &max_item_sort_length,
  2397.       1024, 4, 8192*1024L, 0, 1 },
  2398.   { "max_tmp_tables",          (long*) &max_tmp_tables,
  2399.       32, 1, ~0L, 0, 1 },
  2400.   { "max_write_lock_count",    (long*) &max_write_lock_count,
  2401.       ~0L, 1, ~0L, 0, 1 },
  2402.   { "myisam_sort_buffer_size", (long*) &myisam_sort_buffer_size,
  2403.       8192*1024, 4, ~0L, 0, 1 },
  2404.   { "net_buffer_length",       (long*) &net_buffer_length,
  2405.       16384, 1024, 1024*1024L, MALLOC_OVERHEAD, 1024 },
  2406.   { "net_retry_count",         (long*) &mysqld_net_retry_count,
  2407.       MYSQLD_NET_RETRY_COUNT, 1, ~0L, 0, 1 },
  2408.   { "net_read_timeout",        (long*) &net_read_timeout, 
  2409.       NET_READ_TIMEOUT, 1, 65535, 0, 1 },
  2410.   { "net_write_timeout",       (long*) &net_write_timeout,
  2411.       NET_WRITE_TIMEOUT, 1, 65535, 0, 1 },
  2412.   { "query_buffer_size",       (long*) &query_buff_size,
  2413.       0, MALLOC_OVERHEAD, (long) ~0, MALLOC_OVERHEAD, IO_SIZE },
  2414.   { "record_buffer",           (long*) &my_default_record_cache_size,
  2415.       128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, ~0L, MALLOC_OVERHEAD, IO_SIZE },
  2416.   { "slow_launch_time",        (long*) &slow_launch_time, 
  2417.       2L, 0L, ~0L, 0, 1 },
  2418.   { "sort_buffer",             (long*) &sortbuff_size,
  2419.       MAX_SORT_MEMORY, MIN_SORT_MEMORY+MALLOC_OVERHEAD*2, ~0L, MALLOC_OVERHEAD, 1 },
  2420.   { "table_cache",             (long*) &table_cache_size,
  2421.       64, 1, 16384, 0, 1 },
  2422.   { "thread_concurrency",      (long*) &concurrency,
  2423.       DEFAULT_CONCURRENCY, 1, 512, 0, 1 },
  2424.   { "thread_cache_size",       (long*) &thread_cache_size,
  2425.       0, 1, 16384, 0, 1 },
  2426.   { "tmp_table_size",          (long*) &tmp_table_size,
  2427.       1024*1024L, 1024, ~0L, MALLOC_OVERHEAD, 1 },
  2428.   { "thread_stack",            (long*) &thread_stack,
  2429.       DEFAULT_THREAD_STACK, 1024*32, ~0L, 0, 1024 },
  2430.   { "wait_timeout",            (long*) &net_wait_timeout,
  2431.       NET_WAIT_TIMEOUT, 1, ~0L, 0, 1 },
  2432.   { NullS, (long*) 0, 0, 0, 0, 0, 0}
  2433. };
  2434.  
  2435.  
  2436. struct show_var_st init_vars[]= {
  2437.   {"ansi_mode",               (char*) &opt_ansi_mode,               SHOW_BOOL},
  2438.   {"back_log",                (char*) &back_log,                    SHOW_LONG},
  2439.   {"basedir",                 mysql_home,                           SHOW_CHAR},
  2440. #ifdef HAVE_BERKELEY_DB
  2441.   {"bdb_cache_size",          (char*) &berkeley_cache_size,         SHOW_LONG},
  2442.   {"bdb_home",                (char*) &berkeley_home,               SHOW_CHAR_PTR},
  2443.   {"bdb_lock_max",            (char*) &berkeley_lock_max,        SHOW_LONG},
  2444.   {"bdb_logdir",              (char*) &berkeley_logdir,             SHOW_CHAR_PTR},
  2445.   {"bdb_tmpdir",              (char*) &berkeley_tmpdir,             SHOW_CHAR_PTR},
  2446. #endif
  2447.   {"character_set",           default_charset,                      SHOW_CHAR},
  2448.   {"character_sets",          (char*) &charsets_list,               SHOW_CHAR_PTR},
  2449.   {"concurrent_insert",       (char*) &myisam_concurrent_insert,    SHOW_MY_BOOL},
  2450.   {"connect_timeout",         (char*) &connect_timeout,             SHOW_LONG},
  2451.   {"datadir",                 mysql_real_data_home,                 SHOW_CHAR},
  2452.   {"delay_key_write",         (char*) &myisam_delay_key_write,      SHOW_MY_BOOL},
  2453.   {"delayed_insert_limit",    (char*) &delayed_insert_limit,        SHOW_LONG},
  2454.   {"delayed_insert_timeout",  (char*) &delayed_insert_timeout,      SHOW_LONG},
  2455.   {"delayed_queue_size",      (char*) &delayed_queue_size,          SHOW_LONG},
  2456.   {"flush",                   (char*) &myisam_flush,                SHOW_MY_BOOL},
  2457.   {"flush_time",              (char*) &flush_time,                  SHOW_LONG},
  2458.   {"init_file",               (char*) &opt_init_file,               SHOW_CHAR_PTR},
  2459.   {"interactive_timeout",     (char*) &net_interactive_timeout,     SHOW_LONG},
  2460.   {"join_buffer_size",        (char*) &join_buff_size,              SHOW_LONG},
  2461.   {"key_buffer_size",         (char*) &keybuff_size,                SHOW_LONG},
  2462.   {"language",                language,                             SHOW_CHAR},
  2463.   {"large_files_support",     (char*) &opt_large_files,             SHOW_BOOL},    
  2464. #ifdef HAVE_MLOCKALL
  2465.   {"locked_in_memory",          (char*) &locked_in_memory,        SHOW_BOOL},
  2466. #endif
  2467.   {"log",                     (char*) &opt_log,                     SHOW_BOOL},
  2468.   {"log_update",              (char*) &opt_update_log,              SHOW_BOOL},
  2469.   {"log_bin",                 (char*) &opt_bin_log,                 SHOW_BOOL},
  2470.   {"log_slave_updates",       (char*) &opt_log_slave_updates,       SHOW_BOOL},
  2471.   {"long_query_time",         (char*) &long_query_time,             SHOW_LONG},
  2472.   {"low_priority_updates",    (char*) &low_priority_updates,        SHOW_BOOL},
  2473.   {"lower_case_table_names",  (char*) &lower_case_table_names,      SHOW_LONG},
  2474.   {"max_allowed_packet",      (char*) &max_allowed_packet,          SHOW_LONG},
  2475.   {"max_connections",         (char*) &max_connections,             SHOW_LONG},
  2476.   {"max_connect_errors",      (char*) &max_connect_errors,          SHOW_LONG},
  2477.   {"max_delayed_threads",     (char*) &max_insert_delayed_threads,  SHOW_LONG},
  2478.   {"max_heap_table_size",     (char*) &max_heap_table_size,         SHOW_LONG},
  2479.   {"max_join_size",           (char*) &max_join_size,               SHOW_LONG},
  2480.   {"max_sort_length",         (char*) &max_item_sort_length,        SHOW_LONG},
  2481.   {"max_tmp_tables",          (char*) &max_tmp_tables,              SHOW_LONG},
  2482.   {"max_write_lock_count",    (char*) &max_write_lock_count,        SHOW_LONG},
  2483.   {"myisam_recover_options",  (char*) &myisam_recover_options_str,  SHOW_CHAR_PTR},
  2484.   {"myisam_sort_buffer_size", (char*) &myisam_sort_buffer_size,     SHOW_LONG},
  2485.   {"net_buffer_length",       (char*) &net_buffer_length,           SHOW_LONG},
  2486.   {"net_read_timeout",        (char*) &net_read_timeout,        SHOW_LONG},
  2487.   {"net_retry_count",         (char*) &mysqld_net_retry_count,      SHOW_LONG},
  2488.   {"net_write_timeout",       (char*) &net_write_timeout,        SHOW_LONG},
  2489.   {"pid_file",                (char*) pidfile_name,                 SHOW_CHAR},
  2490.   {"port",                    (char*) &mysql_port,                  SHOW_INT},
  2491.   {"protocol_version",        (char*) &protocol_version,            SHOW_INT},
  2492.   {"record_buffer",           (char*) &my_default_record_cache_size,SHOW_LONG},
  2493.   {"query_buffer_size",       (char*) &query_buff_size,            SHOW_LONG},
  2494.   {"server_id",               (char*) &server_id,            SHOW_LONG},
  2495.   {"skip_locking",            (char*) &my_disable_locking,          SHOW_MY_BOOL},
  2496.   {"skip_networking",         (char*) &opt_disable_networking,      SHOW_BOOL},
  2497.   {"skip_show_database",      (char*) &opt_skip_show_db,            SHOW_BOOL},
  2498.   {"slow_launch_time",        (char*) &slow_launch_time,            SHOW_LONG},
  2499.   {"socket",                  (char*) &mysql_unix_port,             SHOW_CHAR_PTR},
  2500.   {"sort_buffer",             (char*) &sortbuff_size,               SHOW_LONG},
  2501.   {"table_cache",             (char*) &table_cache_size,            SHOW_LONG},
  2502.   {"table_type",              (char*) &default_table_type_name,     SHOW_CHAR_PTR},
  2503.   {"thread_cache_size",       (char*) &thread_cache_size,           SHOW_LONG},
  2504. #ifdef HAVE_THR_SETCONCURRENCY
  2505.   {"thread_concurrency",      (char*) &concurrency,                 SHOW_LONG},
  2506. #endif
  2507.   {"thread_stack",            (char*) &thread_stack,                SHOW_LONG},
  2508. #ifdef HAVE_TZNAME
  2509.   {"timezone",                time_zone,                            SHOW_CHAR},
  2510. #endif
  2511.   {"tmp_table_size",          (char*) &tmp_table_size,              SHOW_LONG},
  2512.   {"tmpdir",                  (char*) &mysql_tmpdir,                SHOW_CHAR_PTR},
  2513.   {"version",                 server_version,                       SHOW_CHAR},
  2514.   {"wait_timeout",            (char*) &net_wait_timeout,            SHOW_LONG},
  2515.   {NullS, NullS, SHOW_LONG}
  2516. };
  2517.  
  2518. struct show_var_st status_vars[]= {
  2519.   {"Aborted_clients",          (char*) &aborted_threads,        SHOW_LONG},
  2520.   {"Aborted_connects",         (char*) &aborted_connects,       SHOW_LONG},
  2521.   {"Bytes_received",           (char*) &bytes_received,         SHOW_LONG},
  2522.   {"Bytes_sent",               (char*) &bytes_sent,             SHOW_LONG},
  2523.   {"Connections",              (char*) &thread_id,              SHOW_LONG_CONST},
  2524.   {"Created_tmp_disk_tables",  (char*) &created_tmp_disk_tables,SHOW_LONG},
  2525.   {"Created_tmp_tables",       (char*) &created_tmp_tables,     SHOW_LONG},
  2526.   {"Created_tmp_files",           (char*) &my_tmp_file_created,    SHOW_LONG},
  2527.   {"Delayed_insert_threads",   (char*) &delayed_insert_threads, SHOW_LONG},
  2528.   {"Delayed_writes",           (char*) &delayed_insert_writes,  SHOW_LONG},
  2529.   {"Delayed_errors",           (char*) &delayed_insert_errors,  SHOW_LONG},
  2530.   {"Flush_commands",           (char*) &refresh_version,        SHOW_LONG_CONST},
  2531.   {"Handler_delete",           (char*) &ha_delete_count,        SHOW_LONG},
  2532.   {"Handler_read_first",       (char*) &ha_read_first_count,    SHOW_LONG},
  2533.   {"Handler_read_key",         (char*) &ha_read_key_count,      SHOW_LONG},
  2534.   {"Handler_read_next",        (char*) &ha_read_next_count,     SHOW_LONG},
  2535.   {"Handler_read_prev",        (char*) &ha_read_prev_count,     SHOW_LONG},
  2536.   {"Handler_read_rnd",         (char*) &ha_read_rnd_count,      SHOW_LONG},
  2537.   {"Handler_read_rnd_next",    (char*) &ha_read_rnd_next_count, SHOW_LONG},
  2538.   {"Handler_update",           (char*) &ha_update_count,        SHOW_LONG},
  2539.   {"Handler_write",            (char*) &ha_write_count,         SHOW_LONG},
  2540.   {"Key_blocks_used",          (char*) &_my_blocks_used,        SHOW_LONG_CONST},
  2541.   {"Key_read_requests",        (char*) &_my_cache_r_requests,   SHOW_LONG},
  2542.   {"Key_reads",                (char*) &_my_cache_read,         SHOW_LONG},
  2543.   {"Key_write_requests",       (char*) &_my_cache_w_requests,   SHOW_LONG},
  2544.   {"Key_writes",               (char*) &_my_cache_write,        SHOW_LONG},
  2545.   {"Max_used_connections",     (char*) &max_used_connections,   SHOW_LONG},
  2546.   {"Not_flushed_key_blocks",   (char*) &_my_blocks_changed,     SHOW_LONG_CONST},
  2547.   {"Not_flushed_delayed_rows", (char*) &delayed_rows_in_use,    SHOW_LONG_CONST},
  2548.   {"Open_tables",              (char*) 0,                       SHOW_OPENTABLES},
  2549.   {"Open_files",               (char*) &my_file_opened,         SHOW_INT_CONST},
  2550.   {"Open_streams",             (char*) &my_stream_opened,       SHOW_INT_CONST},
  2551.   {"Opened_tables",            (char*) &opened_tables,          SHOW_LONG},
  2552.   {"Questions",                (char*) 0,                       SHOW_QUESTION},
  2553.   {"Select_full_join",         (char*) &select_full_join_count, SHOW_LONG},
  2554.   {"Select_full_range_join",   (char*) &select_full_range_join_count, SHOW_LONG},
  2555.   {"Select_range",             (char*) &select_range_count,     SHOW_LONG},
  2556.   {"Select_range_check",       (char*) &select_range_check_count, SHOW_LONG},
  2557.   {"Select_scan",           (char*) &select_scan_count,    SHOW_LONG},
  2558.   {"Slave_running",            (char*) &slave_running,          SHOW_BOOL},
  2559.   {"Slow_launch_threads",      (char*) &slow_launch_threads,    SHOW_LONG},
  2560.   {"Slow_queries",             (char*) &long_query_count,       SHOW_LONG},
  2561.   {"Sort_merge_passes",           (char*) &filesort_merge_passes,  SHOW_LONG},
  2562.   {"Sort_range",           (char*) &filesort_range_count,   SHOW_LONG},
  2563.   {"Sort_rows",               (char*) &filesort_rows,            SHOW_LONG},
  2564.   {"Sort_scan",               (char*) &filesort_scan_count,    SHOW_LONG},
  2565.   {"Threads_cached",           (char*) &cached_thread_count,    SHOW_LONG_CONST},
  2566.   {"Threads_connected",        (char*) &thread_count,           SHOW_INT_CONST},
  2567.   {"Threads_running",          (char*) &thread_running,         SHOW_INT_CONST},
  2568.   {"Uptime",                   (char*) 0,                       SHOW_STARTTIME},
  2569.   {NullS, NullS, SHOW_LONG}
  2570. };
  2571.  
  2572. static void print_version(void)
  2573. {
  2574.   printf("%s  Ver %s for %s on %s\n",my_progname,
  2575.      server_version,SYSTEM_TYPE,MACHINE_TYPE);
  2576. }
  2577.  
  2578. static void use_help(void)
  2579. {
  2580.   print_version();
  2581.   printf("Use '--help' or '--no-defaults --help' for a list of available options\n");
  2582. }  
  2583.  
  2584. static void usage(void)
  2585. {
  2586.   print_version();
  2587.   puts("Copyright (C) 2000 MySQL AB & MySQL Finland AB, by Monty and others");
  2588.   puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,");
  2589.   puts("and you are welcome to modify and redistribute it under the GPL license\n");
  2590.   puts("Starts the MySQL server\n");
  2591.  
  2592.   printf("Usage: %s [OPTIONS]\n", my_progname);
  2593.   puts("\n\
  2594.   --ansi        Use ANSI SQL syntax instead of MySQL syntax\n\
  2595.   -b, --basedir=path    Path to installation directory. All paths are\n\
  2596.             usually resolved relative to this\n\
  2597.   --big-tables        Allow big result sets by saving all temporary sets\n\
  2598.             on file (Solves most 'table full' errors)\n\
  2599.   --bind-address=IP    Ip address to bind to\n\
  2600.   --bootstrap        Used by mysql installation scripts\n\
  2601.   --character-sets-dir=...\n\
  2602.                         Directory where character sets are\n\
  2603.   --chroot=path        Chroot mysqld daemon during startup\n\
  2604.   --core-file        Write core on errors\n\
  2605.   -h, --datadir=path    Path to the database root");
  2606. #ifndef DBUG_OFF
  2607.   printf("\
  2608.   -#, --debug[=...]     Debug log. Default is '%s'\n",default_dbug_option);
  2609. #endif
  2610.   puts("\
  2611.   --default-character-set=charset\n\
  2612.             Set the default character set\n\
  2613.   --default-table-type=type\n\
  2614.             Set the default table type for tables\n\
  2615.   --delay-key-write-for-all-tables\n\
  2616.             Don't flush key buffers between writes for any MyISAM\n\
  2617.             table\n\
  2618.   --enable-locking    Enable system locking\n\
  2619.   -T, --exit-info    Print some debug info at exit\n\
  2620.   --flush        Flush tables to disk between SQL commands\n\
  2621.   -?, --help        Display this help and exit\n\
  2622.   --init-file=file    Read SQL commands from this file at startup\n\
  2623.   -L, --language=...    Client error messages in given language. May be\n\
  2624.             given as a full path\n\
  2625.   -l, --log[=file]    Log connections and queries to file\n\
  2626.   --log-bin[=file]      Log queries in new binary format (for replication)\n\
  2627.   --log-bin-index=file  File that holds the names for last binary log files\n\
  2628.   --log-update[=file]    Log updates to file.# where # is a unique number\n\
  2629.             if not given.\n\
  2630.   --log-isam[=file]    Log all MyISAM changes to file\n\
  2631.   --log-long-format    Log some extra information to update log\n\
  2632.   --low-priority-updates INSERT/DELETE/UPDATE has lower priority than selects\n\
  2633.   --log-slow-queries=[file]\n\
  2634.             Log slow queries to this log file.  Defaults logging\n\
  2635.                         to hostname-slow.log\n\
  2636.   --pid-file=path    Pid file used by safe_mysqld\n\
  2637.   --myisam-recover[=option[,option...]] where options is one of DEAULT,\n\
  2638.             BACKUP or FORCE.\n\
  2639.   --memlock        Lock mysqld in memory\n\
  2640.   -n, --new        Use very new possible 'unsafe' functions\n\
  2641.   -o, --old-protocol    Use the old (3.20) protocol\n\
  2642.   -P, --port=...    Port number to use for connection\n");
  2643. #ifdef ONE_THREAD
  2644.   puts("\
  2645.   --one-thread        Only use one thread (for debugging under Linux)\n");
  2646. #endif
  2647.   puts("\
  2648.   -O, --set-variable var=option\n\
  2649.             Give a variable an value. --help lists variables\n\
  2650.   -Sg, --skip-grant-tables\n\
  2651.             Start without grant tables. This gives all users\n\
  2652.             FULL ACCESS to all tables!\n\
  2653.   --safe-mode        Skip some optimize stages (for testing)\n\
  2654.   --skip-concurrent-insert\n\
  2655.                 Don't use concurrent insert with MyISAM\n\
  2656.   --skip-delay-key-write\n\
  2657.             Ignore the delay_key_write option for all tables\n\
  2658.   --skip-locking    Don't use system locking. To use isamchk one has\n\
  2659.             to shut down the server.\n\
  2660.   --skip-name-resolve    Don't resolve hostnames.\n\
  2661.             All hostnames are IP's or 'localhost'\n\
  2662.   --skip-networking    Don't allow connection with TCP/IP.\n\
  2663.   --skip-new        Don't use new, possible wrong routines.\n\
  2664.   --skip-host-cache    Don't cache host names\n");
  2665.   /* We have to break the string here because of VC++ limits */
  2666.   puts("\
  2667.   --skip-show-database  Don't allow 'SHOW DATABASE' commands\n\
  2668.   --skip-thread-priority\n\
  2669.             Don't give threads different priorities.\n\
  2670.   --socket=...        Socket file to use for connection\n\
  2671.   -t, --tmpdir=path    Path for temporary files\n\
  2672.   -u, --user=user_name    Run mysqld daemon as user\n\
  2673.   -V, --version        output version information and exit");
  2674. #ifdef __WIN__
  2675.   puts("NT and Win32 specific options:\n\
  2676.   --console        Don't remove the console window\n\
  2677.   --install        Install mysqld as a service (NT)\n\
  2678.   --remove        Remove mysqld from the service list (NT)\n\
  2679.   --standalone        Dummy option to start as a standalone program (NT)\n\
  2680. ");
  2681. #endif
  2682. #ifdef HAVE_BERKELEY_DB
  2683.   puts("\
  2684.   --bdb-home=  directory  Berkeley home direcory\n\
  2685.   --bdb-lock-detect=#      Berkeley lock detect\n\
  2686.                           (DEFAULT, OLDEST, RANDOM or YOUNGEST, # sec)\n\
  2687.   --bdb-logdir=directory  Berkeley DB log file directory\n\
  2688.   --bdb-nosync          Don't synchronously flush logs\n\
  2689.   --bdb-recover          Start Berkeley DB in recover mode\n\
  2690.   --bdb-tmpdir=directory  Berkeley DB tempfile name\n\
  2691.   --skip-bdb          Don't use berkeley db (will save memory)\n\
  2692. ");
  2693. #endif
  2694. #ifdef HAVE_INNOBASE_DB
  2695.   puts("\
  2696.   --skip-innobase      Don't use innobase (will save memory)\n\
  2697. ");
  2698. #endif
  2699.   print_defaults("my",load_default_groups);
  2700.   puts("");
  2701.  
  2702. #include "sslopt-usage.h"
  2703.  
  2704.   fix_paths();
  2705.   set_ports();
  2706.   printf("\
  2707. To see what values a running MySQL server is using, type\n\
  2708. 'mysqladmin variables' instead of 'mysqld --help'.\n\
  2709. The default values (after parsing the command line arguments) are:\n\n");
  2710.  
  2711.   printf("basedir:     %s\n",mysql_home);
  2712.   printf("datadir:     %s\n",mysql_real_data_home);
  2713.   printf("tmpdir:      %s\n",mysql_tmpdir);
  2714.   printf("language:    %s\n",language);
  2715. #ifndef __WIN__
  2716.   printf("pid file:    %s\n",pidfile_name);
  2717. #endif
  2718.   if (opt_logname)
  2719.     printf("logfile:     %s\n",opt_logname);
  2720.   if (opt_update_logname)
  2721.     printf("update log:  %s\n",opt_update_logname);
  2722.   if (opt_bin_log)
  2723.   {
  2724.     printf("binary log:  %s\n",opt_bin_logname ? opt_bin_logname : "");
  2725.     printf("binary log index:  %s\n",
  2726.        opt_binlog_index_name ? opt_binlog_index_name : "");
  2727.   }
  2728.   if (opt_slow_logname)
  2729.     printf("update log:  %s\n",opt_slow_logname);
  2730.   printf("TCP port:    %d\n",mysql_port);
  2731. #if defined(HAVE_SYS_UN_H)
  2732.   printf("Unix socket: %s\n",mysql_unix_port);
  2733. #endif
  2734.   if (my_disable_locking)
  2735.     puts("\nsystem locking is not in use");
  2736.   if (opt_noacl)
  2737.     puts("\nGrant tables are not used. All users have full access rights");
  2738.   printf("\nPossible variables for option --set-variable (-O) are:\n");
  2739.   for (uint i=0 ; changeable_vars[i].name ; i++)
  2740.     printf("%-20s  current value: %lu\n",
  2741.        changeable_vars[i].name,
  2742.        (ulong) *changeable_vars[i].varptr);
  2743. }
  2744.  
  2745.  
  2746. static void set_options(void)
  2747. {
  2748.   set_all_changeable_vars( changeable_vars );
  2749. #if !defined( my_pthread_setprio ) && !defined( HAVE_PTHREAD_SETSCHEDPARAM )
  2750.   opt_specialflag |= SPECIAL_NO_PRIOR;
  2751. #endif
  2752.  
  2753.   (void) strmov( default_charset, MYSQL_CHARSET);
  2754.   (void) strmov( language, LANGUAGE);
  2755.   (void) strmov( mysql_real_data_home, get_relative_path(DATADIR));
  2756. #ifdef __WIN__
  2757.   /* Allow Win32 users to move MySQL anywhere */
  2758.   {
  2759.     char prg_dev[LIBLEN];
  2760.     my_path(prg_dev,my_progname,"mysql/bin");
  2761.     strcat(prg_dev,"/../");            // Remove 'bin' to get base dir
  2762.     cleanup_dirname(mysql_home,prg_dev);
  2763.   }
  2764. #else
  2765.   const char *tmpenv;
  2766.   if ( !(tmpenv = getenv("MY_BASEDIR_VERSION")))
  2767.     tmpenv = DEFAULT_MYSQL_HOME;
  2768.   (void) strmov( mysql_home, tmpenv );
  2769. #endif
  2770.  
  2771. #if defined( HAVE_mit_thread ) || defined( __WIN__ ) || defined( HAVE_LINUXTHREADS )
  2772.   my_disable_locking = 1;
  2773. #endif
  2774.   my_bind_addr = htonl( INADDR_ANY );
  2775. }
  2776.  
  2777.     /* Initiates DEBUG - but no debugging here ! */
  2778.  
  2779. static void get_options(int argc,char **argv)
  2780. {
  2781.   int c,option_index=0;
  2782.  
  2783.   myisam_delay_key_write=1;            // Allow use of this
  2784.   while ((c=getopt_long(argc,argv,"ab:C:h:#::T::?l::L:O:P:sS::t:u:noVvI?",
  2785.             long_options, &option_index)) != EOF)
  2786.   {
  2787.     switch(c) {
  2788. #ifndef DBUG_OFF
  2789.     case '#':
  2790.       DBUG_PUSH(optarg ? optarg : default_dbug_option);
  2791.       opt_endinfo=1;                /* unireg: memory allocation */
  2792.       break;
  2793. #endif
  2794.     case 'a':
  2795.       opt_ansi_mode=1;
  2796.       thd_startup_options|=OPTION_ANSI_MODE;
  2797.       break;
  2798.     case 'b':
  2799.       strmov(mysql_home,optarg);
  2800.       break;
  2801.     case 'l':
  2802.       opt_log=1;
  2803.       opt_logname=optarg;            // Use hostname.log if null
  2804.       break;
  2805.     case 'h':
  2806.       strmov(mysql_real_data_home,optarg);
  2807.       break;
  2808.     case 'L':
  2809.       strmov(language,optarg);
  2810.       break;
  2811.     case 'n':
  2812.       opt_specialflag|= SPECIAL_NEW_FUNC;
  2813.       break;
  2814.     case 'o':
  2815.       protocol_version=PROTOCOL_VERSION-1;
  2816.       break;
  2817.     case 'O':
  2818.       if (set_changeable_var(optarg, changeable_vars))
  2819.       {
  2820.     use_help();
  2821.     exit(1);
  2822.       }
  2823.       break;
  2824.     case 'P':
  2825.       mysql_port= (unsigned int) atoi(optarg);
  2826.       break;
  2827. #if !defined(DBUG_OFF) && defined(SAFEMALLOC)      
  2828.     case OPT_SAFEMALLOC_MEM_LIMIT:
  2829.       safemalloc_mem_limit = atoi(optarg);
  2830.       break;
  2831. #endif      
  2832.     case OPT_SOCKET:
  2833.       mysql_unix_port= optarg;
  2834.       break;
  2835.     case 'r':
  2836.       mysqld_chroot=optarg;
  2837.       break;
  2838. #ifdef USE_SYMDIR
  2839.     case 's':
  2840.       my_use_symdir=1;            /* Use internal symbolic links */
  2841.       break;
  2842. #endif
  2843.     case 't':
  2844.       mysql_tmpdir=optarg;
  2845.       break;
  2846.     case 'u':
  2847.       mysqld_user=optarg;
  2848.       break;
  2849.     case 'v':
  2850.     case 'V':
  2851.       print_version();
  2852.       exit(0);
  2853.     case 'I':
  2854.     case '?':
  2855.       usage();
  2856.       exit(0);
  2857.     case 'T':
  2858.       test_flags= optarg ? (uint) atoi(optarg) : (uint) ~0;
  2859.       opt_endinfo=1;
  2860.       break;
  2861.     case 'S':
  2862.       if (!optarg)
  2863.     opt_specialflag|= SPECIAL_NO_NEW_FUNC | SPECIAL_SAFE_MODE;
  2864.       else if (!strcmp(optarg,"l"))
  2865.     my_disable_locking=1;
  2866.       else if (!strcmp(optarg,"g"))
  2867.     opt_noacl=1;
  2868.       else
  2869.       {
  2870.     fprintf(stderr,"%s: Unrecognized option: %s\n",my_progname,optarg);
  2871.     use_help();
  2872.     exit(1);
  2873.       }
  2874.       break;
  2875.     case (int) OPT_BIG_TABLES:
  2876.       thd_startup_options|=OPTION_BIG_TABLES;
  2877.       break;
  2878.     case (int) OPT_ISAM_LOG:
  2879.       opt_myisam_log=1;
  2880.       if (optarg)
  2881.     myisam_log_filename=optarg;
  2882.       break;
  2883.     case (int) OPT_UPDATE_LOG:
  2884.       opt_update_log=1;
  2885.       opt_update_logname=optarg;        // Use hostname.# if null
  2886.       break;
  2887.     case (int) OPT_BIN_LOG_INDEX:
  2888.       opt_binlog_index_name = optarg;
  2889.       break;
  2890.     case (int) OPT_BIN_LOG:
  2891.       opt_bin_log=1;
  2892.       x_free(opt_bin_logname);
  2893.       if (optarg && optarg[0])
  2894.     opt_bin_logname=my_strdup(optarg,MYF(0));
  2895.       break;
  2896.       // needs to be handled (as no-op) in non-debugging mode for test suite
  2897.     case (int)OPT_DISCONNECT_SLAVE_EVENT_COUNT:
  2898. #ifndef DBUG_OFF      
  2899.       disconnect_slave_event_count = atoi(optarg);
  2900. #endif      
  2901.       break;
  2902.     case (int) OPT_LOG_SLAVE_UPDATES:
  2903.       opt_log_slave_updates = 1;
  2904.       break;
  2905.  
  2906.     case (int)OPT_REPLICATE_IGNORE_DB:
  2907.       {
  2908.     i_string *db = new i_string(optarg);
  2909.     replicate_ignore_db.push_back(db);
  2910.         break;
  2911.       }
  2912.     case (int)OPT_REPLICATE_DO_DB:
  2913.       {
  2914.     i_string *db = new i_string(optarg);
  2915.     replicate_do_db.push_back(db);
  2916.         break;
  2917.       }
  2918.     case (int)OPT_REPLICATE_REWRITE_DB:
  2919.       {
  2920.     char* key = optarg,*p, *val;
  2921.     p = strstr(optarg, "->");
  2922.     if(!p)
  2923.       {
  2924.         fprintf(stderr,
  2925.             "bad syntax in replicate-rewrite-db - missing ->\n");
  2926.         exit(1);
  2927.       }
  2928.     val = p--;
  2929.     while(isspace(*p) && p > optarg) *p-- = 0;
  2930.     if(p == optarg)
  2931.       {
  2932.         fprintf(stderr,
  2933.             "bad syntax in replicate-rewrite-db - empty FROM db\n");
  2934.         exit(1);
  2935.       }
  2936.     *val = 0;
  2937.     val += 2;
  2938.     while(*val && isspace(*val)) *val++;
  2939.     if(!*val)
  2940.       {
  2941.         fprintf(stderr,
  2942.             "bad syntax in replicate-rewrite-db - empty TO db\n");
  2943.         exit(1);
  2944.       }
  2945.  
  2946.     i_string_pair* db_pair = new i_string_pair(key, val);
  2947.     replicate_rewrite_db.push_back(db_pair);
  2948.     break;
  2949.       }
  2950.  
  2951.     case (int)OPT_BINLOG_IGNORE_DB:
  2952.       {
  2953.     i_string *db = new i_string(optarg);
  2954.     binlog_ignore_db.push_back(db);
  2955.         break;
  2956.       }
  2957.     case (int)OPT_BINLOG_DO_DB:
  2958.       {
  2959.     i_string *db = new i_string(optarg);
  2960.     binlog_do_db.push_back(db);
  2961.         break;
  2962.       }
  2963.     case (int)OPT_REPLICATE_DO_TABLE:
  2964.       {
  2965.     if(!do_table_inited)
  2966.       init_table_rule_hash(&replicate_do_table, &do_table_inited);
  2967.     if(add_table_rule(&replicate_do_table, optarg))
  2968.       {
  2969.         fprintf(stderr, "could not add do table rule '%s'\n", optarg);
  2970.         exit(1);
  2971.       }
  2972.     table_rules_on = 1;
  2973.     break;
  2974.       }
  2975.     case (int)OPT_REPLICATE_WILD_DO_TABLE:
  2976.       {
  2977.     if(!wild_do_table_inited)
  2978.       init_table_rule_array(&replicate_wild_do_table,
  2979.                 &wild_do_table_inited);
  2980.     if(add_wild_table_rule(&replicate_wild_do_table, optarg))
  2981.       {
  2982.         fprintf(stderr, "could not add do table rule '%s'\n", optarg);
  2983.         exit(1);
  2984.       }
  2985.     table_rules_on = 1;
  2986.     break;
  2987.       }
  2988.     case (int)OPT_REPLICATE_WILD_IGNORE_TABLE:
  2989.       {
  2990.     if(!wild_ignore_table_inited)
  2991.       init_table_rule_array(&replicate_wild_ignore_table,
  2992.                 &wild_ignore_table_inited);
  2993.     if(add_wild_table_rule(&replicate_wild_ignore_table, optarg))
  2994.       {
  2995.         fprintf(stderr, "could not add do table rule '%s'\n", optarg);
  2996.         exit(1);
  2997.       }
  2998.     table_rules_on = 1;
  2999.     break;
  3000.       }
  3001.     case (int)OPT_REPLICATE_IGNORE_TABLE:
  3002.       {
  3003.     if(!ignore_table_inited)
  3004.       init_table_rule_hash(&replicate_ignore_table, &ignore_table_inited);
  3005.     if(add_table_rule(&replicate_ignore_table, optarg))
  3006.       {
  3007.         fprintf(stderr, "could not add ignore table rule '%s'\n", optarg);
  3008.         exit(1);
  3009.       }
  3010.     table_rules_on = 1;
  3011.     break;
  3012.       }
  3013.     case (int) OPT_SQL_BIN_UPDATE_SAME:
  3014.       opt_sql_bin_update  = 1;
  3015.       break;
  3016.     case (int) OPT_SLOW_QUERY_LOG:
  3017.       opt_slow_log=1;
  3018.       opt_slow_logname=optarg;
  3019.       break;
  3020.     case (int)OPT_SKIP_SLAVE_START:
  3021.       opt_skip_slave_start = 1;
  3022.       break;
  3023.     case (int) OPT_SKIP_NEW:
  3024.       opt_specialflag|= SPECIAL_NO_NEW_FUNC;
  3025.       default_table_type=DB_TYPE_ISAM;
  3026.       myisam_delay_key_write=0;
  3027.       myisam_concurrent_insert=0;
  3028.       myisam_recover_options= HA_RECOVER_NONE;
  3029.       ha_open_options&= ~HA_OPEN_ABORT_IF_CRASHED;
  3030.       break;
  3031.     case (int) OPT_SAFE:
  3032.       opt_specialflag|= SPECIAL_SAFE_MODE;
  3033.       myisam_delay_key_write=0;
  3034.       myisam_recover_options= HA_RECOVER_NONE;    // To be changed
  3035.       ha_open_options&= ~HA_OPEN_ABORT_IF_CRASHED;
  3036.       break;
  3037.     case (int) OPT_SKIP_CONCURRENT_INSERT:
  3038.       myisam_concurrent_insert=0;
  3039.       break;
  3040.     case (int) OPT_SKIP_PRIOR:
  3041.       opt_specialflag|= SPECIAL_NO_PRIOR;
  3042.       break;
  3043.     case (int) OPT_SKIP_GRANT:
  3044.       opt_noacl=1;
  3045.       break;
  3046.     case (int) OPT_SKIP_LOCK:
  3047.       my_disable_locking=1;
  3048.       break;
  3049.     case (int) OPT_SKIP_HOST_CACHE:
  3050.       opt_specialflag|= SPECIAL_NO_HOST_CACHE;
  3051.       break;
  3052.     case (int) OPT_ENABLE_LOCK:
  3053.       my_disable_locking=0;
  3054.       break;
  3055.     case (int) OPT_USE_LOCKING:
  3056.       my_disable_locking=0;
  3057.       break;
  3058.     case (int) OPT_SKIP_RESOLVE:
  3059.       opt_specialflag|=SPECIAL_NO_RESOLVE;
  3060.       break;
  3061.     case (int) OPT_LONG_FORMAT:
  3062.       opt_specialflag|=SPECIAL_LONG_LOG_FORMAT;
  3063.       break;
  3064.     case (int) OPT_SKIP_NETWORKING:
  3065.       opt_disable_networking=1;
  3066.       mysql_port=0;
  3067.       break;
  3068.     case (int) OPT_SKIP_SHOW_DB:
  3069.       opt_skip_show_db=1;
  3070.       opt_specialflag|=SPECIAL_SKIP_SHOW_DB;
  3071.       mysql_port=0;
  3072.       break;
  3073.     case (int) OPT_MEMLOCK:
  3074.       locked_in_memory=1;
  3075.       break;
  3076.     case (int) OPT_ONE_THREAD:
  3077.       test_flags |= TEST_NO_THREADS;
  3078.       break;
  3079.     case (int) OPT_WANT_CORE:
  3080.       test_flags |= TEST_CORE_ON_SIGNAL;
  3081.       break;
  3082.     case (int) OPT_BIND_ADDRESS:
  3083.       if (optarg && isdigit(optarg[0]))
  3084.       {
  3085.     my_bind_addr = (ulong) inet_addr(optarg);
  3086.       }
  3087.       else
  3088.       {
  3089.     struct hostent *ent;
  3090.     if (!optarg || !optarg[0])
  3091.       ent=gethostbyname(optarg);
  3092.     else
  3093.     {
  3094.       char myhostname[255];
  3095.       if (gethostname(myhostname,sizeof(myhostname)) < 0)
  3096.       {
  3097.         sql_perror("Can't start server: cannot get my own hostname!");
  3098.         exit(1);
  3099.       }
  3100.       ent=gethostbyname(myhostname);
  3101.     }
  3102.     if (!ent)
  3103.     {
  3104.       sql_perror("Can't start server: cannot resolve hostname!");
  3105.       exit(1);
  3106.     }
  3107.     my_bind_addr = (ulong) ((in_addr*)ent->h_addr_list[0])->s_addr;
  3108.       }
  3109.       break;
  3110.     case (int) OPT_PID_FILE:
  3111.       strmov(pidfile_name,optarg);
  3112.       break;
  3113.     case (int) OPT_INIT_FILE:
  3114.       opt_init_file=optarg;
  3115.       break;
  3116. #ifdef __WIN__
  3117.     case (int) OPT_STANDALONE:        /* Dummy option for NT */
  3118.       break;
  3119.     case (int) OPT_CONSOLE:
  3120.       opt_console=1;
  3121.       break;
  3122. #endif
  3123.     case (int) OPT_FLUSH:
  3124.       nisam_flush=myisam_flush=1;
  3125.       flush_time=0;            // No auto flush
  3126.       break;
  3127.     case OPT_LOW_PRIORITY_UPDATES:
  3128.       thd_startup_options|=OPTION_LOW_PRIORITY_UPDATES;
  3129.       low_priority_updates=1;
  3130.       break;
  3131.     case OPT_BOOTSTRAP:
  3132.       opt_noacl=opt_bootstrap=1;
  3133.       break;
  3134.     case OPT_TABLE_TYPE:
  3135.     {
  3136.       int type;
  3137.       if ((type=find_type(optarg, &ha_table_typelib, 2)) <= 0)
  3138.       {
  3139.     fprintf(stderr,"Unknown table type: %s\n",optarg);
  3140.     exit(1);
  3141.       }
  3142.       default_table_type= (enum db_type) type;
  3143.       break;
  3144.     }
  3145.     case OPT_SERVER_ID:
  3146.       server_id = atoi(optarg);
  3147.       break;
  3148.     case OPT_DELAY_KEY_WRITE:
  3149.       ha_open_options|=HA_OPEN_DELAY_KEY_WRITE;
  3150.       myisam_delay_key_write=1;
  3151.       break;
  3152.     case OPT_SKIP_DELAY_KEY_WRITE:
  3153.       myisam_delay_key_write=0;
  3154.       break;
  3155.     case 'C':
  3156.       strmov(default_charset,optarg);
  3157.       break;
  3158.     case OPT_CHARSETS_DIR:
  3159.       strmov(mysql_charsets_dir, optarg);
  3160.       charsets_dir = mysql_charsets_dir;
  3161.       break;
  3162. #include "sslopt-case.h"
  3163. #ifdef HAVE_BERKELEY_DB
  3164.     case OPT_BDB_LOG:
  3165.       berkeley_logdir=optarg;
  3166.       break;
  3167.     case OPT_BDB_HOME:
  3168.       berkeley_home=optarg;
  3169.       break;
  3170.     case OPT_BDB_NOSYNC:
  3171.       berkeley_init_flags|=DB_TXN_NOSYNC;
  3172.       break;
  3173.     case OPT_BDB_RECOVER:
  3174.       berkeley_init_flags|=DB_RECOVER;
  3175.       break;
  3176.     case OPT_BDB_TMP:
  3177.       berkeley_tmpdir=optarg;
  3178.       break;
  3179.     case OPT_BDB_LOCK:
  3180.     {
  3181.       int type;
  3182.       if ((type=find_type(optarg, &berkeley_lock_typelib, 2)) > 0)
  3183.     berkeley_lock_type=berkeley_lock_types[type-1];
  3184.       else
  3185.       {
  3186.     if (test_if_int(optarg,(uint) strlen(optarg)))
  3187.       berkeley_lock_scan_time=atoi(optarg);
  3188.     else
  3189.     {
  3190.       fprintf(stderr,"Unknown lock type: %s\n",optarg);
  3191.       exit(1);
  3192.     }
  3193.       }
  3194.       break;
  3195.     }
  3196.     case OPT_BDB_SKIP:
  3197.       berkeley_skip=1;
  3198.       break;
  3199. #endif
  3200. #ifdef HAVE_INNOBASE_DB
  3201.     case OPT_INNOBASE_SKIP:
  3202.       innobase_skip=1;
  3203.       break;
  3204. #endif
  3205.     case OPT_MYISAM_RECOVER:
  3206.     {
  3207.       if (!optarg || !optarg[0])
  3208.       {
  3209.     myisam_recover_options=    HA_RECOVER_DEFAULT;
  3210.     myisam_recover_options_str= myisam_recover_typelib.type_names[0];
  3211.       }
  3212.       else
  3213.       {
  3214.     myisam_recover_options_str=optarg;
  3215.     if ((myisam_recover_options=
  3216.         find_bit_type(optarg, &myisam_recover_typelib)) == ~(ulong) 0)
  3217.     {
  3218.       fprintf(stderr, "Unknown option to myisam-recover: %s\n",optarg);
  3219.       exit(1);
  3220.     }
  3221.       }
  3222.       ha_open_options|=HA_OPEN_ABORT_IF_CRASHED;
  3223.       break;
  3224.     }
  3225.     case OPT_MASTER_HOST:
  3226.       master_host=optarg;
  3227.       break;
  3228.     case OPT_MASTER_USER:
  3229.       master_user=optarg;
  3230.       break;
  3231.     case OPT_MASTER_PASSWORD:
  3232.       master_password=optarg;
  3233.       break;
  3234.     case OPT_MASTER_INFO_FILE:
  3235.       master_info_file=optarg;
  3236.       break;
  3237.     case OPT_MASTER_PORT:
  3238.       master_port= atoi(optarg);
  3239.       break;
  3240.     case OPT_MASTER_CONNECT_RETRY:
  3241.       master_connect_retry= atoi(optarg);
  3242.       break;
  3243.  
  3244.     default:
  3245.       fprintf(stderr,"%s: Unrecognized option: %c\n",my_progname,c);
  3246.       use_help();
  3247.       exit(1);
  3248.     }
  3249.   }
  3250.   // Skipp empty arguments (from shell)
  3251.   while (argc != optind && !argv[optind][0])
  3252.     optind++;
  3253.   if (argc != optind)
  3254.   {
  3255.     fprintf(stderr,"%s: Too many parameters\n",my_progname);
  3256.     use_help();
  3257.     exit(1);
  3258.   }
  3259.   fix_paths();
  3260.   default_table_type_name=ha_table_typelib.type_names[default_table_type-1];
  3261. }
  3262.  
  3263.  
  3264. #ifdef __WIN__
  3265.  
  3266. #ifndef KEY_SERVICE_PARAMETERS
  3267. #define KEY_SERVICE_PARAMETERS    "SYSTEM\\CurrentControlSet\\Services\\MySql\\Parameters"
  3268. #endif
  3269.  
  3270. #define COPY_KEY_VALUE(value) if (copy_key_value(hParametersKey,&(value),lpszValue)) return 1
  3271. #define CHECK_KEY_TYPE(type,name) if ( type != dwKeyValueType ) { key_type_error(hParametersKey,name); return 1; }
  3272. #define SET_CHANGEABLE_VARVAL(varname) if (set_varval(hParametersKey,varname,szKeyValueName,dwKeyValueType,lpdwValue)) return 1;
  3273.  
  3274. static void key_type_error(HKEY hParametersKey,const char *szKeyValueName)
  3275. {
  3276.  TCHAR szErrorMsg[512];
  3277.  RegCloseKey( hParametersKey );
  3278.  strxmov(szErrorMsg,TEXT("Value \""),
  3279.      szKeyValueName,
  3280.      TEXT("\" of registry key \"" KEY_SERVICE_PARAMETERS "\" has wrong type\n"),NullS);
  3281.  fprintf(stderr, szErrorMsg); /* not unicode compatible */
  3282. }
  3283.  
  3284. static bool copy_key_value(HKEY hParametersKey, char **var, const char *value)
  3285. {
  3286.   if (!(*var=my_strdup(value,MYF(MY_WME))))
  3287.   {
  3288.     RegCloseKey(hParametersKey);
  3289.     fprintf(stderr, "Couldn't allocate memory for registry key value\n");
  3290.     return 1;
  3291.   }
  3292.   return 0;
  3293. }
  3294.  
  3295. static bool set_varval(HKEY hParametersKey,const char *var,
  3296.                const char *szKeyValueName, DWORD dwKeyValueType,
  3297.                LPDWORD lpdwValue)
  3298. {
  3299.   CHECK_KEY_TYPE(dwKeyValueType, szKeyValueName );
  3300.   if (set_changeable_varval(var, *lpdwValue, changeable_vars))
  3301.   {
  3302.     TCHAR szErrorMsg [ 512 ];
  3303.     RegCloseKey( hParametersKey );
  3304.     strxmov(szErrorMsg,
  3305.         TEXT("Value \""),
  3306.         szKeyValueName,
  3307.         TEXT("\" of registry key \"" KEY_SERVICE_PARAMETERS  "\" is invalid\n"),NullS);
  3308.     fprintf( stderr, szErrorMsg ); /* not unicode compatible */
  3309.     return 1;
  3310.   }
  3311.   return 0;
  3312. }
  3313.  
  3314.  
  3315. static int get_service_parameters()
  3316. {
  3317.   DWORD dwLastError;
  3318.   HKEY hParametersKey;
  3319.   DWORD dwIndex;
  3320.   TCHAR szKeyValueName [ 256 ];
  3321.   DWORD dwKeyValueName;
  3322.   DWORD dwKeyValueType;
  3323.   BYTE bKeyValueBuffer [ 512 ];
  3324.   DWORD dwKeyValueBuffer;
  3325.   LPDWORD lpdwValue = (LPDWORD) &bKeyValueBuffer[0];
  3326.   LPCTSTR lpszValue = (LPCTSTR) &bKeyValueBuffer[0];
  3327.  
  3328.   /* open parameters of service */
  3329.   dwLastError = (DWORD) RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  3330.                       TEXT(KEY_SERVICE_PARAMETERS), 0,
  3331.                       KEY_READ, &hParametersKey );
  3332.   if ( dwLastError == ERROR_FILE_NOT_FOUND ) /* no parameters available */
  3333.     return 0;
  3334.   if ( dwLastError != ERROR_SUCCESS )
  3335.   {
  3336.     fprintf(stderr,"Can't open registry key \"" KEY_SERVICE_PARAMETERS "\" for reading\n" );
  3337.     return 1;
  3338.   }
  3339.  
  3340.   /* enumerate all values of key */
  3341.   dwIndex = 0;
  3342.   dwKeyValueName = sizeof( szKeyValueName ) / sizeof( TCHAR );
  3343.   dwKeyValueBuffer = sizeof( bKeyValueBuffer );
  3344.   while ( (dwLastError = (DWORD) RegEnumValue(hParametersKey, dwIndex,
  3345.                           szKeyValueName, &dwKeyValueName,
  3346.                           NULL, &dwKeyValueType,
  3347.                           &bKeyValueBuffer[0],
  3348.                           &dwKeyValueBuffer))
  3349.       != ERROR_NO_MORE_ITEMS )
  3350.   {
  3351.     /* check if error occured */
  3352.     if ( dwLastError != ERROR_SUCCESS )
  3353.     {
  3354.       RegCloseKey( hParametersKey );
  3355.       fprintf( stderr, "Can't enumerate values of registry key \"" KEY_SERVICE_PARAMETERS "\"\n" );
  3356.       return 1;
  3357.     }
  3358.     if ( lstrcmp(szKeyValueName, TEXT("BaseDir")) == 0 )
  3359.     {
  3360.       CHECK_KEY_TYPE( REG_SZ, szKeyValueName);
  3361.       strmov( mysql_home, lpszValue ); /* not unicode compatible */
  3362.     }
  3363.     else if ( lstrcmp(szKeyValueName, TEXT("BindAddress")) == 0 )
  3364.     {
  3365.       CHECK_KEY_TYPE( REG_SZ, szKeyValueName);
  3366.  
  3367.       my_bind_addr = (ulong) inet_addr( lpszValue );
  3368.       if ( my_bind_addr == (ulong) INADDR_NONE )
  3369.       {
  3370.     struct hostent* ent;
  3371.  
  3372.     if ( !(*lpszValue) )
  3373.     {
  3374.       char szHostName [ 256 ];
  3375.       if ( gethostname(szHostName, sizeof(szHostName)) == SOCKET_ERROR )
  3376.       {
  3377.         RegCloseKey( hParametersKey );
  3378.         fprintf( stderr, "Can't get my own hostname\n" );
  3379.         return 1;
  3380.       }
  3381.       ent = gethostbyname( szHostName );
  3382.     }
  3383.     else ent = gethostbyname( lpszValue );
  3384.     if ( !ent )
  3385.     {
  3386.       RegCloseKey( hParametersKey );
  3387.       fprintf( stderr, "Can't resolve hostname!\n" );
  3388.       return 1;
  3389.     }
  3390.     my_bind_addr = (ulong) ((in_addr*)ent->h_addr_list[0])->s_addr;
  3391.       }
  3392.     }
  3393.     else if ( lstrcmp(szKeyValueName, TEXT("BigTables")) == 0 )
  3394.     {
  3395.       CHECK_KEY_TYPE( REG_DWORD, szKeyValueName);
  3396.       if ( *lpdwValue )
  3397.     thd_startup_options |= OPTION_BIG_TABLES;
  3398.       else
  3399.     thd_startup_options &= ~((ulong)OPTION_BIG_TABLES);
  3400.     }
  3401.     else if ( lstrcmp(szKeyValueName, TEXT("DataDir")) == 0 )
  3402.     {
  3403.       CHECK_KEY_TYPE( REG_SZ, szKeyValueName );
  3404.       strmov( mysql_real_data_home, lpszValue ); /* not unicode compatible */
  3405.     }
  3406.     else if ( lstrcmp(szKeyValueName, TEXT("Locking")) == 0 )
  3407.     {
  3408.       CHECK_KEY_TYPE( REG_DWORD, szKeyValueName );
  3409.       my_disable_locking = !(*lpdwValue);
  3410.     }
  3411.     else if ( lstrcmp(szKeyValueName, TEXT("LogFile")) == 0 )
  3412.     {
  3413.       CHECK_KEY_TYPE( REG_SZ, szKeyValueName );
  3414.       opt_log = 1;
  3415.       COPY_KEY_VALUE( opt_logname );
  3416.     }
  3417.     else if ( lstrcmp(szKeyValueName, TEXT("UpdateLogFile")) == 0 )
  3418.     {
  3419.       CHECK_KEY_TYPE( REG_SZ, szKeyValueName );
  3420.       opt_update_log = 1;
  3421.       COPY_KEY_VALUE( opt_update_logname );
  3422.     }
  3423.     else if ( lstrcmp(szKeyValueName, TEXT("BinaryLogFile")) == 0 )
  3424.     {
  3425.       CHECK_KEY_TYPE( REG_SZ, szKeyValueName );
  3426.       opt_bin_log = 1;
  3427.       COPY_KEY_VALUE( opt_bin_logname );
  3428.     }
  3429.     else if ( lstrcmp(szKeyValueName, TEXT("BinaryLogIndexFile")) == 0 )
  3430.     {
  3431.       CHECK_KEY_TYPE( REG_SZ, szKeyValueName );
  3432.       opt_bin_log = 1;
  3433.       COPY_KEY_VALUE( opt_binlog_index_name );
  3434.     }
  3435.     else if ( lstrcmp(szKeyValueName, TEXT("ISAMLogFile")) == 0 )
  3436.     {
  3437.       CHECK_KEY_TYPE( REG_SZ, szKeyValueName );
  3438.       COPY_KEY_VALUE( myisam_log_filename );
  3439.       opt_myisam_log=1;
  3440.     }
  3441.     else if ( lstrcmp(szKeyValueName, TEXT("LongLogFormat")) == 0 )
  3442.     {
  3443.       CHECK_KEY_TYPE( REG_DWORD, szKeyValueName );
  3444.       if ( *lpdwValue )
  3445.     opt_specialflag |= SPECIAL_LONG_LOG_FORMAT;
  3446.       else
  3447.     opt_specialflag &= ~((ulong)SPECIAL_LONG_LOG_FORMAT);
  3448.     }
  3449.     else if ( lstrcmp(szKeyValueName, TEXT("LowPriorityUpdates")) == 0 )
  3450.     {
  3451.       CHECK_KEY_TYPE( REG_DWORD, szKeyValueName );
  3452.       if ( *lpdwValue )
  3453.       {
  3454.     thd_startup_options |= OPTION_LOW_PRIORITY_UPDATES;
  3455.     low_priority_updates = 1;
  3456.       }
  3457.       else
  3458.       {
  3459.     thd_startup_options &= ~((ulong)OPTION_LOW_PRIORITY_UPDATES);
  3460.     low_priority_updates = 0;
  3461.       }
  3462.     }
  3463.     else if ( lstrcmp(szKeyValueName, TEXT("Port")) == 0 )
  3464.     {
  3465.       CHECK_KEY_TYPE( REG_DWORD, szKeyValueName );
  3466.       mysql_port = (unsigned int) *lpdwValue;
  3467.     }
  3468.     else if ( lstrcmp(szKeyValueName, TEXT("OldProtocol")) == 0 )
  3469.     {
  3470.       CHECK_KEY_TYPE( REG_DWORD, szKeyValueName );
  3471.       protocol_version = *lpdwValue ? PROTOCOL_VERSION - 1 : PROTOCOL_VERSION;
  3472.     }
  3473.     else if ( lstrcmp(szKeyValueName, TEXT("HostnameResolving")) == 0 )
  3474.     {
  3475.       CHECK_KEY_TYPE( REG_DWORD, szKeyValueName );
  3476.       if ( !*lpdwValue )
  3477.     opt_specialflag |= SPECIAL_NO_RESOLVE;
  3478.       else
  3479.     opt_specialflag &= ~((ulong)SPECIAL_NO_RESOLVE);
  3480.     }
  3481.     else if ( lstrcmp(szKeyValueName, TEXT("Networking")) == 0 )
  3482.     {
  3483.       CHECK_KEY_TYPE( REG_DWORD, szKeyValueName );
  3484.       opt_disable_networking = !(*lpdwValue);
  3485.     }
  3486.     else if ( lstrcmp(szKeyValueName, TEXT("ShowDatabase")) == 0 )
  3487.     {
  3488.       CHECK_KEY_TYPE( REG_DWORD, szKeyValueName );
  3489.       opt_skip_show_db = !(*lpdwValue);
  3490.     }
  3491.     else if ( lstrcmp(szKeyValueName, TEXT("HostnameCaching")) == 0 )
  3492.     {
  3493.       CHECK_KEY_TYPE( REG_DWORD, szKeyValueName );
  3494.       if ( !*lpdwValue )
  3495.     opt_specialflag |= SPECIAL_NO_HOST_CACHE;
  3496.       else
  3497.     opt_specialflag &= ~((ulong)SPECIAL_NO_HOST_CACHE);
  3498.     }
  3499.     else if ( lstrcmp(szKeyValueName, TEXT("ThreadPriority")) == 0 )
  3500.     {
  3501.       CHECK_KEY_TYPE( REG_DWORD, szKeyValueName );
  3502.       if ( !(*lpdwValue) )
  3503.     opt_specialflag |= SPECIAL_NO_PRIOR;
  3504.       else
  3505.     opt_specialflag &= ~((ulong)SPECIAL_NO_PRIOR);
  3506.     }
  3507.     else if ( lstrcmp(szKeyValueName, TEXT("NamedPipe")) == 0 )
  3508.     {
  3509.       CHECK_KEY_TYPE( REG_SZ, szKeyValueName );
  3510.       COPY_KEY_VALUE( mysql_unix_port );
  3511.     }
  3512.     else if ( lstrcmp(szKeyValueName, TEXT("TempDir")) == 0 )
  3513.     {
  3514.       CHECK_KEY_TYPE( REG_SZ, szKeyValueName );
  3515.       COPY_KEY_VALUE( mysql_tmpdir );
  3516.     }
  3517.     else if ( lstrcmp(szKeyValueName, TEXT("FlushTables")) == 0 )
  3518.     {
  3519.       CHECK_KEY_TYPE( REG_DWORD, szKeyValueName );
  3520.       nisam_flush = myisam_flush= *lpdwValue ? 1 : 0;
  3521.     }
  3522.     else if ( lstrcmp(szKeyValueName, TEXT("BackLog")) == 0 )
  3523.     {
  3524.       SET_CHANGEABLE_VARVAL( "back_log" );
  3525.     }
  3526.     else if ( lstrcmp(szKeyValueName, TEXT("ConnectTimeout")) == 0 )
  3527.     {
  3528.       SET_CHANGEABLE_VARVAL( "connect_timeout" );
  3529.     }
  3530.     else if ( lstrcmp(szKeyValueName, TEXT("JoinBufferSize")) == 0 )
  3531.     {
  3532.       SET_CHANGEABLE_VARVAL( "join_buffer" );
  3533.     }
  3534.     else if ( lstrcmp(szKeyValueName, TEXT("KeyBufferSize")) == 0 )
  3535.     {
  3536.       SET_CHANGEABLE_VARVAL( "key_buffer" );
  3537.     }
  3538.     else if ( lstrcmp(szKeyValueName, TEXT("LongQueryTime")) == 0 )
  3539.     {
  3540.       SET_CHANGEABLE_VARVAL( "long_query_time" );
  3541.     }
  3542.     else if ( lstrcmp(szKeyValueName, TEXT("MaxAllowedPacket")) == 0 )
  3543.     {
  3544.       SET_CHANGEABLE_VARVAL( "max_allowed_packet" );
  3545.     }
  3546.     else if ( lstrcmp(szKeyValueName, TEXT("MaxConnections")) == 0 )
  3547.     {
  3548.       SET_CHANGEABLE_VARVAL( "max_connections" );
  3549.     }
  3550.     else if ( lstrcmp(szKeyValueName, TEXT("MaxConnectErrors")) == 0 )
  3551.     {
  3552.       SET_CHANGEABLE_VARVAL( "max_connect_errors" );
  3553.     }
  3554.     else if ( lstrcmp(szKeyValueName, TEXT("MaxInsertDelayedThreads")) == 0 )
  3555.     {
  3556.       SET_CHANGEABLE_VARVAL( "max_delayed_threads" );
  3557.     }
  3558.     else if ( lstrcmp(szKeyValueName, TEXT("MaxJoinSize")) == 0 )
  3559.     {
  3560.       SET_CHANGEABLE_VARVAL( "max_join_size" );
  3561.     }
  3562.     else if ( lstrcmp(szKeyValueName, TEXT("MaxSortLength")) == 0 )
  3563.     {
  3564.       SET_CHANGEABLE_VARVAL( "max_sort_length" );
  3565.     }
  3566.     else if ( lstrcmp(szKeyValueName, TEXT("NetBufferLength")) == 0 )
  3567.     {
  3568.       SET_CHANGEABLE_VARVAL( "net_buffer_length" );
  3569.     }
  3570.     else if ( lstrcmp(szKeyValueName, TEXT("RecordBufferSize")) == 0 )
  3571.     {
  3572.       SET_CHANGEABLE_VARVAL( "record_buffer" );
  3573.     }
  3574.     else if ( lstrcmp(szKeyValueName, TEXT("SortBufferSize")) == 0 )
  3575.     {
  3576.       SET_CHANGEABLE_VARVAL( "sort_buffer" );
  3577.     }
  3578.     else if ( lstrcmp(szKeyValueName, TEXT("TableCacheSize")) == 0 )
  3579.     {
  3580.       SET_CHANGEABLE_VARVAL( "table_cache" );
  3581.     }
  3582.     else if ( lstrcmp(szKeyValueName, TEXT("TmpTableSize")) == 0 )
  3583.     {
  3584.       SET_CHANGEABLE_VARVAL( "tmp_table_size" );
  3585.     }
  3586.     else if ( lstrcmp(szKeyValueName, TEXT("ThreadStackSize")) == 0 )
  3587.     {
  3588.       SET_CHANGEABLE_VARVAL( "thread_stack" );
  3589.     }
  3590.     else if ( lstrcmp(szKeyValueName, TEXT("WaitTimeout")) == 0 )
  3591.     {
  3592.       SET_CHANGEABLE_VARVAL( "wait_timeout" );
  3593.     }
  3594.     else if ( lstrcmp(szKeyValueName, TEXT("DelayedInsertTimeout"))
  3595.           == 0 )
  3596.     {
  3597.       SET_CHANGEABLE_VARVAL( "delayed_insert_timeout" );
  3598.     }
  3599.     else if ( lstrcmp(szKeyValueName, TEXT("DelayedInsertLimit")) ==
  3600.           0 )
  3601.     {
  3602.       SET_CHANGEABLE_VARVAL( "delayed_insert_limit" );
  3603.     }
  3604.     else if ( lstrcmp(szKeyValueName, TEXT("DelayedQueueSize")) == 0
  3605.           )
  3606.     {
  3607.       SET_CHANGEABLE_VARVAL( "delayed_queue_size" );
  3608.     }
  3609.     else if ( lstrcmp(szKeyValueName, TEXT("FlushTime")) == 0 )
  3610.     {
  3611.       SET_CHANGEABLE_VARVAL( "flush_time" );
  3612.     }
  3613.     else if ( lstrcmp(szKeyValueName, TEXT("InteractiveTimeout")) ==
  3614.           0 )
  3615.     {
  3616.       SET_CHANGEABLE_VARVAL( "interactive_timeout" );
  3617.     }
  3618.     else if ( lstrcmp(szKeyValueName, TEXT("LowerCaseTableNames"))
  3619.           == 0 )
  3620.     {
  3621.       SET_CHANGEABLE_VARVAL( "lower_case_table_names" );
  3622.     }
  3623.     else if ( lstrcmp(szKeyValueName, TEXT("MaxHeapTableSize")) == 0
  3624.           )
  3625.     {
  3626.       SET_CHANGEABLE_VARVAL( "max_heap_table_size" );
  3627.     }
  3628.     else if ( lstrcmp(szKeyValueName, TEXT("MaxTmpTables")) == 0 )
  3629.     {
  3630.       SET_CHANGEABLE_VARVAL( "max_tmp_tables" );
  3631.     }
  3632.     else if ( lstrcmp(szKeyValueName, TEXT("MaxWriteLockCount")) ==
  3633.           0 )
  3634.     {
  3635.       SET_CHANGEABLE_VARVAL( "max_write_lock_count" );
  3636.     }
  3637.     else if ( lstrcmp(szKeyValueName, TEXT("NetRetryCount")) == 0 )
  3638.     {
  3639.       SET_CHANGEABLE_VARVAL( "net_retry_count" );
  3640.     }
  3641.     else if ( lstrcmp(szKeyValueName, TEXT("QueryBufferSize")) == 0
  3642.           )
  3643.     {
  3644.       SET_CHANGEABLE_VARVAL( "query_buffer_size" );
  3645.     }
  3646.     else if ( lstrcmp(szKeyValueName, TEXT("ThreadConcurrency")) ==
  3647.           0 )
  3648.     {
  3649.       SET_CHANGEABLE_VARVAL( "thread_concurrency" );
  3650.     }
  3651.     else
  3652.     {
  3653.       TCHAR szErrorMsg [ 512 ];
  3654.       RegCloseKey( hParametersKey );
  3655.       lstrcpy( szErrorMsg, TEXT("Value \"") );
  3656.       lstrcat( szErrorMsg, szKeyValueName );
  3657.       lstrcat( szErrorMsg, TEXT("\" of registry key \"" KEY_SERVICE_PARAMETERS "\" is not defined by MySQL\n") );
  3658.       fprintf( stderr, szErrorMsg ); /* not unicode compatible */
  3659.       return 1;
  3660.     }
  3661.  
  3662.     dwIndex++;
  3663.     dwKeyValueName = sizeof( szKeyValueName ) / sizeof( TCHAR );
  3664.     dwKeyValueBuffer = sizeof( bKeyValueBuffer );
  3665.   }
  3666.   RegCloseKey( hParametersKey );
  3667.  
  3668.   /* paths are fixed by method get_options() */
  3669.   return 0;
  3670. }
  3671. #endif
  3672.  
  3673.  
  3674. static char *get_relative_path(const char *path)
  3675. {
  3676.   if (test_if_hard_path(path) &&
  3677.       is_prefix(path,DEFAULT_MYSQL_HOME) &&
  3678.       strcmp(DEFAULT_MYSQL_HOME,FN_ROOTDIR))
  3679.   {
  3680.     path+=(uint) strlen(DEFAULT_MYSQL_HOME);
  3681.     while (*path == FN_LIBCHAR)
  3682.       path++;
  3683.   }
  3684.   return (char*) path;
  3685. }
  3686.  
  3687.  
  3688. static void fix_paths(void)
  3689. {
  3690.   (void) fn_format(mysql_home,mysql_home,"","",16); // Remove symlinks
  3691.   convert_dirname(mysql_home);
  3692.   convert_dirname(mysql_real_data_home);
  3693.   convert_dirname(language);
  3694.   (void) my_load_path(mysql_home,mysql_home,""); // Resolve current dir
  3695.   (void) my_load_path(mysql_real_data_home,mysql_real_data_home,mysql_home);
  3696.   (void) my_load_path(pidfile_name,pidfile_name,mysql_real_data_home);
  3697.  
  3698.   char buff[FN_REFLEN],*sharedir=get_relative_path(SHAREDIR);
  3699.   if (test_if_hard_path(sharedir))
  3700.     strmov(buff,sharedir);            /* purecov: tested */
  3701.   else
  3702.     strxmov(buff,mysql_home,sharedir,NullS);
  3703.   convert_dirname(buff);
  3704.   (void) my_load_path(language,language,buff);
  3705.  
  3706.   /* If --character-sets-dir isn't given, use shared library dir */
  3707.   if (charsets_dir != mysql_charsets_dir)
  3708.   {
  3709.     strmov(strmov(mysql_charsets_dir,buff),CHARSET_DIR);
  3710.     charsets_dir=mysql_charsets_dir;
  3711.   }
  3712.  
  3713.   /* Add '/' to TMPDIR if needed */
  3714.   char *tmp= (char*) my_malloc(FN_REFLEN,MYF(MY_FAE));
  3715.   if (tmp)
  3716.   {
  3717.     strmov(tmp,mysql_tmpdir);
  3718.     mysql_tmpdir=tmp;
  3719.     convert_dirname(mysql_tmpdir);
  3720.     mysql_tmpdir=(char*) my_realloc(mysql_tmpdir,(uint) strlen(mysql_tmpdir)+1,
  3721.                     MYF(MY_HOLD_ON_ERROR));
  3722.   }
  3723. }
  3724.  
  3725.  
  3726. #ifdef SET_RLIMIT_NOFILE
  3727. static uint set_maximum_open_files(uint max_file_limit)
  3728. {
  3729.   struct rlimit rlimit;
  3730.   ulong old_cur;
  3731.  
  3732.   if (!getrlimit(RLIMIT_NOFILE,&rlimit))
  3733.   {
  3734.     old_cur=rlimit.rlim_cur;
  3735.     if (rlimit.rlim_cur >= max_file_limit)    // Nothing to do
  3736.       return rlimit.rlim_cur;            /* purecov: inspected */
  3737.     rlimit.rlim_cur=rlimit.rlim_max=max_file_limit;
  3738.     if (setrlimit(RLIMIT_NOFILE,&rlimit))
  3739.     {
  3740.       sql_print_error("Warning: setrlimit couldn't increase number of open files to more than %ld",
  3741.           old_cur);        /* purecov: inspected */
  3742.       max_file_limit=old_cur;
  3743.     }
  3744.     else
  3745.     {
  3746.       (void) getrlimit(RLIMIT_NOFILE,&rlimit);
  3747.       if ((uint) rlimit.rlim_cur != max_file_limit)
  3748.     sql_print_error("Warning: setrlimit returned ok, but didn't change limits. Max open files is %ld",
  3749.               (ulong) rlimit.rlim_cur); /* purecov: inspected */
  3750.       max_file_limit=rlimit.rlim_cur;
  3751.     }
  3752.   }
  3753.   return max_file_limit;
  3754. }
  3755. #endif
  3756.  
  3757.  
  3758.     /*
  3759.       Return a bitfield from a string of substrings separated by ','
  3760.       returns ~(ulong) 0 on error.
  3761.     */
  3762.  
  3763. static ulong find_bit_type(const char *x, TYPELIB *bit_lib)
  3764. {
  3765.   bool found_end;
  3766.   int  found_count;
  3767.   const char *end,*i,*j;
  3768.   const char **array, *pos;
  3769.   ulong found,found_int,bit;
  3770.   DBUG_ENTER("find_bit_type");
  3771.   DBUG_PRINT("enter",("x: '%s'",x));
  3772.  
  3773.   found=0;
  3774.   found_end= 0;
  3775.   pos=(my_string) x;
  3776.   do
  3777.   {
  3778.     if (!*(end=strcend(pos,',')))        /* Let end point at fieldend */
  3779.     {
  3780.       while (end > pos && end[-1] == ' ')
  3781.     end--;                    /* Skipp end-space */
  3782.       found_end=1;
  3783.     }
  3784.     found_int=0; found_count=0;
  3785.     for (array=bit_lib->type_names, bit=1 ; (i= *array++) ; bit<<=1)
  3786.     {
  3787.       j=pos;
  3788.       while (j != end)
  3789.       {
  3790.     if (toupper(*i++) != toupper(*j++))
  3791.       goto skipp;
  3792.       }
  3793.       found_int=bit;
  3794.       if (! *i)
  3795.       {
  3796.     found_count=1;
  3797.     break;
  3798.       }
  3799.       else if (j != pos)            // Half field found
  3800.       {
  3801.     found_count++;                // Could be one of two values
  3802.       }
  3803. skipp: ;
  3804.     }
  3805.     if (found_count != 1)
  3806.       DBUG_RETURN(~(ulong) 0);                // No unique value
  3807.     found|=found_int;
  3808.     pos=end+1;
  3809.   } while (! found_end);
  3810.  
  3811.   DBUG_PRINT("exit",("bit-field: %ld",(ulong) found));
  3812.   DBUG_RETURN(found);
  3813. } /* find_bit_type */
  3814.  
  3815.  
  3816. /*****************************************************************************
  3817. ** Instantiate templates
  3818. *****************************************************************************/
  3819.  
  3820. #ifdef __GNUC__
  3821. /* Used templates */
  3822. template class I_List<THD>;
  3823. template class I_List_iterator<THD>;
  3824. template class I_List<i_string>;
  3825. template class I_List<i_string_pair>;
  3826. #endif
  3827.