1 /* -*-pgsql-c-*- */
2 /*
3  *
4  * $Header$
5  *
6  * pgpool: a language independent connection pool server for PostgreSQL
7  * written by Tatsuo Ishii
8  *
9  * Copyright (c) 2003-2015	PgPool Global Development Group
10  *
11  * Permission to use, copy, modify, and distribute this software and
12  * its documentation for any purpose and without fee is hereby
13  * granted, provided that the above copyright notice appear in all
14  * copies and that both that copyright notice and this permission
15  * notice appear in supporting documentation, and that the name of the
16  * author not be used in advertising or publicity pertaining to
17  * distribution of the software without specific, written prior
18  * permission. The author makes no representations about the
19  * suitability of this software for any purpose.  It is provided "as
20  * is" without express or implied warranty.
21  *
22  * pool_type.h.: type definition header file
23  *
24  */
25 
26 #ifndef POOL_TYPE_H
27 #define POOL_TYPE_H
28 
29 #include "config.h"
30 #include <sys/types.h>
31 #include <sys/socket.h>
32 #include <stddef.h>
33 #include "libpq-fe.h"
34 /* Define common boolean type. C++ and BEOS already has it so exclude them. */
35 #ifdef c_plusplus
36 #ifndef __cplusplus
37 #define __cplusplus
38 #endif							/* __cplusplus */
39 #endif							/* c_plusplus */
40 
41 #ifndef __BEOS__
42 #ifndef __cplusplus
43 #ifndef bool
44 typedef char bool;
45 #endif
46 #ifndef true
47 #define true ((bool) 1)
48 #endif
49 #ifndef TRUE
50 #define TRUE ((bool) 1)
51 #endif
52 #ifndef false
53 #define false ((bool) 0)
54 #endif
55 #ifndef FALSE
56 #define FALSE ((bool) 0)
57 #endif
58 #endif							/* not C++ */
59 #endif							/* __BEOS__ */
60 
61 /* ----------------------------------------------------------------
62  *              Section 5:  offsetof, lengthof, endof, alignment
63  * ----------------------------------------------------------------
64  */
65 /*
66  * offsetof
67  *      Offset of a structure/union field within that structure/union.
68  *
69  *      XXX This is supposed to be part of stddef.h, but isn't on
70  *      some systems (like SunOS 4).
71  */
72 #ifndef offsetof
73 #define offsetof(type, field)   ((long) &((type *)0)->field)
74 #endif
75 
76 #define PointerIsValid(pointer) ((const void*)(pointer) != NULL)
77 typedef signed char int8;		/* == 8 bits */
78 typedef signed short int16;		/* == 16 bits */
79 typedef signed int int32;		/* == 32 bits */
80 
81 /*
82  * uintN
83  *		Unsigned integer, EXACTLY N BITS IN SIZE,
84  *		used for numerical computations and the
85  *		frontend/backend protocol.
86  */
87 typedef unsigned char uint8;	/* == 8 bits */
88 typedef unsigned short uint16;	/* == 16 bits */
89 typedef unsigned int uint32;	/* == 32 bits */
90 
91 #ifdef HAVE_LONG_INT_64
92 /* Plain "long int" fits, use it */
93 typedef long int int64;
94 typedef unsigned long int uint64;
95 
96 #define pool_atoi64 atol
97 #elif defined(HAVE_LONG_LONG_INT_64)
98 /* We have working support for "long long int", use that */
99 typedef long long int int64;
100 typedef unsigned long long int uint64;
101 #define pool_atoi64 atoll
102 #else
103 /* neither HAVE_LONG_INT_64 nor HAVE_LONG_LONG_INT_64 */
104 #error must have a working 64-bit integer datatype
105 #endif
106 
107 typedef enum
108 {
109 	LOAD_UNSELECTED = 0,
110 	LOAD_SELECTED
111 }			LOAD_BALANCE_STATUS;
112 
113 extern int	assert_enabled;
114 extern void ExceptionalCondition(const char *conditionName,
115 					 const char *errorType,
116 					 const char *fileName, int lineNumber) __attribute__((noreturn));
117 
118 #define MAXIMUM_ALIGNOF 8
119 
120 #define TYPEALIGN(ALIGNVAL,LEN)  \
121 	(((intptr_t) (LEN) + ((ALIGNVAL) - 1)) & ~((intptr_t) ((ALIGNVAL) - 1)))
122 
123 #define SHORTALIGN(LEN)			TYPEALIGN(ALIGNOF_SHORT, (LEN))
124 #define INTALIGN(LEN)			TYPEALIGN(ALIGNOF_INT, (LEN))
125 #define LONGALIGN(LEN)			TYPEALIGN(ALIGNOF_LONG, (LEN))
126 #define DOUBLEALIGN(LEN)		TYPEALIGN(ALIGNOF_DOUBLE, (LEN))
127 #define MAXALIGN(LEN)			TYPEALIGN(MAXIMUM_ALIGNOF, (LEN))
128 
129 /*
130  *  It seems that sockaddr_storage is now commonly used in place of sockaddr.
131  *  So, define it if it is not define yet, and create new SockAddr structure
132  *  that uses sockaddr_storage.
133  */
134 #ifdef HAVE_STRUCT_SOCKADDR_STORAGE
135 
136 #ifndef HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY
137 #ifdef HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY
138 #define ss_family __ss_family
139 #else
140 #error struct sockaddr_storage does not provide an ss_family member
141 #endif							/* HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY */
142 #endif							/* HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY */
143 
144 #ifdef HAVE_STRUCT_SOCKADDR_STORAGE___SS_LEN
145 #define ss_len __ss_len
146 #define HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN 1
147 #endif							/* HAVE_STRUCT_SOCKADDR_STORAGE___SS_LEN */
148 
149 #else							/* !HAVE_STRUCT_SOCKADDR_STORAGE */
150 
151 /* Define a struct sockaddr_storage if we don't have one. */
152 struct sockaddr_storage
153 {
154 	union
155 	{
156 		struct sockaddr sa;		/* get the system-dependent fields */
157 		long int	ss_align;	/* ensures struct is properly aligned.
158 								 * original uses int64 */
159 		char		ss_pad[128];	/* ensures struct has desired size */
160 	}
161 				ss_stuff;
162 };
163 
164 #define ss_family   ss_stuff.sa.sa_family
165 /* It should have an ss_len field if sockaddr has sa_len. */
166 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
167 #define ss_len      ss_stuff.sa.sa_len
168 #define HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN 1
169 #endif
170 #endif							/* HAVE_STRUCT_SOCKADDR_STORAGE */
171 
172 typedef struct
173 {
174 	struct sockaddr_storage addr;
175 
176 	/*
177 	 * ACCEPT_TYPE_ARG3 - Third argument type of accept(). It is defined in
178 	 * ac_func_accept_argtypes.m4
179 	 */
180 	ACCEPT_TYPE_ARG3 salen;
181 }
182 SockAddr;
183 
184 
185 #define AUTH_REQ_OK         0	/* User is authenticated  */
186 #define AUTH_REQ_KRB4       1	/* Kerberos V4. Not supported any more. */
187 #define AUTH_REQ_KRB5       2	/* Kerberos V5. Not supported any more. */
188 #define AUTH_REQ_PASSWORD   3	/* Password */
189 #define AUTH_REQ_CRYPT      4	/* crypt password. Not supported any more. */
190 #define AUTH_REQ_MD5        5	/* md5 password */
191 #define AUTH_REQ_SCM_CREDS  6	/* transfer SCM credentials */
192 #define AUTH_REQ_GSS        7	/* GSSAPI without wrap() */
193 #define AUTH_REQ_GSS_CONT   8	/* Continue GSS exchanges */
194 #define AUTH_REQ_SSPI       9	/* SSPI negotiate without wrap() */
195 #define AUTH_REQ_SASL      10	/* Begin SASL authentication */
196 #define AUTH_REQ_SASL_CONT 11	/* Continue SASL authentication */
197 #define AUTH_REQ_SASL_FIN  12	/* Final SASL message */
198 
199 
200 typedef unsigned int AuthRequest;
201 
202 #ifdef __GNUC__
203 #define PG_USE_INLINE
204 #endif
205 
206 /* no special DLL markers on most ports */
207 #ifndef PGDLLIMPORT
208 #define PGDLLIMPORT
209 #endif
210 #ifndef PGDLLEXPORT
211 #define PGDLLEXPORT
212 #endif
213 
214 #ifdef PG_USE_INLINE
215 #define STATIC_IF_INLINE static inline
216 #else
217 #define STATIC_IF_INLINE
218 #endif							/* PG_USE_INLINE */
219 
220 
221 typedef uint8 bits8;			/* >= 8 bits */
222 typedef uint16 bits16;			/* >= 16 bits */
223 typedef uint32 bits32;			/* >= 32 bits */
224 
225 /*
226  * stdint.h limits aren't guaranteed to be present and aren't guaranteed to
227  * have compatible types with our fixed width types. So just define our own.
228  */
229 #define PG_INT8_MIN		(-0x7F-1)
230 #define PG_INT8_MAX		(0x7F)
231 #define PG_UINT8_MAX	(0xFF)
232 #define PG_INT16_MIN	(-0x7FFF-1)
233 #define PG_INT16_MAX	(0x7FFF)
234 #define PG_UINT16_MAX	(0xFFFF)
235 #define PG_INT32_MIN	(-0x7FFFFFFF-1)
236 #define PG_INT32_MAX	(0x7FFFFFFF)
237 #define PG_UINT32_MAX	(0xFFFFFFFF)
238 #define PG_INT64_MIN	(-INT64CONST(0x7FFFFFFFFFFFFFFF) - 1)
239 #define PG_INT64_MAX	INT64CONST(0x7FFFFFFFFFFFFFFF)
240 #define PG_UINT64_MAX	UINT64CONST(0xFFFFFFFFFFFFFFFF)
241 
242 
243 typedef size_t Size;
244 typedef unsigned long Datum;	/* XXX sizeof(long) >= sizeof(void *) */
245 
246 typedef void (*pg_on_exit_callback) (int code, Datum arg);
247 
248 /*
249  * NULL
250   *		Null pointer.
251    */
252 #ifndef NULL
253 #define NULL	((void *) 0)
254 #endif
255 
256 /* ----------------------------------------------------------------
257  *				Section 6:	assertions
258  * ----------------------------------------------------------------
259  */
260 
261 /*
262  * USE_ASSERT_CHECKING, if defined, turns on all the assertions.
263  * - plai  9/5/90
264  *
265  * It should _NOT_ be defined in releases or in benchmark copies
266  */
267 
268 /*
269  * Assert() can be used in both frontend and backend code. In frontend code it
270  * just calls the standard assert, if it's available. If use of assertions is
271  * not configured, it does nothing.
272  */
273 #ifndef USE_ASSERT_CHECKING
274 
275 #define Assert(condition)
276 #define AssertMacro(condition)	((void)true)
277 #define AssertArg(condition)
278 #define AssertState(condition)
279 #define Trap(condition, errorType)
280 #define TrapMacro(condition, errorType)	(true)
281 
282 #elif defined(FRONTEND)
283 #include <assert.h>
284 #define Assert(p) assert(p)
285 #define AssertMacro(p)	((void) assert(p))
286 #define AssertArg(condition) assert(condition)
287 #define AssertState(condition) assert(condition)
288 #else							/* USE_ASSERT_CHECKING && !FRONTEND */
289 
290 /*
291  * Trap
292  *		Generates an exception if the given condition is true.
293  */
294 #define Trap(condition, errorType) \
295 	do { \
296 		if ((assert_enabled) && (condition)) \
297 		ExceptionalCondition(CppAsString(condition), (errorType), \
298 				__FILE__, __LINE__); \
299 	} while (0)
300 
301 /*
302  *	TrapMacro is the same as Trap but it's intended for use in macros:
303  *
304  *		#define foo(x) (AssertMacro(x != 0), bar(x))
305  *
306  *	Isn't CPP fun?
307  */
308 #define TrapMacro(condition, errorType) \
309 	((bool) ((! assert_enabled) || ! (condition) || \
310 		(ExceptionalCondition(CppAsString(condition), (errorType), \
311 							  __FILE__, __LINE__), 0)))
312 
313 #define Assert(condition) \
314 	Trap(!(condition), "FailedAssertion")
315 
316 #define AssertMacro(condition) \
317 	((void) TrapMacro(!(condition), "FailedAssertion"))
318 
319 #define AssertArg(condition) \
320 	Trap(!(condition), "BadArgument")
321 
322 #define AssertState(condition) \
323 	Trap(!(condition), "BadState")
324 #endif							/* USE_ASSERT_CHECKING && !FRONTEND */
325 
326 
327 /*
328  * Macros to support compile-time assertion checks.
329  *
330  * If the "condition" (a compile-time-constant expression) evaluates to false,
331  * throw a compile error using the "errmessage" (a string literal).
332  *
333  * gcc 4.6 and up supports _Static_assert(), but there are bizarre syntactic
334  * placement restrictions.	These macros make it safe to use as a statement
335  * or in an expression, respectively.
336  *
337  * Otherwise we fall back on a kluge that assumes the compiler will complain
338  * about a negative width for a struct bit-field.  This will not include a
339  * helpful error message, but it beats not getting an error at all.
340  */
341 #ifdef HAVE__STATIC_ASSERT
342 #define StaticAssertStmt(condition, errmessage) \
343 	do { _Static_assert(condition, errmessage); } while(0)
344 #define StaticAssertExpr(condition, errmessage) \
345 	({ StaticAssertStmt(condition, errmessage); true; })
346 #else							/* !HAVE__STATIC_ASSERT */
347 #define StaticAssertStmt(condition, errmessage) \
348 	((void) sizeof(struct { int static_assert_failure : (condition) ? 1 : -1; }))
349 #define StaticAssertExpr(condition, errmessage) \
350 	StaticAssertStmt(condition, errmessage)
351 #endif							/* HAVE__STATIC_ASSERT */
352 
353 
354 /*
355  * Compile-time checks that a variable (or expression) has the specified type.
356  *
357  * AssertVariableIsOfType() can be used as a statement.
358  * AssertVariableIsOfTypeMacro() is intended for use in macros, eg
359  *		#define foo(x) (AssertVariableIsOfTypeMacro(x, int), bar(x))
360  *
361  * If we don't have __builtin_types_compatible_p, we can still assert that
362  * the types have the same size.  This is far from ideal (especially on 32-bit
363  * platforms) but it provides at least some coverage.
364  */
365 #ifdef HAVE__BUILTIN_TYPES_COMPATIBLE_P
366 #define AssertVariableIsOfType(varname, typename) \
367 	StaticAssertStmt(__builtin_types_compatible_p(__typeof__(varname), typename), \
368 			CppAsString(varname) " does not have type " CppAsString(typename))
369 #define AssertVariableIsOfTypeMacro(varname, typename) \
370 	((void) StaticAssertExpr(__builtin_types_compatible_p(__typeof__(varname), typename), \
371 		CppAsString(varname) " does not have type " CppAsString(typename)))
372 #else							/* !HAVE__BUILTIN_TYPES_COMPATIBLE_P */
373 #define AssertVariableIsOfType(varname, typename) \
374 	StaticAssertStmt(sizeof(varname) == sizeof(typename), \
375 			CppAsString(varname) " does not have type " CppAsString(typename))
376 #define AssertVariableIsOfTypeMacro(varname, typename) \
377 																((void) StaticAssertExpr(sizeof(varname) == sizeof(typename),		\
378 																	 CppAsString(varname) " does not have type " CppAsString(typename)))
379 #endif							/* HAVE__BUILTIN_TYPES_COMPATIBLE_P */
380 /*
381  * StrNCpy
382  *	Like standard library function strncpy(), except that result string
383  *	is guaranteed to be null-terminated --- that is, at most N-1 bytes
384  *	of the source string will be kept.
385  *	Also, the macro returns no result (too hard to do that without
386  *	evaluating the arguments multiple times, which seems worse).
387  *
388  *	BTW: when you need to copy a non-null-terminated string (like a text
389  *	datum) and add a null, do not do it with StrNCpy(..., len+1).  That
390  *	might seem to work, but it fetches one byte more than there is in the
391  *	text object.  One fine day you'll have a SIGSEGV because there isn't
392  *	another byte before the end of memory.	Don't laugh, we've had real
393  *	live bug reports from real live users over exactly this mistake.
394  *	Do it honestly with "memcpy(dst,src,len); dst[len] = '\0';", instead.
395  */
396 #define StrNCpy(dst,src,len) \
397 	do \
398 	{ \
399 		char * _dst = (dst); \
400 		Size _len = (len); \
401 \
402 		if (_len > 0) \
403 		{ \
404 			strncpy(_dst, (src), _len); \
405 			_dst[_len-1] = '\0'; \
406 		} \
407 	} while (0)
408 
409 
410 /* Get a bit mask of the bits set in non-long aligned addresses */
411 #define LONG_ALIGN_MASK (sizeof(long) - 1)
412 #define MEMSET_LOOP_LIMIT 1024
413 
414 /*
415  * MemSet
416  *	Exactly the same as standard library function memset(), but considerably
417  *	faster for zeroing small word-aligned structures (such as parsetree nodes).
418  *	This has to be a macro because the main point is to avoid function-call
419  *	overhead.	However, we have also found that the loop is faster than
420  *	native libc memset() on some platforms, even those with assembler
421  *	memset() functions.  More research needs to be done, perhaps with
422  *	MEMSET_LOOP_LIMIT tests in configure.
423  */
424 #define MemSet(start, val, len) \
425 	do \
426 	{ \
427 		/* must be void* because we don't know if it is integer aligned yet */ \
428 		void   *_vstart = (void *) (start); \
429 		int		_val = (val); \
430 		Size	_len = (len); \
431 \
432 		if ((((intptr_t) _vstart) & LONG_ALIGN_MASK) == 0 && \
433 			(_len & LONG_ALIGN_MASK) == 0 && \
434 			_val == 0 && \
435 			_len <= MEMSET_LOOP_LIMIT && \
436 			/* \
437 			 *	If MEMSET_LOOP_LIMIT == 0, optimizer should find \
438 			 *	the whole "if" false at compile time. \
439 			 */ \
440 			MEMSET_LOOP_LIMIT != 0) \
441 		{ \
442 			long *_start = (long *) _vstart; \
443 			long *_stop = (long *) ((char *) _start + _len); \
444 			while (_start < _stop) \
445 				*_start++ = 0; \
446 		} \
447 		else \
448 			memset(_vstart, _val, _len); \
449 	} while (0)
450 
451 /*
452  * MemSetAligned is the same as MemSet except it omits the test to see if
453  * "start" is word-aligned.  This is okay to use if the caller knows a-priori
454  * that the pointer is suitably aligned (typically, because he just got it
455  * from palloc(), which always delivers a max-aligned pointer).
456  */
457 #define MemSetAligned(start, val, len) \
458 	do \
459 	{ \
460 		long   *_start = (long *) (start); \
461 		int		_val = (val); \
462 		Size	_len = (len); \
463 \
464 		if ((_len & LONG_ALIGN_MASK) == 0 && \
465 			_val == 0 && \
466 			_len <= MEMSET_LOOP_LIMIT && \
467 			MEMSET_LOOP_LIMIT != 0) \
468 		{ \
469 			long *_stop = (long *) ((char *) _start + _len); \
470 			while (_start < _stop) \
471 				*_start++ = 0; \
472 		} \
473 		else \
474 			memset(_start, _val, _len); \
475 	} while (0)
476 
477 
478 /*
479  * MemSetTest/MemSetLoop are a variant version that allow all the tests in
480  * MemSet to be done at compile time in cases where "val" and "len" are
481  * constants *and* we know the "start" pointer must be word-aligned.
482  * If MemSetTest succeeds, then it is okay to use MemSetLoop, otherwise use
483  * MemSetAligned.  Beware of multiple evaluations of the arguments when using
484  * this approach.
485  */
486 #define MemSetTest(val, len) \
487 	( ((len) & LONG_ALIGN_MASK) == 0 && \
488 	(len) <= MEMSET_LOOP_LIMIT && \
489 	MEMSET_LOOP_LIMIT != 0 && \
490 	(val) == 0 )
491 
492 #define MemSetLoop(start, val, len) \
493 	do \
494 	{ \
495 		long * _start = (long *) (start); \
496 		long * _stop = (long *) ((char *) _start + (Size) (len)); \
497 	\
498 		while (_start < _stop) \
499 			*_start++ = 0; \
500 	} while (0)
501 
502 
503 #endif							/* POOL_TYPE_H */
504