1/*
2 Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
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 DBUG_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
130static 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)
189typedef unsigned int uint;
190typedef 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
208typedef int File; /* File descriptor */
209#ifdef _WIN32
210typedef SOCKET my_socket;
211#else
212typedef int my_socket; /* File descriptor for sockets */
213#define INVALID_SOCKET -1
214#endif
215C_MODE_START
216typedef void (*sig_return)();/* Returns type from signal */
217C_MODE_END
218#if defined(__GNUC__)
219typedef char pchar; /* Mixed prototypes can take char */
220typedef char pbool; /* Mixed prototypes can take char */
221#else
222typedef int pchar; /* Mixed prototypes can't take char */
223typedef int pbool; /* Mixed prototypes can't take char */
224#endif
225C_MODE_START
226typedef int (*qsort_cmp)(const void *,const void *);
227typedef int (*qsort_cmp2)(const void*, const void *,const void *);
228C_MODE_END
229#ifdef _WIN32
230typedef int socket_len_t;
231typedef int sigset_t;
232typedef int mode_t;
233typedef SSIZE_T ssize_t;
234#else
235typedef socklen_t socket_len_t;
236#endif
237typedef 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
305static 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)
376inline 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 */
386inline 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
457typedef long my_ptrdiff_t;
458#else
459typedef 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
493typedef unsigned char uchar; /* Short for unsigned char */
494typedef signed char int8; /* Signed integer >= 8 bits */
495typedef unsigned char uint8; /* Unsigned integer >= 8 bits */
496typedef short int16;
497typedef unsigned short uint16;
498#if SIZEOF_INT == 4
499typedef int int32;
500typedef unsigned int uint32;
501#elif SIZEOF_LONG == 4
502typedef long int32;
503typedef unsigned long uint32;
504#else
505#error Neither int or long is of 4 bytes width
506#endif
507
508#if !defined(HAVE_ULONG)
509typedef 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*/
516typedef unsigned long long int ulonglong; /* ulong or unsigned long long */
517typedef long long int longlong;
518typedef longlong int64;
519typedef ulonglong uint64;
520
521#if defined (_WIN32)
522typedef unsigned __int64 my_ulonglong;
523#else
524typedef unsigned long long my_ulonglong;
525#endif
526
527#if SIZEOF_CHARP == SIZEOF_INT
528typedef int intptr;
529#elif SIZEOF_CHARP == SIZEOF_LONG
530typedef long intptr;
531#elif SIZEOF_CHARP == SIZEOF_LONG_LONG
532typedef 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)
540typedef unsigned long long my_off_t;
541typedef unsigned long long os_off_t;
542#else
543typedef off_t os_off_t;
544#if SIZEOF_OFF_T > 4
545typedef ulonglong my_off_t;
546#else
547typedef 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 */
555typedef ulonglong table_map; /* Used for table bits in join */
556typedef 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
581typedef int myf; /* Type of MyFlags in my_funcs */
582typedef 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
663enum 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
675static inline struct tm *localtime_r(const time_t *timep, struct tm *tmp)
676{
677 localtime_s(tmp, timep);
678 return tmp;
679}
680
681static 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*/
694union ft64 {
695 FILETIME ft;
696 __int64 i64;
697 };
698
699struct 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
707C_MODE_START
708extern ulonglong my_getsystime(void);
709C_MODE_END
710
711static 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
735static 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*/
747static 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
765static 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
776typedef int MY_MODE;
777#else
778typedef 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