mysqld.cc
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:130k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. #include "mysql_priv.h"
  14. #include <mysql.h>
  15. #include <m_ctype.h>
  16. #include "sql_acl.h"
  17. #include "slave.h"
  18. #ifdef HAVE_BERKELEY_DB
  19. #include "ha_berkeley.h"
  20. #endif
  21. #ifdef HAVE_INNOBASE_DB
  22. #include "ha_innobase.h"
  23. #endif
  24. #include "ha_myisam.h"
  25. #include <nisam.h>
  26. #include <thr_alarm.h>
  27. #include <ft_global.h>
  28. #ifndef DBUG_OFF
  29. #define ONE_THREAD
  30. #endif
  31. extern "C" { // Because of SCO 3.2V4.2
  32. #include <errno.h>
  33. #include <sys/stat.h>
  34. #ifndef __GNU_LIBRARY__
  35. #define __GNU_LIBRARY__ // Skip warnings in getopt.h
  36. #endif
  37. #include <getopt.h>
  38. #ifdef HAVE_SYSENT_H
  39. #include <sysent.h>
  40. #endif
  41. #ifdef HAVE_PWD_H
  42. #include <pwd.h> // For getpwent
  43. #endif
  44. #ifdef HAVE_GRP_H
  45. #include <grp.h>
  46. #endif
  47. #ifndef __WIN__
  48. #include <sys/resource.h>
  49. #ifdef HAVE_SYS_UN_H
  50. #  include <sys/un.h>
  51. #endif
  52. #include <netdb.h>
  53. #ifdef HAVE_SELECT_H
  54. #  include <select.h>
  55. #endif
  56. #ifdef HAVE_SYS_SELECT_H
  57. #include <sys/select.h>
  58. #endif
  59. #include <sys/utsname.h>
  60. #else
  61. #include <windows.h>
  62. #endif // __WIN__
  63. #ifdef HAVE_LIBWRAP
  64. #include <tcpd.h>
  65. #include <syslog.h>
  66. #ifdef NEED_SYS_SYSLOG_H
  67. #include <sys/syslog.h>
  68. #endif /* NEED_SYS_SYSLOG_H */
  69. int allow_severity = LOG_INFO;
  70. int deny_severity = LOG_WARNING;
  71. #endif /* HAVE_LIBWRAP */
  72. #ifdef HAVE_SYS_MMAN_H
  73. #include <sys/mman.h>
  74. #endif
  75. #if defined(__FreeBSD__) && defined(HAVE_IEEEFP_H)
  76. #include <ieeefp.h>
  77. #ifdef HAVE_FP_EXCEPT // Fix type conflict
  78. typedef fp_except fp_except_t;
  79. #endif
  80.   /* We can't handle floating point expections with threads, so disable
  81.      this on freebsd
  82.   */
  83. inline void reset_floating_point_exceptions()
  84. {
  85.   /* Don't fall for overflow, underflow,divide-by-zero or loss of precision */
  86.   fpsetmask(~(FP_X_INV | FP_X_DNML | FP_X_OFL | FP_X_UFL |
  87.       FP_X_DZ | FP_X_IMP));
  88. }
  89. #else
  90. #define reset_floating_point_exceptions()
  91. #endif /* __FreeBSD__ && HAVE_IEEEFP_H */
  92. } /* cplusplus */
  93. #if defined(HAVE_LINUXTHREADS)
  94. #define THR_KILL_SIGNAL SIGINT
  95. #else
  96. #define THR_KILL_SIGNAL SIGUSR2 // Can't use this with LinuxThreads
  97. #endif
  98. #ifdef HAVE_GLIBC2_STYLE_GETHOSTBYNAME_R
  99. #include <sys/types.h>
  100. #else
  101. #include <my_pthread.h> // For thr_setconcurency()
  102. #endif
  103. #if defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE) && !defined(HAVE_mit_thread)
  104. #define SET_RLIMIT_NOFILE
  105. #endif
  106. #ifdef SOLARIS
  107. extern "C" int gethostname(char *name, int namelen);
  108. #endif
  109. #define MYSQL_KILL_SIGNAL SIGTERM
  110. #ifndef DBUG_OFF
  111. static const char* default_dbug_option=IF_WIN("d:t:i:O,\mysqld.trace",
  112.       "d:t:i:o,/tmp/mysqld.trace");
  113. #endif
  114. #ifdef __NT__
  115. static char szPipeName [ 257 ];
  116. static SECURITY_ATTRIBUTES saPipeSecurity;
  117. static SECURITY_DESCRIPTOR sdPipeDescriptor;
  118. static HANDLE hPipe = INVALID_HANDLE_VALUE;
  119. static pthread_cond_t COND_handler_count;
  120. static uint handler_count;
  121. #endif
  122. #ifdef __WIN__
  123. static bool opt_console=0;
  124. #endif
  125. #ifdef HAVE_BERKELEY_DB
  126. SHOW_COMP_OPTION have_berkeley_db=SHOW_OPTION_YES;
  127. #else
  128. SHOW_COMP_OPTION have_berkeley_db=SHOW_OPTION_NO;
  129. #endif
  130. #ifdef HAVE_GEMINI_DB
  131. SHOW_COMP_OPTION have_gemini=SHOW_OPTION_YES;
  132. #else
  133. SHOW_COMP_OPTION have_gemini=SHOW_OPTION_NO;
  134. #endif
  135. #ifdef HAVE_INNOBASE_DB
  136. SHOW_COMP_OPTION have_innobase=SHOW_OPTION_YES;
  137. #else
  138. SHOW_COMP_OPTION have_innobase=SHOW_OPTION_NO;
  139. #endif
  140. #ifndef NO_ISAM
  141. SHOW_COMP_OPTION have_isam=SHOW_OPTION_YES;
  142. #else
  143. SHOW_COMP_OPTION have_isam=SHOW_OPTION_NO;
  144. #endif
  145. #ifdef USE_RAID
  146. SHOW_COMP_OPTION have_raid=SHOW_OPTION_YES;
  147. #else
  148. SHOW_COMP_OPTION have_raid=SHOW_OPTION_NO;
  149. #endif
  150. #ifdef HAVE_OPENSSL
  151. SHOW_COMP_OPTION have_ssl=SHOW_OPTION_YES;
  152. #else
  153. SHOW_COMP_OPTION have_ssl=SHOW_OPTION_NO;
  154. #endif
  155. static bool opt_skip_slave_start = 0; // if set, slave is not autostarted
  156. static ulong opt_specialflag=SPECIAL_ENGLISH;
  157. static my_socket unix_sock= INVALID_SOCKET,ip_sock= INVALID_SOCKET;
  158. static ulong back_log,connect_timeout,concurrency;
  159. static my_string opt_logname=0,opt_update_logname=0,
  160.        opt_binlog_index_name = 0,opt_slow_logname=0;
  161. static char mysql_home[FN_REFLEN],pidfile_name[FN_REFLEN];
  162. static pthread_t select_thread;
  163. static bool opt_log,opt_update_log,opt_bin_log,opt_slow_log,opt_noacl,
  164.     opt_disable_networking=0, opt_bootstrap=0,opt_skip_show_db=0,
  165.             opt_ansi_mode=0,opt_myisam_log=0,
  166.             opt_large_files=sizeof(my_off_t) > 4;
  167. bool opt_sql_bin_update = 0, opt_log_slave_updates = 0, opt_safe_show_db=0;
  168. FILE *bootstrap_file=0;
  169. int segfaulted = 0; // ensure we do not enter SIGSEGV handler twice
  170. extern MASTER_INFO glob_mi;
  171. extern int init_master_info(MASTER_INFO* mi);
  172. // if sql_bin_update is true, SQL_LOG_UPDATE and SQL_LOG_BIN are kept in sync,
  173. // and are treated as aliases for each other
  174. static bool kill_in_progress=FALSE;
  175. static struct rand_struct sql_rand;
  176. static int cleanup_done;
  177. static char **defaults_argv,time_zone[30];
  178. static const char *default_table_type_name;
  179. static char glob_hostname[FN_REFLEN];
  180. #ifdef HAVE_OPENSSL
  181. static bool opt_use_ssl = FALSE;
  182. static char *opt_ssl_key = 0;
  183. static char *opt_ssl_cert = 0;
  184. static char *opt_ssl_ca = 0;
  185. static char *opt_ssl_capath = 0;
  186. static VioSSLAcceptorFd* ssl_acceptor_fd = 0;
  187. #endif /* HAVE_OPENSSL */
  188. I_List <i_string_pair> replicate_rewrite_db;
  189. I_List<i_string> replicate_do_db, replicate_ignore_db;
  190. // allow the user to tell us which db to replicate and which to ignore
  191. I_List<i_string> binlog_do_db, binlog_ignore_db;
  192. /* if we guessed server_id , we need to know about it */
  193. uint32 server_id = 0;
  194. bool server_id_supplied = 0;
  195. uint mysql_port;
  196. uint test_flags, select_errors=0, dropping_tables=0,ha_open_options=0;
  197. uint volatile thread_count=0, thread_running=0, kill_cached_threads=0,
  198.       wake_thread=0, global_read_lock=0;
  199. ulong thd_startup_options=(OPTION_UPDATE_LOG | OPTION_AUTO_IS_NULL |
  200.    OPTION_BIN_LOG | OPTION_QUOTE_SHOW_CREATE );
  201. uint protocol_version=PROTOCOL_VERSION;
  202. ulong keybuff_size,sortbuff_size,max_item_sort_length,table_cache_size,
  203.       max_join_size,join_buff_size,tmp_table_size,thread_stack,
  204.       thread_stack_min,net_wait_timeout,what_to_log= ~ (1L << (uint) COM_TIME),
  205.       query_buff_size, lower_case_table_names, mysqld_net_retry_count,
  206.       net_interactive_timeout, slow_launch_time = 2L,
  207.       net_read_timeout,net_write_timeout,slave_open_temp_tables=0,
  208.       open_files_limit=0, max_binlog_size;
  209. ulong thread_cache_size=0, binlog_cache_size=0, max_binlog_cache_size=0;
  210. volatile ulong cached_thread_count=0;
  211. // replication parameters, if master_host is not NULL, we are a slave
  212. my_string master_user = (char*) "test", master_password = 0, master_host=0,
  213.   master_info_file = (char*) "master.info";
  214. const char *localhost=LOCAL_HOST;
  215. const char *delayed_user="DELAYED";
  216. uint master_port = MYSQL_PORT, master_connect_retry = 60;
  217. ulong max_tmp_tables,max_heap_table_size;
  218. ulong bytes_sent = 0L, bytes_received = 0L;
  219. bool opt_endinfo,using_udf_functions,low_priority_updates, locked_in_memory;
  220. bool opt_using_transactions;
  221. bool volatile abort_loop,select_thread_in_use,grant_option;
  222. bool volatile ready_to_exit,shutdown_in_progress;
  223. ulong refresh_version=1L,flush_version=1L; /* Increments on each reload */
  224. ulong query_id=1L,long_query_count,long_query_time,aborted_threads,
  225.       aborted_connects,delayed_insert_timeout,delayed_insert_limit,
  226.       delayed_queue_size,delayed_insert_threads,delayed_insert_writes,
  227.       delayed_rows_in_use,delayed_insert_errors,flush_time, thread_created;
  228. ulong filesort_rows, filesort_range_count, filesort_scan_count;
  229. ulong filesort_merge_passes;
  230. ulong select_range_check_count, select_range_count, select_scan_count;
  231. ulong select_full_range_join_count,select_full_join_count;
  232. ulong specialflag=0,opened_tables=0,created_tmp_tables=0,
  233.       created_tmp_disk_tables=0;
  234. ulong max_connections,max_insert_delayed_threads,max_used_connections,
  235.       max_connect_errors, max_user_connections = 0;
  236. ulong thread_id=1L,current_pid;
  237. ulong slow_launch_threads = 0;
  238. char mysql_real_data_home[FN_REFLEN],
  239.      mysql_data_home[2],language[LIBLEN],reg_ext[FN_EXTLEN],
  240.      default_charset[LIBLEN],mysql_charsets_dir[FN_REFLEN], *charsets_list,
  241.      blob_newline,f_fyllchar,max_sort_char,*mysqld_user,*mysqld_chroot,
  242.      *opt_init_file;
  243. char *opt_bin_logname = 0; // this one needs to be seen in sql_parse.cc
  244. char server_version[SERVER_VERSION_LENGTH]=MYSQL_SERVER_VERSION;
  245. const char *first_keyword="first";
  246. const char **errmesg; /* Error messages */
  247. const char *myisam_recover_options_str="OFF";
  248. my_string mysql_unix_port=NULL,mysql_tmpdir=NULL;
  249. ulong my_bind_addr; /* the address we bind to */
  250. DATE_FORMAT dayord;
  251. double log_10[32]; /* 10 potences */
  252. I_List<THD> threads,thread_cache;
  253. time_t start_time;
  254. MY_BITMAP temp_pool;
  255. bool use_temp_pool=0;
  256. pthread_key(MEM_ROOT*,THR_MALLOC);
  257. pthread_key(THD*, THR_THD);
  258. pthread_key(NET*, THR_NET);
  259. pthread_mutex_t LOCK_mysql_create_db, LOCK_Acl, LOCK_open, LOCK_thread_count,
  260. LOCK_mapped_file, LOCK_status, LOCK_grant,
  261. LOCK_error_log,
  262. LOCK_delayed_insert, LOCK_delayed_status, LOCK_delayed_create,
  263. LOCK_crypt, LOCK_bytes_sent, LOCK_bytes_received,
  264.                 LOCK_binlog_update, LOCK_slave, LOCK_server_id,
  265. LOCK_user_conn;
  266. pthread_cond_t COND_refresh,COND_thread_count,COND_binlog_update,
  267.   COND_slave_stopped, COND_slave_start;
  268. pthread_cond_t COND_thread_cache,COND_flush_thread_cache;
  269. pthread_t signal_thread;
  270. pthread_attr_t connection_attrib;
  271. enum db_type default_table_type=DB_TYPE_MYISAM;
  272. #ifdef __WIN__
  273. #undef  getpid
  274. #include <process.h>
  275. HANDLE hEventShutdown;
  276. #include "nt_servc.h"
  277. static  NTService  Service;       // Service object for WinNT
  278. #endif
  279. static void *signal_hand(void *arg);
  280. static void set_options(void);
  281. static void get_options(int argc,char **argv);
  282. static char *get_relative_path(const char *path);
  283. static void fix_paths(void);
  284. static pthread_handler_decl(handle_connections_sockets,arg);
  285. static int bootstrap(FILE *file);
  286. static bool read_init_file(char *file_name);
  287. #ifdef __NT__
  288. static pthread_handler_decl(handle_connections_namedpipes,arg);
  289. #endif
  290. #ifdef __WIN__
  291. static int get_service_parameters();
  292. #endif
  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. ** Code to end mysqld
  300. ****************************************************************************/
  301. static void close_connections(void)
  302. {
  303. #ifdef EXTRA_DEBUG
  304.   int count=0;
  305. #endif
  306.   NET net;
  307.   DBUG_ENTER("close_connections");
  308.   /* Clear thread cache */
  309.   kill_cached_threads++;
  310.   flush_thread_cache();
  311.   /* kill flush thread */
  312.   (void) pthread_mutex_lock(&LOCK_manager);
  313.   if (manager_thread_in_use)
  314.   {
  315.     DBUG_PRINT("quit",("killing manager thread: %lx",manager_thread));
  316.    (void) pthread_cond_signal(&COND_manager);
  317.   }
  318.   (void) pthread_mutex_unlock(&LOCK_manager);
  319.   /* kill connection thread */
  320. #if !defined(__WIN__) && !defined(__EMX__)
  321.   DBUG_PRINT("quit",("waiting for select thread: %lx",select_thread));
  322.   (void) pthread_mutex_lock(&LOCK_thread_count);
  323.   while (select_thread_in_use)
  324.   {
  325.     struct timespec abstime;
  326.     int error;
  327.     LINT_INIT(error);
  328. #ifndef DONT_USE_THR_ALARM
  329.     if (pthread_kill(select_thread,THR_CLIENT_ALARM))
  330.       break; // allready dead
  331. #endif
  332. #ifdef HAVE_TIMESPEC_TS_SEC
  333.     abstime.ts_sec=time(NULL)+2; // Bsd 2.1
  334.     abstime.ts_nsec=0;
  335. #else
  336.     struct timeval tv;
  337.     gettimeofday(&tv,0);
  338.     abstime.tv_sec=tv.tv_sec+2;
  339.     abstime.tv_nsec=tv.tv_usec*1000;
  340. #endif
  341.     for (uint tmp=0 ; tmp < 10 ; tmp++)
  342.     {
  343.       error=pthread_cond_timedwait(&COND_thread_count,&LOCK_thread_count,
  344.    &abstime);
  345.       if (error != EINTR)
  346. break;
  347.     }
  348. #ifdef EXTRA_DEBUG
  349.     if (error != 0 && !count++)
  350.       sql_print_error("Got error %d from pthread_cond_timedwait",error);
  351. #endif
  352. #if defined(AIX_3_2) || defined(HAVE_DEC_3_2_THREADS)
  353.     if (ip_sock != INVALID_SOCKET)
  354.     {
  355.       DBUG_PRINT("error",("closing TCP/IP and socket files"));
  356.       VOID(shutdown(ip_sock,2));
  357.       VOID(closesocket(ip_sock));
  358.       VOID(shutdown(unix_sock,2));
  359.       VOID(closesocket(unix_sock));
  360.       VOID(unlink(mysql_unix_port));
  361.       ip_sock=unix_sock= INVALID_SOCKET;
  362.     }
  363. #endif
  364.   }
  365.   (void) pthread_mutex_unlock(&LOCK_thread_count);
  366. #endif /* __WIN__ */
  367.   /* Abort listening to new connections */
  368.   DBUG_PRINT("quit",("Closing sockets"));
  369.   if ( !opt_disable_networking )
  370.   {
  371.     if (ip_sock != INVALID_SOCKET)
  372.     {
  373.       (void) shutdown(ip_sock,2);
  374.       (void) closesocket(ip_sock);
  375.       ip_sock= INVALID_SOCKET;
  376.     }
  377.   }
  378. #ifdef __NT__
  379.   if ( hPipe != INVALID_HANDLE_VALUE )
  380.   {
  381.     HANDLE hTempPipe = hPipe;
  382.     DBUG_PRINT( "quit", ("Closing named pipes") );
  383.     hPipe = INVALID_HANDLE_VALUE;
  384.     CancelIo( hTempPipe );
  385.     DisconnectNamedPipe( hTempPipe );
  386.     CloseHandle( hTempPipe );
  387.   }
  388. #endif
  389. #ifdef HAVE_SYS_UN_H
  390.   if (unix_sock != INVALID_SOCKET)
  391.   {
  392.     (void) shutdown(unix_sock,2);
  393.     (void) closesocket(unix_sock);
  394.     (void) unlink(mysql_unix_port);
  395.     unix_sock= INVALID_SOCKET;
  396.   }
  397. #endif
  398.   end_thr_alarm();  // Don't allow alarms
  399.   /* First signal all threads that it's time to die */
  400.   THD *tmp;
  401.   (void) pthread_mutex_lock(&LOCK_thread_count); // For unlink from list
  402.   I_List_iterator<THD> it(threads);
  403.   while ((tmp=it++))
  404.   {
  405.     DBUG_PRINT("quit",("Informing thread %ld that it's time to die",
  406.        tmp->thread_id));
  407.     tmp->killed=1;
  408.     if (tmp->mysys_var)
  409.     {
  410.       tmp->mysys_var->abort=1;
  411.       if (tmp->mysys_var->current_mutex)
  412.       {
  413. pthread_mutex_lock(tmp->mysys_var->current_mutex);
  414. pthread_cond_broadcast(tmp->mysys_var->current_cond);
  415. pthread_mutex_unlock(tmp->mysys_var->current_mutex);
  416.       }
  417.     }
  418.   }
  419.   (void) pthread_mutex_unlock(&LOCK_thread_count); // For unlink from list
  420.   if (thread_count)
  421.   {
  422.     sleep(1); // Give threads time to die
  423.   }
  424.   /* Force remaining threads to die by closing the connection to the client */
  425.   (void) my_net_init(&net, (Vio*) 0);
  426.   for (;;)
  427.   {
  428.     DBUG_PRINT("quit",("Locking LOCK_thread_count"));
  429.     (void) pthread_mutex_lock(&LOCK_thread_count); // For unlink from list
  430.     if (!(tmp=threads.get()))
  431.     {
  432.       DBUG_PRINT("quit",("Unlocking LOCK_thread_count"));
  433.       (void) pthread_mutex_unlock(&LOCK_thread_count);
  434.       break;
  435.     }
  436. #ifndef __bsdi__ // Bug in BSDI kernel
  437.     if ((net.vio=tmp->net.vio) != 0)
  438.     {
  439.       sql_print_error(ER(ER_FORCING_CLOSE),my_progname,
  440.       tmp->thread_id,tmp->user ? tmp->user : "");
  441.       close_connection(&net,0,0);
  442.     }
  443. #endif
  444.     DBUG_PRINT("quit",("Unlocking LOCK_thread_count"));
  445.     (void) pthread_mutex_unlock(&LOCK_thread_count);
  446.   }
  447.   net_end(&net);
  448.   /* All threads has now been aborted */
  449.   DBUG_PRINT("quit",("Waiting for threads to die (count=%u)",thread_count));
  450.   (void) pthread_mutex_lock(&LOCK_thread_count);
  451.   while (thread_count)
  452.   {
  453.     (void) pthread_cond_wait(&COND_thread_count,&LOCK_thread_count);
  454.     DBUG_PRINT("quit",("One thread died (count=%u)",thread_count));
  455.   }
  456.   (void) pthread_mutex_unlock(&LOCK_thread_count);
  457.   mysql_log.close(1);
  458.   mysql_update_log.close(1);
  459.   mysql_bin_log.close(1);
  460.   my_free(charsets_list, MYF(0));
  461.   DBUG_PRINT("quit",("close_connections thread"));
  462.   DBUG_VOID_RETURN;
  463. }
  464. void kill_mysql(void)
  465. {
  466.   DBUG_ENTER("kill_mysql");
  467. #if defined(__WIN__)
  468.   {
  469.     if (!SetEvent(hEventShutdown))
  470.     {
  471.       DBUG_PRINT("error",("Got error: %ld from SetEvent",GetLastError()));
  472.     }
  473.     // or:
  474.     // HANDLE hEvent=OpenEvent(0, FALSE, "MySqlShutdown");
  475.     // SetEvent(hEventShutdown);
  476.     // CloseHandle(hEvent);
  477.   }
  478. #elif defined(HAVE_PTHREAD_KILL)
  479.     if (pthread_kill(signal_thread,SIGTERM)) /* End everything nicely */
  480.     {
  481.       DBUG_PRINT("error",("Got error %d from pthread_kill",errno)); /* purecov: inspected */
  482.     }
  483. #else
  484.     kill(current_pid,SIGTERM);
  485. #endif
  486.     DBUG_PRINT("quit",("After pthread_kill"));
  487.     shutdown_in_progress=1; // Safety if kill didn't work
  488.     DBUG_VOID_RETURN;
  489. }
  490. /* Force server down. kill all connections and threads and exit */
  491. #ifndef __WIN__
  492. static void *kill_server(void *sig_ptr)
  493. #define RETURN_FROM_KILL_SERVER return 0
  494. #else
  495. static void __cdecl kill_server(int sig_ptr)
  496. #define RETURN_FROM_KILL_SERVER return
  497. #endif
  498. {
  499.   int sig=(int) (long) sig_ptr; // This is passed a int
  500.   DBUG_ENTER("kill_server");
  501.   // if there is a signal during the kill in progress, we do not need
  502.   // another one
  503.   if (kill_in_progress) // Safety
  504.     RETURN_FROM_KILL_SERVER;
  505.   kill_in_progress=TRUE;
  506.   abort_loop=1; // This should be set
  507.   signal(sig,SIG_IGN);
  508.   if (sig == MYSQL_KILL_SIGNAL || sig == 0)
  509.     sql_print_error(ER(ER_NORMAL_SHUTDOWN),my_progname);
  510.   else
  511.     sql_print_error(ER(ER_GOT_SIGNAL),my_progname,sig); /* purecov: inspected */
  512. #if defined(USE_ONE_SIGNAL_HAND) && !defined(__WIN__)
  513.   my_thread_init(); // If this is a new thread
  514. #endif
  515.   close_connections();
  516.   sql_print_error(ER(ER_SHUTDOWN_COMPLETE),my_progname);
  517.   if (sig != MYSQL_KILL_SIGNAL && sig != 0)
  518.     unireg_abort(1); /* purecov: inspected */
  519.   else
  520.     unireg_end(0);
  521.   pthread_exit(0); /* purecov: deadcode */
  522.   RETURN_FROM_KILL_SERVER;
  523. }
  524. #ifdef USE_ONE_SIGNAL_HAND
  525. pthread_handler_decl(kill_server_thread,arg __attribute__((unused)))
  526. {
  527.   my_thread_init(); // Initialize new thread
  528.   kill_server(0);
  529.   my_thread_end(); // Normally never reached
  530.   return 0;
  531. }
  532. #endif
  533. static sig_handler print_signal_warning(int sig)
  534. {
  535.   sql_print_error("Warning: Got signal %d from thread %d",
  536.   sig,my_thread_id());
  537. #ifdef DONT_REMEMBER_SIGNAL
  538.   sigset(sig,print_signal_warning); /* int. thread system calls */
  539. #endif
  540. #ifndef __WIN__
  541.   if (sig == SIGALRM)
  542.     alarm(2); /* reschedule alarm */
  543. #endif
  544. }
  545. void unireg_end(int signal_number __attribute__((unused)))
  546. {
  547.   clean_up();
  548.   pthread_exit(0); // Exit is in main thread
  549. }
  550. void unireg_abort(int exit_code)
  551. {
  552.   if (exit_code)
  553.     sql_print_error("Abortingn");
  554.   clean_up(); /* purecov: inspected */
  555.   exit(exit_code); /* purecov: inspected */
  556. }
  557. void clean_up(void)
  558. {
  559.   DBUG_PRINT("exit",("clean_up"));
  560.   if (cleanup_done++)
  561.     return; /* purecov: inspected */
  562.   acl_free(1);
  563.   grant_free();
  564.   sql_cache_free();
  565.   table_cache_free();
  566.   hostname_cache_free();
  567.   item_user_lock_free();
  568.   lex_free(); /* Free some memory */
  569. #ifdef HAVE_DLOPEN
  570.   if (!opt_noacl)
  571.     udf_free();
  572. #endif
  573.   end_key_cache(); /* This is usually freed automaticly */
  574.   (void) ha_panic(HA_PANIC_CLOSE); /* close all tables and logs */
  575. #ifdef USE_RAID
  576.   end_raid();
  577. #endif
  578.   x_free((gptr) my_errmsg[ERRMAPP]); /* Free messages */
  579.   free_defaults(defaults_argv);
  580.   my_free(mysql_tmpdir,MYF(0));
  581.   x_free(opt_bin_logname);
  582.   bitmap_free(&temp_pool);
  583.   free_max_user_conn();
  584. #ifndef __WIN__
  585.   if (!opt_bootstrap)
  586.     (void) my_delete(pidfile_name,MYF(0)); // This may not always exist
  587. #endif
  588.   end_slave();
  589.   my_thread_end();
  590.   /* Tell main we are ready */
  591.   (void) pthread_mutex_lock(&LOCK_thread_count);
  592.   ready_to_exit=1;
  593.   /* do the broadcast inside the lock to ensure that my_end() is not called */
  594.   (void) pthread_cond_broadcast(&COND_thread_count);
  595.   (void) pthread_mutex_unlock(&LOCK_thread_count);
  596. } /* clean_up */
  597. /****************************************************************************
  598. ** Init IP and UNIX socket
  599. ****************************************************************************/
  600. static void set_ports()
  601. {
  602.   char *env;
  603.   if (!mysql_port && !opt_disable_networking)
  604.   { // Get port if not from commandline
  605.     struct  servent *serv_ptr;
  606.     mysql_port = MYSQL_PORT;
  607.     if ((serv_ptr = getservbyname("mysql", "tcp")))
  608.       mysql_port = ntohs((u_short) serv_ptr->s_port); /* purecov: inspected */
  609.     if ((env = getenv("MYSQL_TCP_PORT")))
  610.       mysql_port = (uint) atoi(env); /* purecov: inspected */
  611.   }
  612.   if (!mysql_unix_port)
  613.   {
  614. #ifdef __WIN__
  615.     mysql_unix_port = (char*) MYSQL_NAMEDPIPE;
  616. #else
  617.     mysql_unix_port = (char*) MYSQL_UNIX_ADDR;
  618. #endif
  619.     if ((env = getenv("MYSQL_UNIX_PORT")))
  620.       mysql_unix_port = env; /* purecov: inspected */
  621.   }
  622. }
  623. /* Change to run as another user if started with --user */
  624. static void set_user(const char *user)
  625. {
  626. #ifndef __WIN__
  627.     struct passwd *ent;
  628.   // don't bother if we aren't superuser
  629.   if (geteuid())
  630.   {
  631.     if (user)
  632.       fprintf(stderr,
  633.       "Warning: One can only use the --user switch if running as rootn");
  634.     return;
  635.   }
  636.   else if (!user)
  637.   {
  638.     if (!opt_bootstrap)
  639.     {
  640.       fprintf(stderr,"Fatal error: Please read "Security" section of the manual to find out how to run mysqld as root!n");
  641.       unireg_abort(1);
  642.     }
  643.     return;
  644.   }
  645.   if (!strcmp(user,"root"))
  646.     return; // Avoid problem with dynamic libraries
  647.   if (!(ent = getpwnam(user)))
  648.   {
  649.     fprintf(stderr,"Fatal error: Can't change to run as user '%s' ;  Please check that the user exists!n",user);
  650.     unireg_abort(1);
  651.   }
  652. #ifdef HAVE_INITGROUPS
  653.   initgroups((char*) user,ent->pw_gid);
  654. #endif
  655.   if (setgid(ent->pw_gid) == -1)
  656.   {
  657.     sql_perror("setgid");
  658.     unireg_abort(1);
  659.   }
  660.   if (setuid(ent->pw_uid) == -1)
  661.   {
  662.     sql_perror("setuid");
  663.     unireg_abort(1);
  664.   }
  665. #endif
  666. }
  667. /* Change root user if started with  --chroot */
  668. static void set_root(const char *path)
  669. {
  670. #if !defined(__WIN__) && !defined(__EMX__)
  671.   if (chroot(path) == -1)
  672.   {
  673.     sql_perror("chroot");
  674.     unireg_abort(1);
  675.   }
  676. #endif
  677. }
  678. static void server_init(void)
  679. {
  680.   struct sockaddr_in IPaddr;
  681. #ifdef HAVE_SYS_UN_H
  682.   struct sockaddr_un UNIXaddr;
  683. #endif
  684.   int arg=1;
  685.   DBUG_ENTER("server_init");
  686. #ifdef __WIN__
  687.   if ( !opt_disable_networking )
  688.   {
  689.     WSADATA WsaData;
  690.     if (SOCKET_ERROR == WSAStartup (0x0101, &WsaData))
  691.     {
  692.       my_message(0,"WSAStartup Failedn",MYF(0));
  693.       unireg_abort(1);
  694.     }
  695.   }
  696. #endif /* __WIN__ */
  697.   set_ports();
  698.   if (mysql_port != 0 && !opt_disable_networking && !opt_bootstrap)
  699.   {
  700.     DBUG_PRINT("general",("IP Socket is %d",mysql_port));
  701.     ip_sock = socket(AF_INET, SOCK_STREAM, 0);
  702.     if (ip_sock == INVALID_SOCKET)
  703.     {
  704.       DBUG_PRINT("error",("Got error: %d from socket()",socket_errno));
  705.       sql_perror(ER(ER_IPSOCK_ERROR)); /* purecov: tested */
  706.       unireg_abort(1); /* purecov: tested */
  707.     }
  708.     bzero((char*) &IPaddr, sizeof(IPaddr));
  709.     IPaddr.sin_family = AF_INET;
  710.     IPaddr.sin_addr.s_addr = my_bind_addr;
  711.     IPaddr.sin_port = (unsigned short) htons((unsigned short) mysql_port);
  712.     (void) setsockopt(ip_sock,SOL_SOCKET,SO_REUSEADDR,(char*)&arg,sizeof(arg));
  713.     for(;;)
  714.     {
  715.       if (bind(ip_sock, my_reinterpret_cast(struct sockaddr *) (&IPaddr),
  716.        sizeof(IPaddr)) >= 0)
  717. break;
  718.       DBUG_PRINT("error",("Got error: %d from bind",socket_errno));
  719.       sql_perror("Can't start server: Bind on TCP/IP port");/* Had a loop here */
  720.       sql_print_error("Do you already have another mysqld server running on port: %d ?",mysql_port);
  721.       unireg_abort(1);
  722.     }
  723.     if (listen(ip_sock,(int) back_log) < 0)
  724.       sql_print_error("Warning:  listen() on TCP/IP failed with error %d",
  725.       errno);
  726.   }
  727.   if (mysqld_chroot)
  728.     set_root(mysqld_chroot);
  729.   set_user(mysqld_user); // set_user now takes care of mysqld_user==NULL
  730. #ifdef __NT__
  731.   /* create named pipe */
  732.   if (Service.IsNT() && mysql_unix_port[0] && !opt_bootstrap)
  733.   {
  734.     sprintf( szPipeName, "\\.\pipe\%s", mysql_unix_port );
  735.     ZeroMemory( &saPipeSecurity, sizeof(saPipeSecurity) );
  736.     ZeroMemory( &sdPipeDescriptor, sizeof(sdPipeDescriptor) );
  737.     if ( !InitializeSecurityDescriptor(&sdPipeDescriptor,
  738.        SECURITY_DESCRIPTOR_REVISION) )
  739.     {
  740.       sql_perror("Can't start server : Initialize security descriptor");
  741.       unireg_abort(1);
  742.     }
  743.     if (!SetSecurityDescriptorDacl(&sdPipeDescriptor, TRUE, NULL, FALSE))
  744.     {
  745.       sql_perror("Can't start server : Set security descriptor");
  746.       unireg_abort(1);
  747.     }
  748.     saPipeSecurity.nLength = sizeof( SECURITY_ATTRIBUTES );
  749.     saPipeSecurity.lpSecurityDescriptor = &sdPipeDescriptor;
  750.     saPipeSecurity.bInheritHandle = FALSE;
  751.     if ((hPipe = CreateNamedPipe(szPipeName,
  752.  PIPE_ACCESS_DUPLEX,
  753.  PIPE_TYPE_BYTE |
  754.  PIPE_READMODE_BYTE |
  755.  PIPE_WAIT,
  756.  PIPE_UNLIMITED_INSTANCES,
  757.  (int) net_buffer_length,
  758.  (int) net_buffer_length,
  759.  NMPWAIT_USE_DEFAULT_WAIT,
  760.  &saPipeSecurity )) == INVALID_HANDLE_VALUE)
  761.       {
  762. LPVOID lpMsgBuf;
  763. int error=GetLastError();
  764. FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
  765.       FORMAT_MESSAGE_FROM_SYSTEM,
  766.       NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  767.       (LPTSTR) &lpMsgBuf, 0, NULL );
  768. MessageBox( NULL, (LPTSTR) lpMsgBuf, "Error from CreateNamedPipe",
  769.     MB_OK|MB_ICONINFORMATION );
  770. LocalFree( lpMsgBuf );
  771. unireg_abort(1);
  772.       }
  773.   }
  774. #endif
  775. #if defined(HAVE_SYS_UN_H)
  776.   /*
  777.   ** Create the UNIX socket
  778.   */
  779.   if (mysql_unix_port[0] && !opt_bootstrap)
  780.   {
  781.     DBUG_PRINT("general",("UNIX Socket is %s",mysql_unix_port));
  782.     if ((unix_sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
  783.     {
  784.       sql_perror("Can't start server : UNIX Socket "); /* purecov: inspected */
  785.       unireg_abort(1); /* purecov: inspected */
  786.     }
  787.     bzero((char*) &UNIXaddr, sizeof(UNIXaddr));
  788.     UNIXaddr.sun_family = AF_UNIX;
  789.     strmov(UNIXaddr.sun_path, mysql_unix_port);
  790.     (void) unlink(mysql_unix_port);
  791.     (void) setsockopt(unix_sock,SOL_SOCKET,SO_REUSEADDR,(char*)&arg,
  792.       sizeof(arg));
  793.     umask(0);
  794.     if (bind(unix_sock, my_reinterpret_cast(struct sockaddr *) (&UNIXaddr),
  795.      sizeof(UNIXaddr)) < 0)
  796.     {
  797.       sql_perror("Can't start server : Bind on unix socket"); /* purecov: tested */
  798.       sql_print_error("Do you already have another mysqld server running on socket: %s ?",mysql_unix_port);
  799.       unireg_abort(1); /* purecov: tested */
  800.     }
  801.     umask(((~my_umask) & 0666));
  802. #if defined(S_IFSOCK) && defined(SECURE_SOCKETS)
  803.     (void) chmod(mysql_unix_port,S_IFSOCK); /* Fix solaris 2.6 bug */
  804. #endif
  805.     if (listen(unix_sock,(int) back_log) < 0)
  806.       sql_print_error("Warning:  listen() on Unix socket failed with error %d",
  807.       errno);
  808.   }
  809. #endif
  810.   DBUG_PRINT("info",("server started"));
  811.   DBUG_VOID_RETURN;
  812. }
  813. void yyerror(const char *s)
  814. {
  815.   NET *net=my_pthread_getspecific_ptr(NET*,THR_NET);
  816.   char *yytext=(char*) current_lex->tok_start;
  817.   if (!strcmp(s,"parse error"))
  818.     s=ER(ER_SYNTAX_ERROR);
  819.   net_printf(net,ER_PARSE_ERROR, s, yytext ? (char*) yytext : "",
  820.      current_lex->yylineno);
  821. }
  822. void close_connection(NET *net,uint errcode,bool lock)
  823. {
  824.   Vio* vio;
  825.   DBUG_ENTER("close_connection");
  826.   DBUG_PRINT("enter",("fd: %s  error: '%s'",
  827.                     net->vio? vio_description(net->vio):"(not connected)",
  828.                     errcode ? ER(errcode) : ""));
  829.   if (lock)
  830.     (void) pthread_mutex_lock(&LOCK_thread_count);
  831.   if ((vio=net->vio) != 0)
  832.   {
  833.     if (errcode)
  834.       send_error(net,errcode,ER(errcode)); /* purecov: inspected */
  835.     vio_close(vio); /* vio is freed in delete thd */
  836.   }
  837.   if (lock)
  838.     (void) pthread_mutex_unlock(&LOCK_thread_count);
  839.   DBUG_VOID_RETURN;
  840. }
  841. /* Called when a thread is aborted */
  842. /* ARGSUSED */
  843. sig_handler end_thread_signal(int sig __attribute__((unused)))
  844. {
  845.   THD *thd=current_thd;
  846.   DBUG_ENTER("end_thread_signal");
  847.   if (thd)
  848.     end_thread(thd,0);
  849.   DBUG_VOID_RETURN; /* purecov: deadcode */
  850. }
  851. void end_thread(THD *thd, bool put_in_cache)
  852. {
  853.   DBUG_ENTER("end_thread");
  854.   (void) pthread_mutex_lock(&LOCK_thread_count);
  855.   thread_count--;
  856.   delete thd;
  857.   if (put_in_cache && cached_thread_count < thread_cache_size &&
  858.       ! abort_loop && !kill_cached_threads)
  859.   {
  860.     /* Don't kill the thread, just put it in cache for reuse */
  861.     DBUG_PRINT("info", ("Adding thread to cache"))
  862.     cached_thread_count++;
  863.     while (!abort_loop && ! wake_thread && ! kill_cached_threads)
  864.       (void) pthread_cond_wait(&COND_thread_cache, &LOCK_thread_count);
  865.     cached_thread_count--;
  866.     if (kill_cached_threads)
  867.       pthread_cond_signal(&COND_flush_thread_cache);
  868.     if (wake_thread)
  869.     {
  870.       wake_thread--;
  871.       thd=thread_cache.get();
  872.       thd->real_id=pthread_self();
  873.       (void) thd->store_globals();
  874.       threads.append(thd);
  875.       pthread_mutex_unlock(&LOCK_thread_count);
  876.       DBUG_VOID_RETURN;
  877.     }
  878.   }
  879.   DBUG_PRINT("info", ("sending a broadcast"))
  880.   /* Tell main we are ready */
  881.   (void) pthread_mutex_unlock(&LOCK_thread_count);
  882.   (void) pthread_cond_broadcast(&COND_thread_count);
  883.   DBUG_PRINT("info", ("unlocked thread_count mutex"))
  884. #ifdef ONE_THREAD
  885.   if (!(test_flags & TEST_NO_THREADS)) // For debugging under Linux
  886. #endif
  887.   {
  888.     my_thread_end();
  889.     pthread_exit(0);
  890.   }
  891.   DBUG_VOID_RETURN;
  892. }
  893. /* Start a cached thread. LOCK_thread_count is locked on entry */
  894. static void start_cached_thread(THD *thd)
  895. {
  896.   thread_cache.append(thd);
  897.   wake_thread++;
  898.   thread_count++;
  899.   pthread_cond_signal(&COND_thread_cache);
  900. }
  901. void flush_thread_cache()
  902. {
  903.   (void) pthread_mutex_lock(&LOCK_thread_count);
  904.   kill_cached_threads++;
  905.   while (cached_thread_count)
  906.   {
  907.     pthread_cond_broadcast(&COND_thread_cache);
  908.     pthread_cond_wait(&COND_flush_thread_cache,&LOCK_thread_count);
  909.   }
  910.   kill_cached_threads--;
  911.   (void) pthread_mutex_unlock(&LOCK_thread_count);
  912. }
  913. /*
  914. ** Aborts a thread nicely. Commes here on SIGPIPE
  915. ** TODO: One should have to fix that thr_alarm know about this
  916. ** thread too
  917. */
  918. #ifdef THREAD_SPECIFIC_SIGPIPE
  919. static sig_handler abort_thread(int sig __attribute__((unused)))
  920. {
  921.   THD *thd=current_thd;
  922.   DBUG_ENTER("abort_thread");
  923.   if (thd)
  924.     thd->killed=1;
  925.   DBUG_VOID_RETURN;
  926. }
  927. #endif
  928. /******************************************************************************
  929. ** Setup a signal thread with handles all signals
  930. ** Because linux doesn't support scemas use a mutex to check that
  931. ** the signal thread is ready before continuing
  932. ******************************************************************************/
  933. #ifdef __WIN__
  934. static void init_signals(void)
  935. {
  936.   int signals[] = {SIGINT,SIGILL,SIGFPE,SIGSEGV,SIGTERM,SIGABRT } ;
  937.   for (uint i=0 ; i < sizeof(signals)/sizeof(int) ; i++)
  938.     signal( signals[i], kill_server) ;
  939.   signal(SIGBREAK,SIG_IGN); //ignore SIGBREAK for NT
  940. }
  941. #elif defined(__EMX__)
  942. static void sig_reload(int signo)
  943. {
  944.   reload_acl_and_cache((THD*) 0,~0, (TABLE_LIST*) 0); // Flush everything
  945.   signal(signo, SIG_ACK);
  946. }
  947. static void sig_kill(int signo)
  948. {
  949.   if (!abort_loop)
  950.   {
  951.     abort_loop=1; // mark abort for threads
  952.     kill_server((void*) signo);
  953.   }
  954.   signal(signo, SIG_ACK);
  955. }
  956. static void init_signals(void)
  957. {
  958.   signal(SIGQUIT, sig_kill);
  959.   signal(SIGKILL, sig_kill);
  960.   signal(SIGTERM, sig_kill);
  961.   signal(SIGINT,  sig_kill);
  962.   signal(SIGHUP,  sig_reload); // Flush everything
  963.   signal(SIGALRM, SIG_IGN);
  964.   signal(SIGBREAK,SIG_IGN);
  965.   signal_thread = pthread_self();
  966. }
  967. #else /* if ! __WIN__ && ! __EMX__ */
  968. #ifdef HAVE_LINUXTHREADS
  969. static sig_handler write_core(int sig);
  970. #ifdef __i386__
  971. #define SIGRETURN_FRAME_COUNT  1
  972. #define PTR_SANE(p) ((char*)p >= heap_start && (char*)p <= heap_end)
  973. extern char* __bss_start;
  974. static char* heap_start, *heap_end;
  975. inline __volatile__ void print_str(const char* name,
  976.    const char* val, int max_len)
  977. {
  978.   fprintf(stderr, "%s at %p ", name, val);
  979.   if(!PTR_SANE(val))
  980.     {
  981.       fprintf(stderr, " is invalid pointern");
  982.       return;
  983.     }
  984.   fprintf(stderr, "= ");
  985.   for(; max_len && PTR_SANE(val) && *val; --max_len)
  986.     fputc(*val++, stderr);
  987.   fputc('n', stderr);
  988. }
  989. inline __volatile__ void  trace_stack()
  990. {
  991.   uchar **stack_bottom;
  992.   uchar** ebp;
  993.   LINT_INIT(ebp);
  994.   LINT_INIT(stack_bottom);
  995.   fprintf(stderr,
  996. "Attempting backtrace. You can use the following information to find outn
  997. where mysqld died.  If you see no messages after this, something wentn
  998. terribly wrong...n");
  999.   THD* thd = current_thd;
  1000.   uint frame_count = 0;
  1001.   __asm __volatile__ ("movl %%ebp,%0"
  1002.       :"=r"(ebp)
  1003.       :"r"(ebp));
  1004.   if (!ebp)
  1005.   {
  1006.     fprintf(stderr, "frame pointer (ebp) is NULL, did you compile withn
  1007. -fomit-frame-pointer? Aborting backtrace!n");
  1008.     return;
  1009.   }
  1010.   if (!thd)
  1011.   {
  1012.     fprintf(stderr, "Cannot determine thread, ebp=%p, backtrace may not be correct.n", ebp);
  1013.     /* Assume that the stack starts at the previous even 65K */
  1014.     ulong tmp= min(0x10000,thread_stack);
  1015.     stack_bottom= (uchar**) (((ulong) &stack_bottom + tmp) &
  1016.      ~(ulong) 0xFFFF);
  1017.   }
  1018.   else
  1019.     stack_bottom = (uchar**) thd->thread_stack;
  1020.   if (ebp > stack_bottom || ebp < stack_bottom - thread_stack)
  1021.   {
  1022.     fprintf(stderr,
  1023.     "Bogus stack limit or frame pointer, aborting backtrace.n");
  1024.     return;
  1025.   }
  1026.   fprintf(stderr, "Stack range sanity check OK, backtrace follows:n");
  1027.   
  1028.   while (ebp < stack_bottom)
  1029.   {
  1030.     uchar** new_ebp = (uchar**)*ebp;
  1031.     fprintf(stderr, "%pn", frame_count == SIGRETURN_FRAME_COUNT ?
  1032.     *(ebp+17) : *(ebp+1));
  1033.     if (new_ebp <= ebp )
  1034.     {
  1035.       fprintf(stderr, "
  1036. New value of ebp failed sanity check, terminating backtrace!n");
  1037.       return;
  1038.     }
  1039.     ebp = new_ebp;
  1040.     ++frame_count;
  1041.   }
  1042.   fprintf(stderr, "Stack trace successful, trying to get some variables.n
  1043. Some pointers may be invalid and cause the dump to abort...n");
  1044.   heap_start = __bss_start; 
  1045.   heap_end = (char*)sbrk(0);
  1046.   print_str("thd->query", thd->query, 1024);
  1047.   fprintf(stderr, "thd->thread_id = %ldn", thd->thread_id);
  1048.   fprintf(stderr, "Successfully dumped variables, if you ran with --log,n
  1049. take a look at the details of what thread %ld did to cause the crash.n
  1050. In some cases of really bad corruption, this value may be invalidn",
  1051.   thd->thread_id);
  1052.   fprintf(stderr, "Please use the information above to create a repeatablen
  1053. test case for the crash, and send it to bugs@lists.mysql.comn");
  1054. }
  1055. #endif
  1056. #endif
  1057. static sig_handler handle_segfault(int sig)
  1058. {
  1059.   // strictly speaking, one needs a mutex here
  1060.   // but since we have got SIGSEGV already, things are a mess
  1061.   // so not having the mutex is not as bad as possibly using a buggy
  1062.   // mutex - so we keep things simple
  1063.   if (segfaulted)
  1064.     return;
  1065.   segfaulted = 1;
  1066.   fprintf(stderr,"
  1067. mysqld got signal %d;n
  1068. The manual section 'Debugging a MySQL server' tells you how to use an
  1069. stack trace and/or the core file to produce a readable backtrace that mayn
  1070. help in finding out why mysqld died.n",sig);
  1071. #if defined(HAVE_LINUXTHREADS)
  1072. #ifdef __i386__
  1073.   trace_stack();
  1074. #endif /* __i386__ */
  1075.  if (test_flags & TEST_CORE_ON_SIGNAL)
  1076.    write_core(sig);
  1077. #endif /* HAVE_LINUXTHREADS */
  1078.  exit(1);
  1079. }
  1080. /* Produce a core for the thread */
  1081. #ifdef HAVE_LINUXTHREADS
  1082. static sig_handler write_core(int sig)
  1083. {
  1084.   signal(sig, SIG_DFL);
  1085.   if (fork() != 0) exit(1); // Abort main program
  1086.   // Core will be written at exit
  1087. }
  1088. #endif
  1089. static void init_signals(void)
  1090. {
  1091.   sigset_t set;
  1092.   pthread_attr_t thr_attr;
  1093.   int error;
  1094.   DBUG_ENTER("init_signals");
  1095.   sigset(THR_KILL_SIGNAL,end_thread_signal);
  1096.   sigset(THR_SERVER_ALARM,print_signal_warning); // Should never be called!
  1097.   struct sigaction sa; sa.sa_flags = 0;
  1098.   sigemptyset(&sa.sa_mask);
  1099.   sigprocmask(SIG_SETMASK,&sa.sa_mask,NULL);
  1100.   if (!(test_flags & TEST_NO_STACKTRACE))
  1101.   {
  1102. #ifdef HAVE_DARWIN_THREADS
  1103.     sa.sa_handler=( void (*)() ) handle_segfault;
  1104. #else
  1105.     sa.sa_handler=handle_segfault;
  1106. #endif
  1107.     sigaction(SIGSEGV, &sa, NULL);
  1108. #ifdef SIGBUS
  1109.     sigaction(SIGBUS, &sa, NULL);
  1110. #endif
  1111.     sigaction(SIGILL, &sa, NULL);
  1112.   }
  1113.   (void) sigemptyset(&set);
  1114. #ifdef THREAD_SPECIFIC_SIGPIPE
  1115.   sigset(SIGPIPE,abort_thread);
  1116.   sigaddset(&set,SIGPIPE);
  1117. #else
  1118.   (void) signal(SIGPIPE,SIG_IGN); // Can't know which thread
  1119.   sigaddset(&set,SIGPIPE);
  1120. #endif
  1121.   sigaddset(&set,SIGINT);
  1122.   sigaddset(&set,SIGQUIT);
  1123.   sigaddset(&set,SIGTERM);
  1124.   sigaddset(&set,SIGHUP);
  1125.   signal(SIGTERM,SIG_DFL); // If it's blocked by parent
  1126.   signal(SIGHUP,SIG_DFL); // If it's blocked by parent
  1127. #ifdef SIGTSTP
  1128.   sigaddset(&set,SIGTSTP);
  1129. #endif
  1130.   sigaddset(&set,THR_SERVER_ALARM);
  1131.   sigdelset(&set,THR_KILL_SIGNAL); // May be SIGINT
  1132.   sigdelset(&set,THR_CLIENT_ALARM); // For alarms
  1133.   (void) pthread_sigmask(SIG_SETMASK,&set,NULL);
  1134.   (void) pthread_attr_init(&thr_attr);
  1135. #if !defined(HAVE_DEC_3_2_THREADS)
  1136.   pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_SYSTEM);
  1137.   (void) pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED);
  1138.   if (!(opt_specialflag & SPECIAL_NO_PRIOR))
  1139.     my_pthread_attr_setprio(&thr_attr,INTERRUPT_PRIOR);
  1140.   pthread_attr_setstacksize(&thr_attr,32768);
  1141. #endif
  1142.   (void) pthread_mutex_lock(&LOCK_thread_count);
  1143.   if ((error=pthread_create(&signal_thread,&thr_attr,signal_hand,0)))
  1144.   {
  1145.     sql_print_error("Can't create interrupt-thread (error %d, errno: %d)",
  1146.     error,errno);
  1147.     exit(1);
  1148.   }
  1149.   (void) pthread_cond_wait(&COND_thread_count,&LOCK_thread_count);
  1150.   pthread_mutex_unlock(&LOCK_thread_count);
  1151.   (void) pthread_attr_destroy(&thr_attr);
  1152.   DBUG_VOID_RETURN;
  1153. }
  1154. /*
  1155. ** This threads handles all signals and alarms
  1156. */
  1157. /* ARGSUSED */
  1158. static void *signal_hand(void *arg __attribute__((unused)))
  1159. {
  1160.   sigset_t set;
  1161.   int sig;
  1162.   my_thread_init(); // Init new thread
  1163.   DBUG_ENTER("signal_hand");
  1164.   /* Setup alarm handler */
  1165.   init_thr_alarm(max_connections+max_insert_delayed_threads);
  1166. #if SIGINT != THR_KILL_SIGNAL
  1167.   (void) sigemptyset(&set); // Setup up SIGINT for debug
  1168.   (void) sigaddset(&set,SIGINT); // For debugging
  1169.   (void) pthread_sigmask(SIG_UNBLOCK,&set,NULL);
  1170. #endif
  1171.   (void) sigemptyset(&set); // Setup up SIGINT for debug
  1172. #ifdef USE_ONE_SIGNAL_HAND
  1173.   (void) sigaddset(&set,THR_SERVER_ALARM); // For alarms
  1174. #endif
  1175.   (void) sigaddset(&set,SIGQUIT);
  1176.   (void) sigaddset(&set,SIGTERM);
  1177. #if THR_CLIENT_ALARM != SIGHUP
  1178.   (void) sigaddset(&set,SIGHUP);
  1179. #endif
  1180.   (void) sigaddset(&set,SIGTSTP);
  1181.   /* Save pid to this process (or thread on Linux) */
  1182.   if (!opt_bootstrap)
  1183.   {
  1184.     File pidFile;
  1185.     if ((pidFile = my_create(pidfile_name,0664, O_WRONLY, MYF(MY_WME))) >= 0)
  1186.     {
  1187.       char buff[21];
  1188.       sprintf(buff,"%lu",(ulong) getpid());
  1189.       (void) my_write(pidFile, buff,strlen(buff),MYF(MY_WME));
  1190.       (void) my_close(pidFile,MYF(0));
  1191.     }
  1192.   }
  1193.   (void) pthread_mutex_lock(&LOCK_thread_count);
  1194.   (void) pthread_cond_signal(&COND_thread_count); /* continue init_signals */
  1195.   (void) pthread_mutex_unlock(&LOCK_thread_count);
  1196.   for (;;)
  1197.   {
  1198.     int error; // Used when debugging
  1199.     if (shutdown_in_progress && !abort_loop)
  1200.     {
  1201.       sig=SIGTERM;
  1202.       error=0;
  1203.     }
  1204.     else
  1205.       while ((error=my_sigwait(&set,&sig)) == EINTR) ;
  1206.     if (cleanup_done)
  1207.       pthread_exit(0); // Safety
  1208.     switch (sig) {
  1209.     case SIGTERM:
  1210.     case SIGQUIT:
  1211.     case SIGKILL:
  1212. #ifdef EXTRA_DEBUG
  1213.       sql_print_error("Got signal %d to shutdown mysqld",sig);
  1214. #endif
  1215.       DBUG_PRINT("info",("Got signal: %d  abort_loop: %d",sig,abort_loop));
  1216.       if (!abort_loop)
  1217.       {
  1218. abort_loop=1; // mark abort for threads
  1219. #ifdef USE_ONE_SIGNAL_HAND
  1220. pthread_t tmp;
  1221. if (!(opt_specialflag & SPECIAL_NO_PRIOR))
  1222.   my_pthread_attr_setprio(&connection_attrib,INTERRUPT_PRIOR);
  1223. if (pthread_create(&tmp,&connection_attrib, kill_server_thread,
  1224.    (void*) sig))
  1225.   sql_print_error("Error: Can't create thread to kill server");
  1226. #else
  1227.   kill_server((void*) sig); // MIT THREAD has a alarm thread
  1228. #endif
  1229.       }
  1230.       break;
  1231.     case SIGHUP:
  1232.       reload_acl_and_cache((THD*) 0,~0, (TABLE_LIST*) 0); // Flush everything
  1233.       mysql_print_status((THD*) 0); // Send debug some info
  1234.       break;
  1235. #ifdef USE_ONE_SIGNAL_HAND
  1236.     case THR_SERVER_ALARM:
  1237.       process_alarm(sig); // Trigger alarms.
  1238.       break;
  1239. #endif
  1240.     default:
  1241. #ifdef EXTRA_DEBUG
  1242.       sql_print_error("Warning: Got signal: %d, error: %d",sig,error); /* purecov: tested */
  1243. #endif
  1244.       break; /* purecov: tested */
  1245.     }
  1246.   }
  1247.   return(0); /* purecov: deadcode */
  1248. }
  1249. #endif /* __WIN__*/
  1250. /*
  1251. ** All global error messages are sent here where the first one is stored for
  1252. ** the client
  1253. */
  1254. /* ARGSUSED */
  1255. static int my_message_sql(uint error, const char *str,
  1256.   myf MyFlags __attribute__((unused)))
  1257. {
  1258.   NET *net;
  1259.   DBUG_ENTER("my_message_sql");
  1260.   DBUG_PRINT("error",("Message: '%s'",str));
  1261.   if ((net=my_pthread_getspecific_ptr(NET*,THR_NET)))
  1262.   {
  1263.     if (!net->last_error[0]) // Return only first message
  1264.     {
  1265.       strmake(net->last_error,str,sizeof(net->last_error)-1);
  1266.       net->last_errno=error ? error : ER_UNKNOWN_ERROR;
  1267.     }
  1268.   }
  1269.   else
  1270.     sql_print_error("%s: %s",my_progname,str); /* purecov: inspected */
  1271.   DBUG_RETURN(0);
  1272. }
  1273. #ifdef __WIN__
  1274. #undef errno
  1275. #undef EINTR
  1276. #define errno WSAGetLastError()
  1277. #define EINTR WSAEINTR
  1278. struct utsname
  1279. {
  1280.   char nodename[FN_REFLEN];
  1281. };
  1282. int uname(struct utsname *a)
  1283. {
  1284.   return -1;
  1285. }
  1286. #endif
  1287. #ifdef __WIN__
  1288. pthread_handler_decl(handle_shutdown,arg)
  1289. {
  1290.   MSG msg;
  1291.   my_thread_init();
  1292.   /* this call should create the message queue for this thread */
  1293.   PeekMessage(&msg, NULL, 1, 65534,PM_NOREMOVE);
  1294.   if (WaitForSingleObject(hEventShutdown,INFINITE)==WAIT_OBJECT_0)
  1295.      kill_server(MYSQL_KILL_SIGNAL);
  1296.   return 0;
  1297. }
  1298. int __stdcall handle_kill(ulong ctrl_type)
  1299. {
  1300.   if (ctrl_type == CTRL_CLOSE_EVENT ||
  1301.       ctrl_type == CTRL_SHUTDOWN_EVENT)
  1302.   {
  1303.     kill_server(MYSQL_KILL_SIGNAL);
  1304.     return TRUE;
  1305.   }
  1306.   return FALSE;
  1307. }
  1308. #endif
  1309. const char *load_default_groups[]= { "mysqld","server",0 };
  1310. #ifdef HAVE_LIBWRAP
  1311. char *libwrapName=NULL;
  1312. #endif
  1313. static void open_log(MYSQL_LOG *log, const char *hostname,
  1314.      const char *opt_name, const char *extension,
  1315.      enum_log_type type)
  1316. {
  1317.   char tmp[FN_REFLEN];
  1318.   if (!opt_name || !opt_name[0])
  1319.   {
  1320.     /* TODO: The following should be using fn_format();  We just need to
  1321.      first change fn_format() to cut the file name if it's too long.
  1322.     */
  1323.     strmake(tmp,hostname,FN_REFLEN-5);
  1324.     strmov(strcend(tmp,'.'),extension);
  1325.     opt_name=tmp;
  1326.   }
  1327.   log->open(opt_name,type);
  1328. }
  1329. #ifdef __WIN__
  1330. int win_main(int argc, char **argv)
  1331. #else
  1332. int main(int argc, char **argv)
  1333. #endif
  1334. {
  1335.   DEBUGGER_OFF;
  1336.   my_umask=0660; // Default umask for new files
  1337.   my_umask_dir=0700; // Default umask for new directories
  1338.   MY_INIT(argv[0]); // init my_sys library & pthreads
  1339.   tzset(); // Set tzname
  1340.   start_time=time((time_t*) 0);
  1341. #ifdef HAVE_TZNAME
  1342. #if defined(HAVE_LOCALTIME_R) && defined(_REENTRANT)
  1343.   {
  1344.     struct tm tm_tmp;
  1345.     localtime_r(&start_time,&tm_tmp);
  1346.     strmov(time_zone,tzname[tm_tmp.tm_isdst == 1 ? 1 : 0]);
  1347.   }
  1348. #else
  1349.   {
  1350.     struct tm *start_tm;
  1351.     start_tm=localtime(&start_time);
  1352.     strmov(time_zone,tzname[start_tm->tm_isdst == 1 ? 1 : 0]);
  1353.   }
  1354. #endif
  1355. #endif
  1356.   if (gethostname(glob_hostname,sizeof(glob_hostname)-4) < 0)
  1357.     strmov(glob_hostname,"mysql");
  1358.   strmov(pidfile_name,glob_hostname);
  1359.   strmov(strcend(pidfile_name,'.'),".pid"); // Add extension
  1360. #ifndef DBUG_OFF
  1361.   strxmov(strend(server_version),MYSQL_SERVER_SUFFIX,"-debug",NullS);
  1362. #else
  1363.   strmov(strend(server_version),MYSQL_SERVER_SUFFIX);
  1364. #endif
  1365. #ifdef _CUSTOMSTARTUPCONFIG_
  1366.   if (_cust_check_startup())
  1367.   {
  1368.     /* _cust_check_startup will report startup failure error */
  1369.     exit( 1 );
  1370.   }
  1371. #endif
  1372.   load_defaults("my",load_default_groups,&argc,&argv);
  1373.   defaults_argv=argv;
  1374.   mysql_tmpdir=getenv("TMPDIR"); /* Use this if possible */
  1375. #ifdef __WIN__
  1376.   if (!mysql_tmpdir)
  1377.     mysql_tmpdir=getenv("TEMP");
  1378.   if (!mysql_tmpdir)
  1379.     mysql_tmpdir=getenv("TMP");
  1380. #endif
  1381.   if (!mysql_tmpdir || !mysql_tmpdir[0])
  1382.     mysql_tmpdir=(char*) P_tmpdir; /* purecov: inspected */
  1383.   set_options();
  1384. #ifdef __WIN__
  1385.   /* service parameters can be overwritten by options */
  1386.   if (get_service_parameters())
  1387.   {
  1388.     my_message( 0, "Can't read MySQL service parameters", MYF(0) );
  1389.     exit( 1 );
  1390.   }
  1391. #endif
  1392.   get_options(argc,argv);
  1393.   if (opt_log || opt_update_log || opt_slow_log || opt_bin_log)
  1394.     strcat(server_version,"-log");
  1395.   DBUG_PRINT("info",("%s  Ver %s for %s on %sn",my_progname,
  1396.      server_version, SYSTEM_TYPE,MACHINE_TYPE));
  1397.   /* These must be set early */
  1398.   (void) pthread_cond_init(&COND_thread_count,NULL);
  1399.   (void) pthread_mutex_init(&LOCK_mysql_create_db,NULL);
  1400.   (void) pthread_mutex_init(&LOCK_Acl,NULL);
  1401.   (void) pthread_mutex_init(&LOCK_grant,NULL);
  1402.   (void) pthread_mutex_init(&LOCK_open,NULL);
  1403.   (void) pthread_mutex_init(&LOCK_thread_count,NULL);
  1404.   (void) pthread_mutex_init(&LOCK_mapped_file,NULL);
  1405.   (void) pthread_mutex_init(&LOCK_status,NULL);
  1406.   (void) pthread_mutex_init(&LOCK_error_log,NULL);
  1407.   (void) pthread_mutex_init(&LOCK_delayed_insert,NULL);
  1408.   (void) pthread_mutex_init(&LOCK_delayed_status,NULL);
  1409.   (void) pthread_mutex_init(&LOCK_delayed_create,NULL);
  1410.   (void) pthread_cond_init(&COND_refresh,NULL);
  1411.   (void) pthread_cond_init(&COND_thread_cache,NULL);
  1412.   (void) pthread_cond_init(&COND_flush_thread_cache,NULL);
  1413.   (void) pthread_cond_init(&COND_manager,NULL);
  1414.   (void) pthread_mutex_init(&LOCK_manager,NULL);
  1415.   (void) pthread_mutex_init(&LOCK_crypt,NULL);
  1416.   (void) pthread_mutex_init(&LOCK_bytes_sent,NULL);
  1417.   (void) pthread_mutex_init(&LOCK_bytes_received,NULL);
  1418.   (void) pthread_mutex_init(&LOCK_timezone,NULL);
  1419.   (void) pthread_mutex_init(&LOCK_binlog_update, NULL);
  1420.   (void) pthread_mutex_init(&LOCK_slave, NULL);
  1421.   (void) pthread_mutex_init(&LOCK_server_id, NULL);
  1422.   (void) pthread_mutex_init(&LOCK_user_conn, NULL);
  1423.   (void) pthread_cond_init(&COND_binlog_update, NULL);
  1424.   (void) pthread_cond_init(&COND_slave_stopped, NULL);
  1425.   (void) pthread_cond_init(&COND_slave_start, NULL);
  1426.   if (set_default_charset_by_name(default_charset, MYF(MY_WME)))
  1427.     unireg_abort(1);
  1428.   charsets_list = list_charsets(MYF(MY_COMPILED_SETS|MY_CONFIG_SETS));
  1429. #ifdef HAVE_OPENSSL
  1430.   if (opt_use_ssl)
  1431.   {
  1432.     ssl_acceptor_fd = VioSSLAcceptorFd_new(opt_ssl_key, opt_ssl_cert,
  1433.    opt_ssl_ca, opt_ssl_capath);
  1434.     if (!ssl_acceptor_fd)
  1435.       opt_use_ssl=0;
  1436.     /* having ssl_acceptor_fd!=0 signals the use of SSL */
  1437.   }
  1438. #endif /* HAVE_OPENSSL */
  1439. #ifdef HAVE_LIBWRAP
  1440.   libwrapName= my_progname+dirname_length(my_progname);
  1441.   openlog(libwrapName, LOG_PID, LOG_AUTH);
  1442. #endif
  1443.   if (!(opt_specialflag & SPECIAL_NO_PRIOR))
  1444.     my_pthread_setprio(pthread_self(),CONNECT_PRIOR);
  1445.   /* Parameter for threads created for connections */
  1446.   (void) pthread_attr_init(&connection_attrib);
  1447.   (void) pthread_attr_setdetachstate(&connection_attrib,
  1448.      PTHREAD_CREATE_DETACHED);
  1449.   pthread_attr_setstacksize(&connection_attrib,thread_stack);
  1450.   if (!(opt_specialflag & SPECIAL_NO_PRIOR))
  1451.     my_pthread_attr_setprio(&connection_attrib,WAIT_PRIOR);
  1452.   pthread_attr_setscope(&connection_attrib, PTHREAD_SCOPE_SYSTEM);
  1453. #ifdef SET_RLIMIT_NOFILE
  1454.   /* connections and databases neads lots of files */
  1455.   {
  1456.     uint wanted_files=10+(uint) max(max_connections*5,
  1457.     max_connections+table_cache_size*2);
  1458.     set_if_bigger(wanted_files, open_files_limit);
  1459.     // Note that some system returns 0 if we succeed here:
  1460.     uint files=set_maximum_open_files(wanted_files);
  1461.     if (files && files < wanted_files && ! open_files_limit)
  1462.     {
  1463.       max_connections= (ulong) min((files-10),max_connections);
  1464.       table_cache_size= (ulong) max((files-10-max_connections)/2,64);
  1465.       DBUG_PRINT("warning",
  1466.  ("Changed limits: max_connections: %ld  table_cache: %ld",
  1467.   max_connections,table_cache_size));
  1468.       sql_print_error("Warning: Changed limits: max_connections: %ld  table_cache: %ld",max_connections,table_cache_size);
  1469.     }
  1470.   }
  1471. #endif
  1472.   unireg_init(opt_specialflag); /* Set up extern variabels */
  1473.   init_errmessage(); /* Read error messages from file */
  1474.   lex_init();
  1475.   item_init();
  1476.   mysys_uses_curses=0;
  1477. #ifdef USE_REGEX
  1478.   regex_init();
  1479. #endif
  1480.   select_thread=pthread_self();
  1481.   select_thread_in_use=1;
  1482.   if (use_temp_pool && bitmap_init(&temp_pool,1024))
  1483.     unireg_abort(1);
  1484.   /*
  1485.   ** We have enough space for fiddling with the argv, continue
  1486.   */
  1487.   umask(((~my_umask) & 0666));
  1488.   if (my_setwd(mysql_real_data_home,MYF(MY_WME)))
  1489.   {
  1490.     unireg_abort(1); /* purecov: inspected */
  1491.   }
  1492.   mysql_data_home[0]=FN_CURLIB; // all paths are relative from here
  1493.   mysql_data_home[1]=0;
  1494.   server_init();
  1495.   table_cache_init();
  1496.   hostname_cache_init();
  1497.   sql_cache_init();
  1498.   randominit(&sql_rand,(ulong) start_time,(ulong) start_time/2);
  1499.   reset_floating_point_exceptions();
  1500.   init_thr_lock();
  1501.   /* Setup log files */
  1502.   if (opt_log)
  1503.     open_log(&mysql_log, glob_hostname, opt_logname, ".log", LOG_NORMAL);
  1504.   if (opt_update_log)
  1505.     open_log(&mysql_update_log, glob_hostname, opt_update_logname, "",
  1506.      LOG_NEW);
  1507.   if (opt_bin_log && !server_id)
  1508.   {
  1509.     server_id= !master_host ? 1 : 2;
  1510.     switch (server_id) {
  1511. #ifdef EXTRA_DEBUG
  1512.     case 1:
  1513.       sql_print_error("
  1514. Warning: You should set server-id to a non-0 value if log-bin is enabled.n
  1515. mysqld will log updates to the binary log, but will not accept connectionsn
  1516. from slaves.");
  1517.       break;
  1518. #endif
  1519.     case 2:
  1520.       sql_print_error("
  1521. Warning: You should set server-id to a non-0 value if master_host is set.n
  1522. The server will not act as a slave.");
  1523.       break;
  1524.     }
  1525.   }
  1526.   if (opt_bin_log)
  1527.   {
  1528.     if (!opt_bin_logname)
  1529.     {
  1530.       char tmp[FN_REFLEN];
  1531.       /* TODO: The following should be using fn_format();  We just need to
  1532.  first change fn_format() to cut the file name if it's too long.
  1533.       */
  1534.       strmake(tmp,glob_hostname,FN_REFLEN-5);
  1535.       strmov(strcend(tmp,'.'),"-bin");
  1536.       opt_bin_logname=my_strdup(tmp,MYF(MY_WME));
  1537.     }
  1538.     mysql_bin_log.set_index_file_name(opt_binlog_index_name);
  1539.     open_log(&mysql_bin_log, glob_hostname, opt_bin_logname, "-bin",
  1540.      LOG_BIN);
  1541.   }
  1542.   
  1543.   if (opt_slow_log)
  1544.     open_log(&mysql_slow_log, glob_hostname, opt_slow_logname, "-slow.log",
  1545.      LOG_NORMAL);
  1546.   if (ha_init())
  1547.   {
  1548.     sql_print_error("Can't init databases");
  1549.     exit(1);
  1550.   }
  1551. #if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT)
  1552.   if (locked_in_memory && !geteuid())
  1553.   {
  1554.     ha_key_cache();
  1555.     if (mlockall(MCL_CURRENT))
  1556.     {
  1557.       sql_print_error("Warning: Failed to lock memory. Errno: %dn",errno);
  1558.     }
  1559.     else
  1560.       locked_in_memory=1;
  1561.   }
  1562. #else
  1563.   locked_in_memory=0;
  1564. #endif    
  1565.   if (opt_myisam_log)
  1566.     (void) mi_log( 1 );
  1567.   ft_init_stopwords(ft_precompiled_stopwords);       /* SerG */
  1568. #ifdef __WIN__
  1569. #define MYSQL_ERR_FILE "mysql.err"
  1570.   if (!opt_console)
  1571.   {
  1572.     freopen(MYSQL_ERR_FILE,"a+",stdout);
  1573.     freopen(MYSQL_ERR_FILE,"a+",stderr);
  1574.     FreeConsole(); // Remove window
  1575.   }
  1576. #endif
  1577.   /*
  1578.     init signals & alarm
  1579.     After this we can't quit by a simple unireg_abort
  1580.   */
  1581.   error_handler_hook = my_message_sql;
  1582.   if (pthread_key_create(&THR_THD,NULL) || pthread_key_create(&THR_NET,NULL) ||
  1583.       pthread_key_create(&THR_MALLOC,NULL))
  1584.   {
  1585.     sql_print_error("Can't create thread-keys");
  1586.     exit(1);
  1587.   }
  1588.   init_signals(); // Creates pidfile
  1589.   if (acl_init(opt_noacl))
  1590.   {
  1591.     select_thread_in_use=0;
  1592.     (void) pthread_kill(signal_thread,MYSQL_KILL_SIGNAL);
  1593. #ifndef __WIN__
  1594.     if (!opt_bootstrap)
  1595.       (void) my_delete(pidfile_name,MYF(MY_WME)); // Not neaded anymore
  1596. #endif
  1597.     exit(1);
  1598.   }
  1599.   if (!opt_noacl)
  1600.     (void) grant_init();
  1601.   if (max_user_connections)
  1602.     init_max_user_conn();
  1603. #ifdef HAVE_DLOPEN
  1604.   if (!opt_noacl)
  1605.     udf_init();
  1606. #endif
  1607.   if (opt_bootstrap)
  1608.   {
  1609.     int error=bootstrap(stdin);
  1610.     end_thr_alarm(); // Don't allow alarms
  1611.     unireg_abort(error ? 1 : 0);
  1612.   }
  1613.   if (opt_init_file)
  1614.   {
  1615.     if (read_init_file(opt_init_file))
  1616.     {
  1617.       end_thr_alarm(); // Don't allow alarms
  1618.       unireg_abort(1);
  1619.     }
  1620.   }
  1621.   (void) thr_setconcurrency(concurrency); // 10 by default
  1622. #ifdef __WIN__         //IRENA
  1623.   {
  1624.     hEventShutdown=CreateEvent(0, FALSE, FALSE, "MySqlShutdown");
  1625.     pthread_t hThread;
  1626.     if (pthread_create(&hThread,&connection_attrib,handle_shutdown,0))
  1627.       sql_print_error("Warning: Can't create thread to handle shutdown requests");
  1628.     // On "Stop Service" we have to do regular shutdown
  1629.     Service.SetShutdownEvent(hEventShutdown);
  1630.   }
  1631. #endif
  1632.   if (
  1633. #ifdef HAVE_BERKELEY_DB
  1634.       !berkeley_skip ||
  1635. #endif
  1636.       (flush_time && flush_time != ~(ulong) 0L))
  1637.   {
  1638.     pthread_t hThread;
  1639.     if (pthread_create(&hThread,&connection_attrib,handle_manager,0))
  1640.       sql_print_error("Warning: Can't create thread to manage maintenance");
  1641.   }
  1642.   // slave thread
  1643.   if (master_host)
  1644.   {
  1645.     pthread_t hThread;
  1646.     if (!opt_skip_slave_start &&
  1647.        pthread_create(&hThread, &connection_attrib, handle_slave, 0))
  1648.       sql_print_error("Warning: Can't create thread to handle slave");
  1649.     else if(opt_skip_slave_start)
  1650.       init_master_info(&glob_mi);
  1651.   }
  1652.   printf(ER(ER_READY),my_progname,server_version,"");
  1653.   fflush(stdout);
  1654. #ifdef __NT__
  1655.   if (hPipe == INVALID_HANDLE_VALUE && !have_tcpip)
  1656.   {
  1657.     sql_print_error("TCP/IP must be installed on Win98 platforms");
  1658.   }
  1659.   else
  1660.   {
  1661.     pthread_mutex_lock(&LOCK_thread_count);
  1662.     (void) pthread_cond_init(&COND_handler_count,NULL);
  1663.     {
  1664.       pthread_t hThread;
  1665.       handler_count=0;
  1666.       if ( hPipe != INVALID_HANDLE_VALUE )
  1667.       {
  1668. handler_count++;
  1669. if (pthread_create(&hThread,&connection_attrib,
  1670.    handle_connections_namedpipes, 0))
  1671. {
  1672.   sql_print_error("Warning: Can't create thread to handle named pipes");
  1673.   handler_count--;
  1674. }
  1675.       }
  1676.       if (have_tcpip && !opt_disable_networking)
  1677.       {
  1678. handler_count++;
  1679. if (pthread_create(&hThread,&connection_attrib,
  1680.    handle_connections_sockets, 0))
  1681. {
  1682.   sql_print_error("Warning: Can't create thread to handle named pipes");
  1683.   handler_count--;
  1684. }
  1685.       }
  1686.       while (handler_count > 0)
  1687.       {
  1688. pthread_cond_wait(&COND_handler_count,&LOCK_thread_count);
  1689.       }
  1690.     }
  1691.     pthread_mutex_unlock(&LOCK_thread_count);
  1692.   }
  1693. #else
  1694.   handle_connections_sockets(0);
  1695. #ifdef EXTRA_DEBUG
  1696.   sql_print_error("Exiting main thread");
  1697. #endif
  1698. #endif /* __NT__ */
  1699.   /* (void) pthread_attr_destroy(&connection_attrib); */
  1700.   DBUG_PRINT("quit",("Exiting main thread"));
  1701. #ifndef __WIN__
  1702. #ifdef EXTRA_DEBUG
  1703.   sql_print_error("Before Lock_thread_count");
  1704. #endif
  1705.   (void) pthread_mutex_lock(&LOCK_thread_count);
  1706.   select_thread_in_use=0; // For close_connections
  1707.   (void) pthread_cond_broadcast(&COND_thread_count);
  1708.   (void) pthread_mutex_unlock(&LOCK_thread_count);
  1709. #ifdef EXTRA_DEBUG
  1710.   sql_print_error("After lock_thread_count");
  1711. #endif
  1712. #else
  1713.   // remove the event, because it will not be valid anymore
  1714.   Service.SetShutdownEvent(0);
  1715.   if(hEventShutdown) CloseHandle(hEventShutdown);
  1716.   // if it was started as service on NT try to stop the service
  1717.   if(Service.IsNT())
  1718.      Service.Stop();
  1719. #endif
  1720.   /* Wait until cleanup is done */
  1721.   (void) pthread_mutex_lock(&LOCK_thread_count);
  1722.   while (!ready_to_exit)
  1723.   {
  1724.     pthread_cond_wait(&COND_thread_count,&LOCK_thread_count);
  1725.   }
  1726.   (void) pthread_mutex_unlock(&LOCK_thread_count);
  1727.   my_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0);
  1728.   exit(0);
  1729.   return(0); /* purecov: deadcode */
  1730. }
  1731. #ifdef __WIN__
  1732. /* ------------------------------------------------------------------------
  1733.    main and thread entry function for Win32
  1734.    (all this is needed only to run mysqld as a service on WinNT)
  1735.  -------------------------------------------------------------------------- */
  1736. int mysql_service(void *p)
  1737. {
  1738.   win_main(Service.my_argc, Service.my_argv);
  1739.   return 0;
  1740. }
  1741. int main(int argc, char **argv)
  1742. {
  1743.   // check  environment variable OS
  1744.   if (Service.GetOS()) // "OS" defined; Should be NT
  1745.   {
  1746.     if (argc == 2)
  1747.     {
  1748.       if (!strcmp(argv[1],"-install") || !strcmp(argv[1],"--install"))
  1749.       {
  1750. char path[FN_REFLEN];
  1751. my_path(path, argv[0], "");    // Find name in path
  1752. fn_format(path,argv[0],path,"",1+4+16);    // Force use of full path
  1753. if (!Service.Install(MYSQL_SERVICENAME,MYSQL_SERVICENAME,path))
  1754.   MessageBox(NULL,"Failed to install Service",MYSQL_SERVICENAME,
  1755.      MB_OK|MB_ICONSTOP);
  1756. return 0;
  1757.       }
  1758.       else if (!strcmp(argv[1],"-remove") || !strcmp(argv[1],"--remove"))
  1759.       {
  1760. Service.Remove(MYSQL_SERVICENAME);
  1761. return 0;
  1762.       }
  1763.     }
  1764.     else if (argc == 1)    // No arguments; start as a service
  1765.     {
  1766.       // init service
  1767.       long tmp=Service.Init(MYSQL_SERVICENAME,mysql_service);
  1768.       return 0;
  1769.     }
  1770.   }
  1771.   // This is a WIN95 machine or a start of mysqld as a standalone program
  1772.   // we have to pass the arguments, in case of NT-service this will be done
  1773.   // by ServiceMain()
  1774.   Service.my_argc=argc;
  1775.   Service.my_argv=argv;
  1776.   mysql_service(NULL);
  1777.   return 0;
  1778. }
  1779. /* ------------------------------------------------------------------------ */
  1780. #endif
  1781. static int bootstrap(FILE *file)
  1782. {
  1783.   THD *thd= new THD;
  1784.   int error;
  1785.   thd->bootstrap=1;
  1786.   thd->client_capabilities=0;
  1787.   my_net_init(&thd->net,(Vio*) 0);
  1788.   thd->max_packet_length=thd->net.max_packet;
  1789.   thd->master_access= ~0;
  1790.   thd->thread_id=thread_id++;
  1791.   thread_count++;
  1792.   bootstrap_file=file;
  1793.   if (pthread_create(&thd->real_id,&connection_attrib,handle_bootstrap,
  1794.      (void*) thd))
  1795.   {
  1796.     sql_print_error("Warning: Can't create thread to handle bootstrap");    
  1797.     return -1;
  1798.   }
  1799.   /* Wait for thread to die */
  1800.   (void) pthread_mutex_lock(&LOCK_thread_count);
  1801.   while (thread_count)
  1802.   {
  1803.     (void) pthread_cond_wait(&COND_thread_count,&LOCK_thread_count);
  1804.     DBUG_PRINT("quit",("One thread died (count=%u)",thread_count));
  1805.   }
  1806.   (void) pthread_mutex_unlock(&LOCK_thread_count);
  1807.   error= thd->fatal_error;
  1808.   net_end(&thd->net);
  1809.   delete thd;
  1810.   return error;
  1811. }
  1812. static bool read_init_file(char *file_name)
  1813. {
  1814.   FILE *file;
  1815.   DBUG_ENTER("read_init_file");
  1816.   DBUG_PRINT("enter",("name: %s",file_name));
  1817.   if (!(file=my_fopen(file_name,O_RDONLY,MYF(MY_WME))))
  1818.     return(1);
  1819.   bootstrap(file); /* Ignore errors from this */
  1820.   (void) my_fclose(file,MYF(MY_WME));
  1821.   return 0;
  1822. }
  1823. static void create_new_thread(THD *thd)
  1824. {
  1825.   DBUG_ENTER("create_new_thread");
  1826.   NET *net=&thd->net; // For easy ref
  1827.   net->timeout = (uint) connect_timeout; // Timeout for read
  1828.   if (protocol_version > 9)
  1829.     net->return_errno=1;
  1830.   /* don't allow too many connections */
  1831.   if (thread_count - delayed_insert_threads >= max_connections+1 || abort_loop)
  1832.   {
  1833.     DBUG_PRINT("error",("Too many connections"));
  1834.     close_connection(net,ER_CON_COUNT_ERROR);
  1835.     delete thd;
  1836.     DBUG_VOID_RETURN;
  1837.   }
  1838.   if (pthread_mutex_lock(&LOCK_thread_count))
  1839.   {
  1840.     DBUG_PRINT("error",("Can't lock LOCK_thread_count"));
  1841.     close_connection(net,ER_OUT_OF_RESOURCES);
  1842.     delete thd;
  1843.     DBUG_VOID_RETURN;
  1844.   }
  1845.   if (thread_count-delayed_insert_threads > max_used_connections)
  1846.     max_used_connections=thread_count-delayed_insert_threads;
  1847.   thd->thread_id=thread_id++;
  1848.   for (uint i=0; i < 8 ; i++) // Generate password teststring
  1849.     thd->scramble[i]= (char) (rnd(&sql_rand)*94+33);
  1850.   thd->scramble[8]=0;
  1851.   thd->rand=sql_rand;
  1852.   thd->real_id=pthread_self(); // Keep purify happy
  1853.   /* Start a new thread to handle connection */
  1854. #ifdef ONE_THREAD
  1855.   if (test_flags & TEST_NO_THREADS) // For debugging under Linux
  1856.   {
  1857.     thread_cache_size=0; // Safety
  1858.     thread_count++;
  1859.     threads.append(thd);
  1860.     thd->real_id=pthread_self();
  1861.     (void) pthread_mutex_unlock(&LOCK_thread_count);
  1862.     handle_one_connection((void*) thd);
  1863.   }
  1864.   else
  1865. #endif
  1866.   {
  1867.     if (cached_thread_count > wake_thread)
  1868.     {
  1869.       start_cached_thread(thd);
  1870.       (void) pthread_mutex_unlock(&LOCK_thread_count);
  1871.     }
  1872.     else
  1873.     {
  1874.       int error;
  1875.       thread_count++;
  1876.       thread_created++;
  1877.       threads.append(thd);
  1878.       DBUG_PRINT("info",(("creating thread %d"), thd->thread_id));
  1879.       thd->connect_time = time(NULL);
  1880.       (void) pthread_mutex_unlock(&LOCK_thread_count);
  1881.       if ((error=pthread_create(&thd->real_id,&connection_attrib,
  1882. handle_one_connection,