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