1 /*
2    Copyright (c) 2001, 2021, Oracle and/or its affiliates.
3 
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License, version 2.0,
6    as published by the Free Software Foundation.
7 
8    This program is also distributed with certain software (including
9    but not limited to OpenSSL) that is licensed under separate terms,
10    as designated in a particular file or component or in included license
11    documentation.  The authors of MySQL hereby grant you an additional
12    permission to link the program and your derivative works with the
13    separately licensed software that they have included with MySQL.
14 
15    Without limiting anything contained in the foregoing, this file,
16    which is part of C Driver for MySQL (Connector/C), is also subject to the
17    Universal FOSS Exception, version 1.0, a copy of which can be found at
18    http://oss.oracle.com/licenses/universal-foss-exception.
19 
20    This program is distributed in the hope that it will be useful,
21    but WITHOUT ANY WARRANTY; without even the implied warranty of
22    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23    GNU General Public License, version 2.0, for more details.
24 
25    You should have received a copy of the GNU General Public License
26    along with this program; if not, write to the Free Software
27    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA */
28 
29 #ifndef MY_GLOBAL_INCLUDED
30 #define MY_GLOBAL_INCLUDED
31 
32 /*
33   This include file should be included first in every header file.
34 
35   This makes sure my_config.h is included to get platform specific
36   symbols defined and it makes sure a lot of platform/compiler
37   differences are mitigated.
38 */
39 
40 #include "my_config.h"
41 
42 #define __STDC_LIMIT_MACROS	/* Enable C99 limit macros */
43 #define __STDC_FORMAT_MACROS	/* Enable C99 printf format macros */
44 #define _USE_MATH_DEFINES       /* Get access to M_PI, M_E, etc. in math.h */
45 
46 #ifdef _WIN32
47 /* Include common headers.*/
48 # include <winsock2.h>
49 # include <ws2tcpip.h> /* SOCKET */
50 # include <io.h>       /* access(), chmod() */
51 #endif
52 
53 #include <stdio.h>
54 #include <stdarg.h>
55 #include <stdlib.h>
56 #include <stddef.h>
57 #include <math.h>
58 #include <limits.h>
59 #include <float.h>
60 #include <fcntl.h>
61 #include <time.h>
62 #include <errno.h>				/* Recommended by debian */
63 #include <sys/types.h>
64 
65 #ifdef HAVE_SYS_SOCKET_H
66 #include <sys/socket.h>
67 #endif
68 #if !defined(_WIN32)
69 #include <netdb.h>
70 #endif
71 #ifdef MY_MSCRT_DEBUG
72 #include <crtdbg.h>
73 #endif
74 
75 /*
76   A lot of our programs uses asserts, so better to always include it
77   This also fixes a problem when people uses assert without including
78   assert.h
79 */
80 #include <assert.h>
81 
82 /* Include standard definitions of operator new and delete. */
83 #ifdef __cplusplus
84 # include <new>
85 #endif
86 
87 #include "my_compiler.h"
88 
89 
90 /*
91   InnoDB depends on some MySQL internals which other plugins should not
92   need.  This is because of InnoDB's foreign key support, "safe" binlog
93   truncation, and other similar legacy features.
94 
95   We define accessors for these internals unconditionally, but do not
96   expose them in mysql/plugin.h.  They are declared in ha_innodb.h for
97   InnoDB's use.
98 */
99 #define INNODB_COMPATIBILITY_HOOKS
100 
101 /* Macros to make switching between C and C++ mode easier */
102 #ifdef __cplusplus
103 #define C_MODE_START    extern "C" {
104 #define C_MODE_END	}
105 #else
106 #define C_MODE_START
107 #define C_MODE_END
108 #endif
109 
110 #ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
111 #define HAVE_PSI_INTERFACE
112 #endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */
113 
114 /* Make it easier to add conditional code in _expressions_ */
115 #ifdef _WIN32
116 #define IF_WIN(A,B) A
117 #else
118 #define IF_WIN(A,B) B
119 #endif
120 
121 #if defined (_WIN32)
122 /*
123  off_t is 32 bit long. We do not use C runtime functions
124  with off_t but native Win32 file IO APIs, that work with
125  64 bit offsets.
126 */
127 #undef SIZEOF_OFF_T
128 #define SIZEOF_OFF_T 8
129 
sleep(unsigned long seconds)130 static inline void sleep(unsigned long seconds)
131 {
132   Sleep(seconds * 1000);
133 }
134 
135 /* Define missing access() modes. */
136 #define F_OK 0
137 #define W_OK 2
138 #define R_OK 4                        /* Test for read permission.  */
139 
140 /* Define missing file locking constants. */
141 #define F_RDLCK 1
142 #define F_WRLCK 2
143 #define F_UNLCK 3
144 #define F_TO_EOF 0x3FFFFFFF
145 
146 #define O_NONBLOCK 1    /* For emulation of fcntl() */
147 
148 /*
149   SHUT_RDWR is called SD_BOTH in windows and
150   is defined to 2 in winsock2.h
151   #define SD_BOTH 0x02
152 */
153 #define SHUT_RDWR 0x02
154 
155 /* Shared memory and named pipe connections are supported. */
156 #define shared_memory_buffer_length 16000
157 #define default_shared_memory_base_name "MYSQL"
158 #endif /* _WIN32*/
159 
160 /**
161   Cast a member of a structure to the structure that contains it.
162 
163   @param  ptr     Pointer to the member.
164   @param  type    Type of the structure that contains the member.
165   @param  member  Name of the member within the structure.
166 */
167 #define my_container_of(ptr, type, member)              \
168   ((type *)((char *)ptr - offsetof(type, member)))
169 
170 /* an assert that works at compile-time. only for constant expression */
171 #define compile_time_assert(X)                                              \
172   do                                                                        \
173   {                                                                         \
174     typedef char compile_time_assert[(X) ? 1 : -1] MY_ATTRIBUTE((unused)); \
175   } while(0)
176 
177 #define QUOTE_ARG(x)		#x	/* Quote argument (before cpp) */
178 #define STRINGIFY_ARG(x) QUOTE_ARG(x)	/* Quote argument, after cpp */
179 
180 #ifdef _WIN32
181 #define SO_EXT ".dll"
182 #elif defined(__APPLE__)
183 #define SO_EXT ".dylib"
184 #else
185 #define SO_EXT ".so"
186 #endif
187 
188 #if !defined(HAVE_UINT)
189 typedef unsigned int uint;
190 typedef unsigned short ushort;
191 #endif
192 
193 #define swap_variables(t, a, b) { t dummy; dummy= a; a= b; b= dummy; }
194 #define MY_TEST(a)		((a) ? 1 : 0)
195 #define set_if_bigger(a,b)  do { if ((a) < (b)) (a)=(b); } while(0)
196 #define set_if_smaller(a,b) do { if ((a) > (b)) (a)=(b); } while(0)
197 #define test_all_bits(a,b) (((a) & (b)) == (b))
198 #define array_elements(A) ((uint) (sizeof(A)/sizeof(A[0])))
199 
200 /* Define some general constants */
201 #ifndef TRUE
202 #define TRUE		(1)	/* Logical true */
203 #define FALSE		(0)	/* Logical false */
204 #endif
205 
206 /* Some types that is different between systems */
207 
208 typedef int	File;		/* File descriptor */
209 #ifdef _WIN32
210 typedef SOCKET my_socket;
211 #else
212 typedef int	my_socket;	/* File descriptor for sockets */
213 #define INVALID_SOCKET -1
214 #endif
215 C_MODE_START
216 typedef void	(*sig_return)();/* Returns type from signal */
217 C_MODE_END
218 #if defined(__GNUC__)
219 typedef char	pchar;		/* Mixed prototypes can take char */
220 typedef char	pbool;		/* Mixed prototypes can take char */
221 #else
222 typedef int	pchar;		/* Mixed prototypes can't take char */
223 typedef int	pbool;		/* Mixed prototypes can't take char */
224 #endif
225 C_MODE_START
226 typedef int	(*qsort_cmp)(const void *,const void *);
227 typedef int	(*qsort_cmp2)(const void*, const void *,const void *);
228 C_MODE_END
229 #ifdef _WIN32
230 typedef int       socket_len_t;
231 typedef int       sigset_t;
232 typedef int       mode_t;
233 typedef SSIZE_T   ssize_t;
234 #else
235 typedef socklen_t socket_len_t;
236 #endif
237 typedef socket_len_t SOCKET_SIZE_TYPE; /* Used by NDB */
238 
239 /* file create flags */
240 
241 #ifndef O_SHARE			/* Probably not windows */
242 #define O_SHARE		0	/* Flag to my_open for shared files */
243 #ifndef O_BINARY
244 #define O_BINARY	0	/* Flag to my_open for binary files */
245 #endif
246 #ifndef FILE_BINARY
247 #define FILE_BINARY	O_BINARY /* Flag to my_fopen for binary streams */
248 #endif
249 #ifdef HAVE_FCNTL
250 #define HAVE_FCNTL_LOCK
251 #define F_TO_EOF	0L	/* Param to lockf() to lock rest of file */
252 #endif
253 #endif /* O_SHARE */
254 
255 #ifndef O_TEMPORARY
256 #define O_TEMPORARY	0
257 #endif
258 #ifndef O_SHORT_LIVED
259 #define O_SHORT_LIVED	0
260 #endif
261 #ifndef O_NOFOLLOW
262 #define O_NOFOLLOW      0
263 #endif
264 
265 /* additional file share flags for win32 */
266 #ifdef _WIN32
267 #define _SH_DENYRWD     0x110    /* deny read/write mode & delete */
268 #define _SH_DENYWRD     0x120    /* deny write mode & delete      */
269 #define _SH_DENYRDD     0x130    /* deny read mode & delete       */
270 #define _SH_DENYDEL     0x140    /* deny delete only              */
271 #endif /* _WIN32 */
272 
273 
274 /* General constants */
275 #define FN_LEN		256	/* Max file name len */
276 #define FN_HEADLEN	253	/* Max length of filepart of file name */
277 #define FN_EXTLEN	20	/* Max length of extension (part of FN_LEN) */
278 #define FN_REFLEN	512	/* Max length of full path-name */
279 #define FN_REFLEN_SE	4000	/* Max length of full path-name in SE */
280 #define FN_EXTCHAR	'.'
281 #define FN_HOMELIB	'~'	/* ~/ is used as abbrev for home dir */
282 #define FN_CURLIB	'.'	/* ./ is used as abbrev for current dir */
283 #define FN_PARENTDIR	".."	/* Parent directory; Must be a string */
284 
285 #ifdef _WIN32
286 #define FN_LIBCHAR	'\\'
287 #define FN_LIBCHAR2	'/'
288 #define FN_DIRSEP       "/\\"               /* Valid directory separators */
289 #define FN_EXEEXT   ".exe"
290 #define FN_SOEXT    ".dll"
291 #define FN_ROOTDIR	"\\"
292 #define FN_DEVCHAR	':'
293 #define FN_NETWORK_DRIVES	/* Uses \\ to indicate network drives */
294 #else
295 #define FN_LIBCHAR	'/'
296 /*
297   FN_LIBCHAR2 is not defined on !Windows. Use is_directory_separator().
298 */
299 #define FN_DIRSEP       "/"     /* Valid directory separators */
300 #define FN_EXEEXT   ""
301 #define FN_SOEXT    ".so"
302 #define FN_ROOTDIR	"/"
303 #endif
304 
is_directory_separator(char c)305 static inline int is_directory_separator(char c)
306 {
307 #ifdef _WIN32
308   return c == FN_LIBCHAR || c == FN_LIBCHAR2;
309 #else
310   return c == FN_LIBCHAR;
311 #endif
312 }
313 
314 /*
315   MY_FILE_MIN is  Windows speciality and is used to quickly detect
316   the mismatch of CRT and mysys file IO usage on Windows at runtime.
317   CRT file descriptors can be in the range 0-2047, whereas descriptors returned
318   by my_open() will start with 2048. If a file descriptor with value less then
319   MY_FILE_MIN is passed to mysys IO function, chances are it stemms from
320   open()/fileno() and not my_open()/my_fileno.
321 
322   For Posix,  mysys functions are light wrappers around libc, and MY_FILE_MIN
323   is logically 0.
324 */
325 
326 #ifdef _WIN32
327 #define MY_FILE_MIN  2048
328 #else
329 #define MY_FILE_MIN  0
330 #endif
331 
332 /*
333   MY_NFILE is the default size of my_file_info array.
334 
335   It is larger on Windows, because it all file handles are stored in my_file_info
336   Default size is 16384 and this should be enough for most cases.If it is not
337   enough, --max-open-files with larger value can be used.
338 
339   For Posix , my_file_info array is only used to store filenames for
340   error reporting and its size is not a limitation for number of open files.
341 */
342 #ifdef _WIN32
343 #define MY_NFILE (16384 + MY_FILE_MIN)
344 #else
345 #define MY_NFILE 64
346 #endif
347 
348 #define OS_FILE_LIMIT	UINT_MAX
349 
350 /*
351   Io buffer size; Must be a power of 2 and a multiple of 512. May be
352   smaller what the disk page size. This influences the speed of the
353   isam btree library. eg to big to slow.
354 */
355 #define IO_SIZE			4096
356 /*
357   How much overhead does malloc have. The code often allocates
358   something like 1024-MALLOC_OVERHEAD bytes
359 */
360 #define MALLOC_OVERHEAD 8
361 
362 	/* get memory in huncs */
363 #define ONCE_ALLOC_INIT		(uint) (4096-MALLOC_OVERHEAD)
364 	/* Typical record cash */
365 #define RECORD_CACHE_SIZE	(uint) (64*1024-MALLOC_OVERHEAD)
366 	/* Typical key cash */
367 #define KEY_CACHE_SIZE		(uint) (8*1024*1024)
368 	/* Default size of a key cache block  */
369 #define KEY_CACHE_BLOCK_SIZE	(uint) 1024
370 
371 
372 /* Some defines of functions for portability */
373 
374 #if (_WIN32)
375 #if !defined(_WIN64)
my_ulonglong2double(unsigned long long value)376 inline double my_ulonglong2double(unsigned long long value)
377 {
378   long long nr=(long long) value;
379   if (nr >= 0)
380     return (double) nr;
381   return (18446744073709551616.0 + (double) nr);
382 }
383 #define ulonglong2double my_ulonglong2double
384 #define my_off_t2double  my_ulonglong2double
385 #endif /* _WIN64 */
my_double2ulonglong(double d)386 inline unsigned long long my_double2ulonglong(double d)
387 {
388   double t= d - (double) 0x8000000000000000ULL;
389 
390   if (t >= 0)
391     return  ((unsigned long long) t) + 0x8000000000000000ULL;
392   return (unsigned long long) d;
393 }
394 #define double2ulonglong my_double2ulonglong
395 #endif /* _WIN32 */
396 
397 #ifndef ulonglong2double
398 #define ulonglong2double(A) ((double) (ulonglong) (A))
399 #define my_off_t2double(A)  ((double) (my_off_t) (A))
400 #endif
401 #ifndef double2ulonglong
402 #define double2ulonglong(A) ((ulonglong) (double) (A))
403 #endif
404 
405 #define INT_MIN64       (~0x7FFFFFFFFFFFFFFFLL)
406 #define INT_MAX64       0x7FFFFFFFFFFFFFFFLL
407 #define INT_MIN32       (~0x7FFFFFFFL)
408 #define INT_MAX32       0x7FFFFFFFL
409 #define UINT_MAX32      0xFFFFFFFFL
410 #define INT_MIN24       (~0x007FFFFF)
411 #define INT_MAX24       0x007FFFFF
412 #define UINT_MAX24      0x00FFFFFF
413 #define INT_MIN16       (~0x7FFF)
414 #define INT_MAX16       0x7FFF
415 #define UINT_MAX16      0xFFFF
416 #define INT_MIN8        (~0x7F)
417 #define INT_MAX8        0x7F
418 #define UINT_MAX8       0xFF
419 
420 #ifndef SIZE_T_MAX
421 #define SIZE_T_MAX      (~((size_t) 0))
422 #endif
423 
424 // Our ifdef trickery for my_isfinite does not work with gcc/solaris unless we:
425 #ifdef HAVE_IEEEFP_H
426 #include <ieeefp.h>
427 #endif
428 
429 #if (__cplusplus >= 201103L)
430   /* For C++11 use the new std functions rather than C99 macros. */
431   #include <cmath>
432   #define my_isfinite(X) std::isfinite(X)
433   #define my_isnan(X) std::isnan(X)
434   #define my_isinf(X) std::isinf(X)
435 #else
436   #ifdef HAVE_LLVM_LIBCPP /* finite is deprecated in libc++ */
437     #define my_isfinite(X) isfinite(X)
438   #elif defined _WIN32
439     #define my_isfinite(X) _finite(X)
440   #else
441     #define my_isfinite(X) finite(X)
442   #endif
443   #define my_isnan(X) isnan(X)
444   #ifdef HAVE_ISINF
445     /* System-provided isinf() is available and safe to use */
446     #define my_isinf(X) isinf(X)
447   #else /* !HAVE_ISINF */
448     #define my_isinf(X) (!my_isfinite(X) && !my_isnan(X))
449   #endif
450 #endif /* __cplusplus >= 201103L */
451 
452 /*
453   Max size that must be added to a so that we know Size to make
454   adressable obj.
455 */
456 #if SIZEOF_CHARP == 4
457 typedef long		my_ptrdiff_t;
458 #else
459 typedef long long	my_ptrdiff_t;
460 #endif
461 
462 #define MY_ALIGN(A,L)	(((A) + (L) - 1) & ~((L) - 1))
463 #define ALIGN_SIZE(A)	MY_ALIGN((A),sizeof(double))
464 /* Size to make adressable obj. */
465 #define ADD_TO_PTR(ptr,size,type) (type) ((uchar*) (ptr)+size)
466 #define PTR_BYTE_DIFF(A,B) (my_ptrdiff_t) ((uchar*) (A) - (uchar*) (B))
467 
468 /*
469   Custom version of standard offsetof() macro which can be used to get
470   offsets of members in class for non-POD types (according to the current
471   version of C++ standard offsetof() macro can't be used in such cases and
472   attempt to do so causes warnings to be emitted, OTOH in many cases it is
473   still OK to assume that all instances of the class has the same offsets
474   for the same members).
475 
476   This is temporary solution which should be removed once File_parser class
477   and related routines are refactored.
478 */
479 
480 #define my_offsetof(TYPE, MEMBER) \
481         ((size_t)((char *)&(((TYPE *)0x10)->MEMBER) - (char*)0x10))
482 
483 #define NullS		(char *) 0
484 
485 #ifdef _WIN32
486 #define STDCALL __stdcall
487 #else
488 #define STDCALL
489 #endif
490 
491 /* Typdefs for easyier portability */
492 
493 typedef unsigned char	uchar;	/* Short for unsigned char */
494 typedef signed char int8;       /* Signed integer >= 8  bits */
495 typedef unsigned char uint8;    /* Unsigned integer >= 8  bits */
496 typedef short int16;
497 typedef unsigned short uint16;
498 #if SIZEOF_INT == 4
499 typedef int int32;
500 typedef unsigned int uint32;
501 #elif SIZEOF_LONG == 4
502 typedef long int32;
503 typedef unsigned long uint32;
504 #else
505 #error Neither int or long is of 4 bytes width
506 #endif
507 
508 #if !defined(HAVE_ULONG)
509 typedef unsigned long	ulong;		  /* Short for unsigned long */
510 #endif
511 /*
512   Using [unsigned] long long is preferable as [u]longlong because we use
513   [unsigned] long long unconditionally in many places,
514   for example in constants with [U]LL suffix.
515 */
516 typedef unsigned long long int ulonglong; /* ulong or unsigned long long */
517 typedef long long int	longlong;
518 typedef longlong int64;
519 typedef ulonglong uint64;
520 
521 #if defined (_WIN32)
522 typedef unsigned __int64 my_ulonglong;
523 #else
524 typedef unsigned long long my_ulonglong;
525 #endif
526 
527 #if SIZEOF_CHARP == SIZEOF_INT
528 typedef int intptr;
529 #elif SIZEOF_CHARP == SIZEOF_LONG
530 typedef long intptr;
531 #elif SIZEOF_CHARP == SIZEOF_LONG_LONG
532 typedef long long intptr;
533 #else
534 #error sizeof(void *) is neither sizeof(int) nor sizeof(long) nor sizeof(long long)
535 #endif
536 
537 #define MY_ERRPTR ((void*)(intptr)1)
538 
539 #if defined(_WIN32)
540 typedef unsigned long long my_off_t;
541 typedef unsigned long long os_off_t;
542 #else
543 typedef off_t os_off_t;
544 #if SIZEOF_OFF_T > 4
545 typedef ulonglong my_off_t;
546 #else
547 typedef unsigned long my_off_t;
548 #endif
549 #endif /*_WIN32*/
550 #define MY_FILEPOS_ERROR	(~(my_off_t) 0)
551 
552 /*
553   TODO Convert these to use Bitmap class.
554  */
555 typedef ulonglong table_map;          /* Used for table bits in join */
556 typedef ulonglong nesting_map;  /* Used for flags of nesting constructs */
557 
558 #if defined(_WIN32)
559 #define socket_errno	WSAGetLastError()
560 #define SOCKET_EINTR	WSAEINTR
561 #define SOCKET_EAGAIN	WSAEINPROGRESS
562 #define SOCKET_EWOULDBLOCK WSAEWOULDBLOCK
563 #define SOCKET_EADDRINUSE WSAEADDRINUSE
564 #define SOCKET_ETIMEDOUT WSAETIMEDOUT
565 #define SOCKET_ECONNRESET WSAECONNRESET
566 #define SOCKET_ENFILE	ENFILE
567 #define SOCKET_EMFILE	EMFILE
568 #else /* Unix */
569 #define socket_errno	errno
570 #define closesocket(A)	close(A)
571 #define SOCKET_EINTR	EINTR
572 #define SOCKET_EAGAIN	EAGAIN
573 #define SOCKET_EWOULDBLOCK EWOULDBLOCK
574 #define SOCKET_EADDRINUSE EADDRINUSE
575 #define SOCKET_ETIMEDOUT ETIMEDOUT
576 #define SOCKET_ECONNRESET ECONNRESET
577 #define SOCKET_ENFILE	ENFILE
578 #define SOCKET_EMFILE	EMFILE
579 #endif
580 
581 typedef int		myf;	/* Type of MyFlags in my_funcs */
582 typedef char		my_bool; /* Small bool */
583 
584 /* Macros for converting *constants* to the right type */
585 #define MYF(v)		(myf) (v)
586 
587 /* Some helper macros */
588 #define YESNO(X) ((X) ? "yes" : "no")
589 
590 #define MY_HOW_OFTEN_TO_WRITE	1000	/* How often we want info on screen */
591 
592 #include <my_byteorder.h>
593 
594 #ifdef HAVE_CHARSET_utf8
595 #define MYSQL_UNIVERSAL_CLIENT_CHARSET "utf8"
596 #else
597 #define MYSQL_UNIVERSAL_CLIENT_CHARSET MYSQL_DEFAULT_CHARSET_NAME
598 #endif
599 
600 #if defined(_WIN32)
601 #define dlsym(lib, name) (void*)GetProcAddress((HMODULE)lib, name)
602 #define dlopen(libname, unused) LoadLibraryEx(libname, NULL, 0)
603 #define dlclose(lib) FreeLibrary((HMODULE)lib)
604 #ifndef HAVE_DLOPEN
605 #define HAVE_DLOPEN
606 #endif
607 #define DLERROR_GENERATE(errmsg, error_number) \
608   char win_errormsg[2048]; \
609   if(FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, \
610                    0, error_number, 0, win_errormsg, 2048, NULL)) \
611   { \
612     char *ptr; \
613     for (ptr= &win_errormsg[0] + strlen(win_errormsg) - 1; \
614          ptr >= &win_errormsg[0] && strchr("\r\n\t\0x20", *ptr); \
615          ptr--) \
616       *ptr= 0; \
617     errmsg= win_errormsg; \
618   } \
619   else \
620     errmsg= ""
621 #define dlerror() ""
622 #define dlopen_errno GetLastError()
623 
624 #else /* _WIN32 */
625 #define DLERROR_GENERATE(errmsg, error_number) errmsg= dlerror()
626 #define dlopen_errno errno
627 #endif /* _WIN32 */
628 
629 /* Length of decimal number represented by INT32. */
630 #define MY_INT32_NUM_DECIMAL_DIGITS 11U
631 
632 /* Length of decimal number represented by INT64. */
633 #define MY_INT64_NUM_DECIMAL_DIGITS 21U
634 
635 /* Define some useful general macros (should be done after all headers). */
636 #define MY_MAX(a, b)	((a) > (b) ? (a) : (b))
637 #define MY_MIN(a, b)	((a) < (b) ? (a) : (b))
638 
639 #if !defined(__cplusplus) && !defined(bool)
640 #define bool In_C_you_should_use_my_bool_instead()
641 #endif
642 
643 /*
644   MYSQL_PLUGIN_IMPORT macro is used to export mysqld data
645   (i.e variables) for usage in storage engine loadable plugins.
646   Outside of Windows, it is dummy.
647 */
648 #if (defined(_WIN32) && defined(MYSQL_DYNAMIC_PLUGIN))
649 #define MYSQL_PLUGIN_IMPORT __declspec(dllimport)
650 #else
651 #define MYSQL_PLUGIN_IMPORT
652 #endif
653 
654 #include <my_dbug.h>
655 
656 #ifdef EMBEDDED_LIBRARY
657 #define NO_EMBEDDED_ACCESS_CHECKS
658 /* Things we don't need in the embedded version of MySQL */
659 #undef HAVE_OPENSSL
660 #endif /* EMBEDDED_LIBRARY */
661 
662 
663 enum loglevel {
664    ERROR_LEVEL=       0,
665    WARNING_LEVEL=     1,
666    INFORMATION_LEVEL= 2
667 };
668 
669 
670 #ifdef _WIN32
671 /****************************************************************************
672 ** Replacements for localtime_r and gmtime_r
673 ****************************************************************************/
674 
localtime_r(const time_t * timep,struct tm * tmp)675 static inline struct tm *localtime_r(const time_t *timep, struct tm *tmp)
676 {
677   localtime_s(tmp, timep);
678   return tmp;
679 }
680 
gmtime_r(const time_t * clock,struct tm * res)681 static inline struct tm *gmtime_r(const time_t *clock, struct tm *res)
682 {
683   gmtime_s(res, clock);
684   return res;
685 }
686 #endif /* _WIN32 */
687 
688 #ifndef HAVE_STRUCT_TIMESPEC /* Windows before VS2015 */
689 /*
690   Declare a union to make sure FILETIME is properly aligned
691   so it can be used directly as a 64 bit value. The value
692   stored is in 100ns units.
693 */
694 union ft64 {
695   FILETIME ft;
696   __int64 i64;
697  };
698 
699 struct timespec {
700   union ft64 tv;
701   /* The max timeout value in millisecond for native_cond_timedwait */
702   long max_timeout_msec;
703 };
704 
705 #endif /* !HAVE_STRUCT_TIMESPEC */
706 
707 C_MODE_START
708 extern ulonglong my_getsystime(void);
709 C_MODE_END
710 
set_timespec_nsec(struct timespec * abstime,ulonglong nsec)711 static inline void set_timespec_nsec(struct timespec *abstime, ulonglong nsec)
712 {
713 #ifdef HAVE_STRUCT_TIMESPEC
714   ulonglong now= my_getsystime() + (nsec / 100);
715   ulonglong tv_sec= now / 10000000ULL;
716 #if SIZEOF_TIME_T < SIZEOF_LONG_LONG
717   /* Ensure that the number of seconds don't overflow. */
718   tv_sec= MY_MIN(tv_sec, ((ulonglong)INT_MAX32));
719 #endif
720   abstime->tv_sec=  (time_t)tv_sec;
721   abstime->tv_nsec= (now % 10000000ULL) * 100 + (nsec % 100);
722 #else /* !HAVE_STRUCT_TIMESPEC */
723   ulonglong max_timeout_msec= (nsec / 1000000);
724   union ft64 tv;
725   GetSystemTimeAsFileTime(&tv.ft);
726   abstime->tv.i64= tv.i64 + (__int64)(nsec / 100);
727 #if SIZEOF_LONG < SIZEOF_LONG_LONG
728   /* Ensure that the msec value doesn't overflow. */
729   max_timeout_msec= MY_MIN(max_timeout_msec, ((ulonglong)INT_MAX32));
730 #endif
731   abstime->max_timeout_msec= (long)max_timeout_msec;
732 #endif /* !HAVE_STRUCT_TIMESPEC */
733 }
734 
set_timespec(struct timespec * abstime,ulonglong sec)735 static inline void set_timespec(struct timespec *abstime, ulonglong sec)
736 {
737   set_timespec_nsec(abstime, sec * 1000000000ULL);
738 }
739 
740 /**
741    Compare two timespec structs.
742 
743    @retval  1 If ts1 ends after ts2.
744    @retval -1 If ts1 ends before ts2.
745    @retval  0 If ts1 is equal to ts2.
746 */
cmp_timespec(struct timespec * ts1,struct timespec * ts2)747 static inline int cmp_timespec(struct timespec *ts1, struct timespec *ts2)
748 {
749 #ifdef HAVE_STRUCT_TIMESPEC
750   if (ts1->tv_sec > ts2->tv_sec ||
751       (ts1->tv_sec == ts2->tv_sec && ts1->tv_nsec > ts2->tv_nsec))
752     return 1;
753   if (ts1->tv_sec < ts2->tv_sec ||
754       (ts1->tv_sec == ts2->tv_sec && ts1->tv_nsec < ts2->tv_nsec))
755     return -1;
756 #else
757   if (ts1->tv.i64 > ts2->tv.i64)
758     return 1;
759   if (ts1->tv.i64 < ts2->tv.i64)
760     return -1;
761 #endif
762   return 0;
763 }
764 
diff_timespec(struct timespec * ts1,struct timespec * ts2)765 static inline ulonglong diff_timespec(struct timespec *ts1, struct timespec *ts2)
766 {
767 #ifdef HAVE_STRUCT_TIMESPEC
768   return (ts1->tv_sec - ts2->tv_sec) * 1000000000ULL +
769     ts1->tv_nsec - ts2->tv_nsec;
770 #else
771   return (ts1->tv.i64 - ts2->tv.i64) * 100;
772 #endif
773 }
774 
775 #ifdef _WIN32
776 typedef int MY_MODE;
777 #else
778 typedef mode_t MY_MODE;
779 #endif /* _WIN32 */
780 
781 /* File permissions */
782 #define USER_READ       (1L << 0)
783 #define USER_WRITE      (1L << 1)
784 #define USER_EXECUTE    (1L << 2)
785 #define GROUP_READ      (1L << 3)
786 #define GROUP_WRITE     (1L << 4)
787 #define GROUP_EXECUTE   (1L << 5)
788 #define OTHERS_READ     (1L << 6)
789 #define OTHERS_WRITE    (1L << 7)
790 #define OTHERS_EXECUTE  (1L << 8)
791 #define USER_RWX        USER_READ | USER_WRITE | USER_EXECUTE
792 #define GROUP_RWX       GROUP_READ | GROUP_WRITE | GROUP_EXECUTE
793 #define OTHERS_RWX      OTHERS_READ | OTHERS_WRITE | OTHERS_EXECUTE
794 
795 /* Defaults */
796 #define DEFAULT_SSL_CA_CERT     "ca.pem"
797 #define DEFAULT_SSL_CA_KEY      "ca-key.pem"
798 #define DEFAULT_SSL_SERVER_CERT "server-cert.pem"
799 #define DEFAULT_SSL_SERVER_KEY  "server-key.pem"
800 
801 #if defined(_WIN32) || defined(_WIN64)
802   #define strcasecmp _stricmp
803 #endif
804 #endif  // MY_GLOBAL_INCLUDED
805