my_init.c 11.6 KB
Newer Older
unknown's avatar
unknown committed
1
/* Copyright (C) 2000-2003 MySQL AB
unknown's avatar
unknown committed
2 3 4 5 6 7 8

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
unknown's avatar
unknown committed
9
   but WITHOUT ANY WARRANTY; without even the implied warranty of
unknown's avatar
unknown committed
10 11 12 13 14 15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
unknown's avatar
unknown committed
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38

#include "mysys_priv.h"
#include "my_static.h"
#include "mysys_err.h"
#include <m_string.h>
#include <m_ctype.h>
#include <signal.h>
#ifdef VMS
#include <my_static.c>
#include <m_ctype.h>
#endif
#ifdef __WIN__
#ifdef _MSC_VER
#include <locale.h>
#include <crtdbg.h>
#endif
my_bool have_tcpip=0;
static void my_win_init(void);
static my_bool win32_have_tcpip(void);
static my_bool win32_init_tcp_ip();
#else
#define my_win_init()
#endif
unknown's avatar
unknown committed
39 40 41 42 43 44
#ifdef __NETWARE__
static void netware_init();
#else
#define netware_init()
#endif

45 46
my_bool my_init_done= 0;
uint	mysys_usage_id= 0;              /* Incremented for each my_init() */
47

48
static ulong atoi_octal(const char *str)
unknown's avatar
unknown committed
49 50
{
  long int tmp;
51
  while (*str && my_isspace(&my_charset_latin1, *str))
unknown's avatar
unknown committed
52 53
    str++;
  str2int(str,
54
	  (*str == '0' ? 8 : 10),       /* Octalt or decimalt */
unknown's avatar
unknown committed
55 56 57 58 59
	  0, INT_MAX, &tmp);
  return (ulong) tmp;
}


60 61
/*
  Init my_sys functions and my_sys variabels
unknown's avatar
unknown committed
62

63 64 65 66 67 68 69 70 71
  SYNOPSIS
    my_init()

  RETURN
    0  ok
    1  Couldn't initialize environment
*/

my_bool my_init(void)
unknown's avatar
unknown committed
72 73 74
{
  my_string str;
  if (my_init_done)
75
    return 0;
unknown's avatar
unknown committed
76
  my_init_done=1;
77
  mysys_usage_id++;
78 79
  my_umask= 0660;                       /* Default umask for new files */
  my_umask_dir= 0700;                   /* Default umask for new directories */
unknown's avatar
unknown committed
80 81 82 83
#if defined(THREAD) && defined(SAFE_MUTEX)
  safe_mutex_global_init();		/* Must be called early */
#endif
  netware_init();
unknown's avatar
unknown committed
84 85 86 87
#ifdef THREAD
#if defined(HAVE_PTHREAD_INIT)
  pthread_init();			/* Must be called before DBUG_ENTER */
#endif
88 89
  if (my_thread_global_init())
    return 1;
90
#if !defined( __WIN__) && !defined(__NETWARE__)
unknown's avatar
unknown committed
91 92
  sigfillset(&my_signals);		/* signals blocked by mf_brkhant */
#endif
unknown's avatar
unknown committed
93
#endif /* THREAD */
unknown's avatar
unknown committed
94 95
  {
    DBUG_ENTER("my_init");
96
    DBUG_PROCESS((char*) (my_progname ? my_progname : "unknown"));
unknown's avatar
unknown committed
97 98 99 100 101 102
    if (!home_dir)
    {					/* Don't initialize twice */
      my_win_init();
      if ((home_dir=getenv("HOME")) != 0)
	home_dir=intern_filename(home_dir_buff,home_dir);
#ifndef VMS
unknown's avatar
unknown committed
103
      /* Default creation of new files */
unknown's avatar
unknown committed
104
      if ((str=getenv("UMASK")) != 0)
unknown's avatar
unknown committed
105 106
	my_umask=(int) (atoi_octal(str) | 0600);
	/* Default creation of new dir's */
unknown's avatar
unknown committed
107
      if ((str=getenv("UMASK_DIR")) != 0)
unknown's avatar
unknown committed
108
	my_umask_dir=(int) (atoi_octal(str) | 0700);
unknown's avatar
unknown committed
109 110 111 112 113 114 115 116 117
#endif
#ifdef VMS
      init_ctype();			/* Stupid linker don't link _ctype.c */
#endif
      DBUG_PRINT("exit",("home: '%s'",home_dir));
    }
#ifdef __WIN__
    win32_init_tcp_ip();
#endif
118
    DBUG_RETURN(0);
unknown's avatar
unknown committed
119 120 121 122 123 124 125 126
  }
} /* my_init */


	/* End my_sys */

void my_end(int infoflag)
{
127 128 129 130 131
  /*
    this code is suboptimal to workaround a bug in
    Sun CC: Sun C++ 5.6 2004/06/02 for x86, and should not be
    optimized until this compiler is not in use anymore
  */
132
  FILE *info_file= DBUG_FILE;
133
  my_bool print_info= (info_file != stderr);
134 135 136 137
  /* We do not use DBUG_ENTER here, as after cleanup DBUG is no longer
     operational, so we cannot use DBUG_RETURN.
  */
  DBUG_PRINT("info",("Shutting down"));
138 139 140 141 142 143 144 145 146
  if (!info_file)
  {
    info_file= stderr;
    print_info= 0;
  }

  DBUG_PRINT("info",("Shutting down: print_info: %d", print_info));
  if ((infoflag & MY_CHECK_ERROR) || print_info)

unknown's avatar
unknown committed
147 148 149 150 151 152 153 154
  {					/* Test if some file is left open */
    if (my_file_opened | my_stream_opened)
    {
      sprintf(errbuff[0],EE(EE_OPEN_WARNING),my_file_opened,my_stream_opened);
      (void) my_message_no_curses(EE_OPEN_WARNING,errbuff[0],ME_BELL);
      DBUG_PRINT("error",("%s",errbuff[0]));
    }
  }
155
  free_charsets();
156
  my_once_free();
157 158

  if ((infoflag & MY_GIVE_INFO) || print_info)
unknown's avatar
unknown committed
159 160 161
  {
#ifdef HAVE_GETRUSAGE
    struct rusage rus;
162 163 164 165
#ifdef HAVE_purify
    /* Purify assumes that rus is uninitialized after getrusage call */
    bzero((char*) &rus, sizeof(rus));
#endif
unknown's avatar
unknown committed
166
    if (!getrusage(RUSAGE_SELF, &rus))
167 168 169 170 171 172
      fprintf(info_file,"\n\
User time %.2f, System time %.2f\n\
Maximum resident set size %ld, Integral resident set size %ld\n\
Non-physical pagefaults %ld, Physical pagefaults %ld, Swaps %ld\n\
Blocks in %ld out %ld, Messages in %ld out %ld, Signals %ld\n\
Voluntary context switches %ld, Involuntary context switches %ld\n",
unknown's avatar
unknown committed
173 174 175 176 177 178 179 180 181 182
	      (rus.ru_utime.tv_sec * SCALE_SEC +
	       rus.ru_utime.tv_usec / SCALE_USEC) / 100.0,
	      (rus.ru_stime.tv_sec * SCALE_SEC +
	       rus.ru_stime.tv_usec / SCALE_USEC) / 100.0,
	      rus.ru_maxrss, rus.ru_idrss,
	      rus.ru_minflt, rus.ru_majflt,
	      rus.ru_nswap, rus.ru_inblock, rus.ru_oublock,
	      rus.ru_msgsnd, rus.ru_msgrcv, rus.ru_nsignals,
	      rus.ru_nvcsw, rus.ru_nivcsw);
#endif
unknown's avatar
unknown committed
183
#if ( defined(MSDOS) || defined(__NETWARE__) ) && !defined(__WIN__)
unknown's avatar
unknown committed
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
    fprintf(info_file,"\nRun time: %.1f\n",(double) clock()/CLOCKS_PER_SEC);
#endif
#if defined(SAFEMALLOC)
    TERMINATE(stderr);		/* Give statistic on screen */
#elif defined(__WIN__) && defined(_MSC_VER)
   _CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE );
   _CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDERR );
   _CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE );
   _CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDERR );
   _CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE );
   _CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDERR );
   _CrtCheckMemory();
   _CrtDumpMemoryLeaks();
#endif
  }
#ifdef THREAD
  DBUG_POP();				/* Must be done before my_thread_end */
  my_thread_end();
  my_thread_global_end();
unknown's avatar
unknown committed
203 204 205 206 207 208 209 210 211
#if defined(SAFE_MUTEX)
  /*
    Check on destroying of mutexes. A few may be left that will get cleaned
    up by C++ destructors
  */
  safe_mutex_end(infoflag & MY_GIVE_INFO ? stderr : (FILE *) 0);
#endif /* defined(SAFE_MUTEX) */
#endif /* THREAD */

unknown's avatar
unknown committed
212
#ifdef __WIN__
unknown's avatar
unknown committed
213 214
  if (have_tcpip)
    WSACleanup();
unknown's avatar
unknown committed
215
#endif /* __WIN__ */
unknown's avatar
unknown committed
216
  my_init_done=0;
unknown's avatar
unknown committed
217 218
} /* my_end */

unknown's avatar
unknown committed
219

unknown's avatar
unknown committed
220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262
#ifdef __WIN__

/*
  This code is specially for running MySQL, but it should work in
  other cases too.

  Inizializzazione delle variabili d'ambiente per Win a 32 bit.

  Vengono inserite nelle variabili d'ambiente (utilizzando cosi'
  le funzioni getenv e putenv) i valori presenti nelle chiavi
  del file di registro:

  HKEY_LOCAL_MACHINE\software\MySQL

  Se la kiave non esiste nonn inserisce nessun valore
*/

/* Crea la stringa d'ambiente */

void setEnvString(char *ret, const char *name, const char *value)
{
  DBUG_ENTER("setEnvString");
  strxmov(ret, name,"=",value,NullS);
  DBUG_VOID_RETURN ;
}

static void my_win_init(void)
{
  HKEY	hSoftMysql ;
  DWORD dimName = 256 ;
  DWORD dimData = 1024 ;
  DWORD dimNameValueBuffer = 256 ;
  DWORD dimDataValueBuffer = 1024 ;
  DWORD indexValue = 0 ;
  long	retCodeEnumValue ;
  char	NameValueBuffer[256] ;
  char	DataValueBuffer[1024] ;
  char	EnvString[1271] ;
  const char *targetKey = "Software\\MySQL" ;
  DBUG_ENTER("my_win_init");

  setlocale(LC_CTYPE, "");             /* To get right sortorder */

unknown's avatar
unknown committed
263 264 265 266 267
#if defined(_MSC_VER) && (_MSC_VER < 1300)
  /* 
    Clear the OS system variable TZ and avoid the 100% CPU usage
    Only for old versions of Visual C++
  */
268
  _putenv( "TZ=" ); 
unknown's avatar
unknown committed
269
#endif  
270 271
  _tzset();

unknown's avatar
unknown committed
272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294
  /* apre la chiave HKEY_LOCAL_MACHINES\software\MySQL */
  if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,(LPCTSTR)targetKey,0,
		   KEY_READ,&hSoftMysql) != ERROR_SUCCESS)
    DBUG_VOID_RETURN;

  /*
  ** Ne legge i valori e li inserisce  nell'ambiente
  ** suppone che tutti i valori letti siano di tipo stringa + '\0'
  ** Legge il valore con indice 0 e lo scarta
  */
  retCodeEnumValue = RegEnumValue(hSoftMysql, indexValue++,
				  (LPTSTR)NameValueBuffer, &dimNameValueBuffer,
				  NULL, NULL, (LPBYTE)DataValueBuffer,
				  &dimDataValueBuffer) ;

  while (retCodeEnumValue != ERROR_NO_MORE_ITEMS)
  {
    char *my_env;
    /* Crea la stringa d'ambiente */
    setEnvString(EnvString, NameValueBuffer, DataValueBuffer) ;

    /* Inserisce i dati come variabili d'ambiente */
    my_env=strdup(EnvString);  /* variable for putenv must be allocated ! */
295
    putenv(my_env) ;
unknown's avatar
unknown committed
296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312

    dimNameValueBuffer = dimName ;
    dimDataValueBuffer = dimData ;

    retCodeEnumValue = RegEnumValue(hSoftMysql, indexValue++,
				    NameValueBuffer, &dimNameValueBuffer,
				    NULL, NULL, (LPBYTE)DataValueBuffer,
				    &dimDataValueBuffer) ;
  }

  /* chiude la chiave */
  RegCloseKey(hSoftMysql) ;
  DBUG_VOID_RETURN ;
}


/*------------------------------------------------------------------
unknown's avatar
unknown committed
313 314 315 316
  Name: CheckForTcpip| Desc: checks if tcpip has been installed on system
  According to Microsoft Developers documentation the first registry
  entry should be enough to check if TCP/IP is installed, but as expected
  this doesn't work on all Win32 machines :(
unknown's avatar
unknown committed
317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341
------------------------------------------------------------------*/

#define TCPIPKEY  "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters"
#define WINSOCK2KEY "SYSTEM\\CurrentControlSet\\Services\\Winsock2\\Parameters"
#define WINSOCKKEY  "SYSTEM\\CurrentControlSet\\Services\\Winsock\\Parameters"

static my_bool win32_have_tcpip(void)
{
  HKEY hTcpipRegKey;
  if (RegOpenKeyEx ( HKEY_LOCAL_MACHINE, TCPIPKEY, 0, KEY_READ,
		      &hTcpipRegKey) != ERROR_SUCCESS)
  {
    if (RegOpenKeyEx ( HKEY_LOCAL_MACHINE, WINSOCK2KEY, 0, KEY_READ,
		      &hTcpipRegKey) != ERROR_SUCCESS)
    {
      if (RegOpenKeyEx ( HKEY_LOCAL_MACHINE, WINSOCKKEY, 0, KEY_READ,
			 &hTcpipRegKey) != ERROR_SUCCESS)
	if (!getenv("HAVE_TCPIP") || have_tcpip)	/* Provide a workaround */
	  return (FALSE);
    }
  }
  RegCloseKey ( hTcpipRegKey);
  return (TRUE);
}

unknown's avatar
unknown committed
342

unknown's avatar
unknown committed
343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373
static my_bool win32_init_tcp_ip()
{
  if (win32_have_tcpip())
  {
    WORD wVersionRequested = MAKEWORD( 2, 0 );
    WSADATA wsaData;
 	/* Be a good citizen: maybe another lib has already initialised
 		sockets, so dont clobber them unless necessary */
    if (WSAStartup( wVersionRequested, &wsaData ))
    {
      /* Load failed, maybe because of previously loaded
	 incompatible version; try again */
      WSACleanup( );
      if (!WSAStartup( wVersionRequested, &wsaData ))
	have_tcpip=1;
    }
    else
    {
      if (wsaData.wVersion != wVersionRequested)
      {
	/* Version is no good, try again */
	WSACleanup( );
	if (!WSAStartup( wVersionRequested, &wsaData ))
	  have_tcpip=1;
      }
      else
	have_tcpip=1;
    }
  }
  return(0);
}
unknown's avatar
unknown committed
374 375 376 377
#endif /* __WIN__ */


#ifdef __NETWARE__
unknown's avatar
unknown committed
378 379 380
/*
  Basic initialisation for netware
*/
unknown's avatar
unknown committed
381 382 383

static void netware_init()
{
384
  char cwd[PATH_MAX], *name;
unknown's avatar
unknown committed
385

unknown's avatar
unknown committed
386 387
  DBUG_ENTER("netware_init");

unknown's avatar
unknown committed
388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411
  /* init only if we are not a client library */
  if (my_progname)
  {
#if SUPPORTED_BY_LIBC   /* Removed until supported in Libc */
    struct termios tp;
    /* Disable control characters */
    tcgetattr(STDIN_FILENO, &tp);
    tp.c_cc[VINTR] = _POSIX_VDISABLE;
    tp.c_cc[VEOF] = _POSIX_VDISABLE;
    tp.c_cc[VSUSP] = _POSIX_VDISABLE;
    tcsetattr(STDIN_FILENO, TCSANOW, &tp);
#endif /* SUPPORTED_BY_LIBC */

    /* With stdout redirection */
    if (!isatty(STDOUT_FILENO))
    {
      setscreenmode(SCR_AUTOCLOSE_ON_EXIT);      /* auto close the screen */
    }
    else
    {
      setscreenmode(SCR_NO_MODE);		/* keep the screen up */
    }

    /* Parse program name and change to base format */
unknown's avatar
unknown committed
412
    name= (char*) my_progname;
unknown's avatar
unknown committed
413 414 415 416
    for (; *name; name++)
    {
      if (*name == '\\')
      {
417
        *name = '/';
unknown's avatar
unknown committed
418 419 420
      }
      else
      {
421
        *name = tolower(*name);
unknown's avatar
unknown committed
422 423 424
      }
    }
  }
unknown's avatar
unknown committed
425 426

  DBUG_VOID_RETURN;
unknown's avatar
unknown committed
427 428
}
#endif /* __NETWARE__ */