1 /* -*- mode: c; indent-tabs-mode: nil -*- */ 2 /* include/k5-platform.h */ 3 /* 4 * Copyright 2003, 2004, 2005, 2007, 2008, 2009 Massachusetts Institute of Technology. 5 * All Rights Reserved. 6 * 7 * Export of this software from the United States of America may 8 * require a specific license from the United States Government. 9 * It is the responsibility of any person or organization contemplating 10 * export to obtain such a license before exporting. 11 * 12 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 13 * distribute this software and its documentation for any purpose and 14 * without fee is hereby granted, provided that the above copyright 15 * notice appear in all copies and that both that copyright notice and 16 * this permission notice appear in supporting documentation, and that 17 * the name of M.I.T. not be used in advertising or publicity pertaining 18 * to distribution of the software without specific, written prior 19 * permission. Furthermore if you modify this software you must label 20 * your software as modified software and not distribute it in such a 21 * fashion that it might be confused with the original M.I.T. software. 22 * M.I.T. makes no representations about the suitability of 23 * this software for any purpose. It is provided "as is" without express 24 * or implied warranty. 25 */ 26 27 /* 28 * Some platform-dependent definitions to sync up the C support level. 29 * Some to a C99-ish level, some related utility code. 30 * 31 * Currently: 32 * + [u]int{8,16,32}_t types 33 * + 64-bit types and load/store code 34 * + SIZE_MAX 35 * + shared library init/fini hooks 36 * + consistent getpwnam/getpwuid interfaces 37 * + va_copy fudged if not provided 38 * + strlcpy/strlcat 39 * + fnmatch 40 * + [v]asprintf 41 * + strerror_r 42 * + mkstemp 43 * + zap (support function and macro) 44 * + constant time memory comparison 45 * + path manipulation 46 * + _, N_, dgettext, bindtextdomain (for localization) 47 * + getopt_long 48 * + secure_getenv 49 * + fetching filenames from a directory 50 */ 51 52 #ifndef K5_PLATFORM_H 53 #define K5_PLATFORM_H 54 55 #include "autoconf.h" 56 #include <assert.h> 57 #include <string.h> 58 #include <stdarg.h> 59 #include <stdint.h> 60 #include <limits.h> 61 #include <stdlib.h> 62 #include <stdio.h> 63 #include <fcntl.h> 64 #include <errno.h> 65 #ifdef HAVE_FNMATCH_H 66 #include <fnmatch.h> 67 #endif 68 69 #ifdef HAVE_UNISTD_H 70 #include <unistd.h> 71 #endif 72 73 #ifdef __cplusplus 74 extern "C" { 75 #endif 76 77 #ifdef _WIN32 78 #define CAN_COPY_VA_LIST 79 #endif 80 81 /* This attribute prevents unused function warnings in gcc and clang. */ 82 #ifdef __GNUC__ 83 #define UNUSED __attribute__((__unused__)) 84 #else 85 #define UNUSED 86 #endif 87 88 #if defined(macintosh) || (defined(__MACH__) && defined(__APPLE__)) 89 #include <TargetConditionals.h> 90 #endif 91 92 /* Initialization and finalization function support for libraries. 93 94 At top level, before the functions are defined or even declared: 95 MAKE_INIT_FUNCTION(init_fn); 96 MAKE_FINI_FUNCTION(fini_fn); 97 Then: 98 int init_fn(void) { ... } 99 void fini_fn(void) { if (INITIALIZER_RAN(init_fn)) ... } 100 In code, in the same file: 101 err = CALL_INIT_FUNCTION(init_fn); 102 103 To trigger or verify the initializer invocation from another file, 104 a helper function must be created. 105 106 This model handles both the load-time execution (Windows) and 107 delayed execution (pthread_once) approaches, and should be able to 108 guarantee in both cases that the init function is run once, in one 109 thread, before other stuff in the library is done; furthermore, the 110 finalization code should only run if the initialization code did. 111 (Maybe I could've made the "if INITIALIZER_RAN" test implicit, via 112 another function hidden in macros, but this is hairy enough 113 already.) 114 115 The init_fn and fini_fn names should be chosen such that any 116 exported names staring with those names, and optionally followed by 117 additional characters, fits in with any namespace constraints on 118 the library in question. 119 120 121 There's also PROGRAM_EXITING() currently always defined as zero. 122 If there's some trivial way to find out if the fini function is 123 being called because the program that the library is linked into is 124 exiting, we can just skip all the work because the resources are 125 about to be freed up anyways. Generally this is likely to be the 126 same as distinguishing whether the library was loaded dynamically 127 while the program was running, or loaded as part of program 128 startup. On most platforms, I don't think we can distinguish these 129 cases easily, and it's probably not worth expending any significant 130 effort. (Note in particular that atexit() won't do, because if the 131 library is explicitly loaded and unloaded, it would have to be able 132 to deregister the atexit callback function. Also, the system limit 133 on atexit callbacks may be small.) 134 135 136 Implementation outline: 137 138 Windows: MAKE_FINI_FUNCTION creates a symbol with a magic name that 139 is sought at library build time, and code is added to invoke the 140 function when the library is unloaded. MAKE_INIT_FUNCTION does 141 likewise, but the function is invoked when the library is loaded, 142 and an extra variable is declared to hold an error code and a "yes 143 the initializer ran" flag. CALL_INIT_FUNCTION blows up if the flag 144 isn't set, otherwise returns the error code. 145 146 UNIX: MAKE_INIT_FUNCTION creates and initializes a variable with a 147 name derived from the function name, containing a k5_once_t 148 (pthread_once_t or int), an error code, and a pointer to the 149 function. The function itself is declared static, but the 150 associated variable has external linkage. CALL_INIT_FUNCTION 151 ensures thath the function is called exactly once (pthread_once or 152 just check the flag) and returns the stored error code (or the 153 pthread_once error). 154 155 (That's the basic idea. With some debugging assert() calls and 156 such, it's a bit more complicated. And we also need to handle 157 doing the pthread test at run time on systems where that works, so 158 we use the k5_once_t stuff instead.) 159 160 UNIX, with library unloading prevented or when building static 161 libraries: we don't need to run finalizers. 162 163 UNIX, with compiler support: MAKE_FINI_FUNCTION declares the 164 function as a destructor, and the run time linker support or 165 whatever will cause it to be invoked when the library is unloaded, 166 the program ends, etc. 167 168 UNIX, with linker support: MAKE_FINI_FUNCTION creates a symbol with 169 a magic name that is sought at library build time, and linker 170 options are used to mark it as a finalization function for the 171 library. The symbol must be exported. 172 173 UNIX, no library finalization support: The finalization function 174 never runs, and we leak memory. Tough. 175 176 DELAY_INITIALIZER will be defined by the configure script if we 177 want to use k5_once instead of load-time initialization. That'll 178 be the preferred method on most systems except Windows, where we 179 have to initialize some mutexes. 180 181 182 183 184 For maximum flexibility in defining the macros, the function name 185 parameter should be a simple name, not even a macro defined as 186 another name. The function should have a unique name, and should 187 conform to whatever namespace is used by the library in question. 188 (We do have export lists, but (1) they're not used for all 189 platforms, and (2) they're not used for static libraries.) 190 191 If the macro expansion needs the function to have been declared, it 192 must include a declaration. If it is not necessary for the symbol 193 name to be exported from the object file, the macro should declare 194 it as "static". Hence the signature must exactly match "void 195 foo(void)". (ANSI C allows a static declaration followed by a 196 non-static one; the result is internal linkage.) The macro 197 expansion has to come before the function, because gcc apparently 198 won't act on "__attribute__((constructor))" if it comes after the 199 function definition. 200 201 This is going to be compiler- and environment-specific, and may 202 require some support at library build time, and/or "asm" 203 statements. But through macro expansion and auxiliary functions, 204 we should be able to handle most things except #pragma. 205 206 It's okay for this code to require that the library be built 207 with the same compiler and compiler options throughout, but 208 we shouldn't require that the library and application use the 209 same compiler. 210 211 For static libraries, we don't really care about cleanup too much, 212 since it's all memory handling and mutex allocation which will all 213 be cleaned up when the program exits. Thus, it's okay if gcc-built 214 static libraries don't play nicely with cc-built executables when 215 it comes to static constructors, just as long as it doesn't cause 216 linking to fail. 217 218 For dynamic libraries on UNIX, we'll use pthread_once-type support 219 to do delayed initialization, so if finalization can't be made to 220 work, we'll only have memory leaks in a load/use/unload cycle. If 221 anyone (like, say, the OS vendor) complains about this, they can 222 tell us how to get a shared library finalization function invoked 223 automatically. 224 225 Currently there's --disable-delayed-initialization for preventing 226 the initialization from being delayed on UNIX, but that's mainly 227 just for testing the linker options for initialization, and will 228 probably be removed at some point. */ 229 230 /* Helper macros. */ 231 232 # define JOIN__2_2(A,B) A ## _ ## _ ## B 233 # define JOIN__2(A,B) JOIN__2_2(A,B) 234 235 /* XXX Should test USE_LINKER_INIT_OPTION early, and if it's set, 236 always provide a function by the expected name, even if we're 237 delaying initialization. */ 238 239 #if defined(DELAY_INITIALIZER) 240 241 /* Run the initialization code during program execution, at the latest 242 possible moment. This means multiple threads may be active. */ 243 # include "k5-thread.h" 244 typedef struct { k5_once_t once; int error, did_run; void (*fn)(void); } k5_init_t; 245 # ifdef USE_LINKER_INIT_OPTION 246 # define MAYBE_DUMMY_INIT(NAME) \ 247 void JOIN__2(NAME, auxinit) () { } 248 # else 249 # define MAYBE_DUMMY_INIT(NAME) 250 # endif 251 # ifdef __GNUC__ 252 /* Do it in macro form so we get the file/line of the invocation if 253 the assertion fails. */ 254 # define k5_call_init_function(I) \ 255 (__extension__ ({ \ 256 k5_init_t *k5int_i = (I); \ 257 int k5int_err = k5_once(&k5int_i->once, k5int_i->fn); \ 258 (k5int_err \ 259 ? k5int_err \ 260 : (assert(k5int_i->did_run != 0), k5int_i->error)); \ 261 })) 262 # define MAYBE_DEFINE_CALLINIT_FUNCTION 263 # else 264 # define MAYBE_DEFINE_CALLINIT_FUNCTION \ 265 static inline int k5_call_init_function(k5_init_t *i) \ 266 { \ 267 int err; \ 268 err = k5_once(&i->once, i->fn); \ 269 if (err) \ 270 return err; \ 271 assert (i->did_run != 0); \ 272 return i->error; \ 273 } 274 # endif 275 # define MAKE_INIT_FUNCTION(NAME) \ 276 static int NAME(void); \ 277 MAYBE_DUMMY_INIT(NAME) \ 278 /* forward declaration for use in initializer */ \ 279 static void JOIN__2(NAME, aux) (void); \ 280 static k5_init_t JOIN__2(NAME, once) = \ 281 { K5_ONCE_INIT, 0, 0, JOIN__2(NAME, aux) }; \ 282 MAYBE_DEFINE_CALLINIT_FUNCTION \ 283 static void JOIN__2(NAME, aux) (void) \ 284 { \ 285 JOIN__2(NAME, once).did_run = 1; \ 286 JOIN__2(NAME, once).error = NAME(); \ 287 } \ 288 /* so ';' following macro use won't get error */ \ 289 static int NAME(void) 290 # define CALL_INIT_FUNCTION(NAME) \ 291 k5_call_init_function(& JOIN__2(NAME, once)) 292 /* This should be called in finalization only, so we shouldn't have 293 multiple active threads mucking around in our library at this 294 point. So ignore the once_t object and just look at the flag. 295 296 XXX Could we have problems with memory coherence between processors 297 if we don't invoke mutex/once routines? Probably not, the 298 application code should already be coordinating things such that 299 the library code is not in use by this point, and memory 300 synchronization will be needed there. */ 301 # define INITIALIZER_RAN(NAME) \ 302 (JOIN__2(NAME, once).did_run && JOIN__2(NAME, once).error == 0) 303 304 # define PROGRAM_EXITING() (0) 305 306 #elif defined(__GNUC__) && !defined(_WIN32) && defined(CONSTRUCTOR_ATTR_WORKS) 307 308 /* Run initializer at load time, via GCC/C++ hook magic. */ 309 310 # ifdef USE_LINKER_INIT_OPTION 311 /* Both gcc and linker option?? Favor gcc. */ 312 # define MAYBE_DUMMY_INIT(NAME) \ 313 void JOIN__2(NAME, auxinit) () { } 314 # else 315 # define MAYBE_DUMMY_INIT(NAME) 316 # endif 317 318 typedef struct { int error; unsigned char did_run; } k5_init_t; 319 # define MAKE_INIT_FUNCTION(NAME) \ 320 MAYBE_DUMMY_INIT(NAME) \ 321 static k5_init_t JOIN__2(NAME, ran) \ 322 = { 0, 2 }; \ 323 static void JOIN__2(NAME, aux)(void) \ 324 __attribute__((constructor)); \ 325 static int NAME(void); \ 326 static void JOIN__2(NAME, aux)(void) \ 327 { \ 328 JOIN__2(NAME, ran).error = NAME(); \ 329 JOIN__2(NAME, ran).did_run = 3; \ 330 } \ 331 static int NAME(void) 332 # define CALL_INIT_FUNCTION(NAME) \ 333 (JOIN__2(NAME, ran).did_run == 3 \ 334 ? JOIN__2(NAME, ran).error \ 335 : (abort(),0)) 336 # define INITIALIZER_RAN(NAME) (JOIN__2(NAME,ran).did_run == 3 && JOIN__2(NAME, ran).error == 0) 337 338 # define PROGRAM_EXITING() (0) 339 340 #elif defined(USE_LINKER_INIT_OPTION) || defined(_WIN32) 341 342 /* Run initializer at load time, via linker magic, or in the 343 case of WIN32, win_glue.c hard-coded knowledge. */ 344 typedef struct { int error; unsigned char did_run; } k5_init_t; 345 # define MAKE_INIT_FUNCTION(NAME) \ 346 static k5_init_t JOIN__2(NAME, ran) \ 347 = { 0, 2 }; \ 348 static int NAME(void); \ 349 void JOIN__2(NAME, auxinit)() \ 350 { \ 351 JOIN__2(NAME, ran).error = NAME(); \ 352 JOIN__2(NAME, ran).did_run = 3; \ 353 } \ 354 static int NAME(void) 355 # define CALL_INIT_FUNCTION(NAME) \ 356 (JOIN__2(NAME, ran).did_run == 3 \ 357 ? JOIN__2(NAME, ran).error \ 358 : (abort(),0)) 359 # define INITIALIZER_RAN(NAME) \ 360 (JOIN__2(NAME, ran).error == 0) 361 362 # define PROGRAM_EXITING() (0) 363 364 #else 365 366 # error "Don't know how to do load-time initializers for this configuration." 367 368 # define PROGRAM_EXITING() (0) 369 370 #endif 371 372 373 374 #if defined(USE_LINKER_FINI_OPTION) || defined(_WIN32) 375 /* If we're told the linker option will be used, it doesn't really 376 matter what compiler we're using. Do it the same way 377 regardless. */ 378 379 # ifdef __hpux 380 381 /* On HP-UX, we need this auxiliary function. At dynamic load or 382 unload time (but *not* program startup and termination for 383 link-time specified libraries), the linker-indicated function 384 is called with a handle on the library and a flag indicating 385 whether it's being loaded or unloaded. 386 387 The "real" fini function doesn't need to be exported, so 388 declare it static. 389 390 As usual, the final declaration is just for syntactic 391 convenience, so the top-level invocation of this macro can be 392 followed by a semicolon. */ 393 394 # include <dl.h> 395 # define MAKE_FINI_FUNCTION(NAME) \ 396 static void NAME(void); \ 397 void JOIN__2(NAME, auxfini)(shl_t, int); /* silence gcc warnings */ \ 398 void JOIN__2(NAME, auxfini)(shl_t h, int l) { if (!l) NAME(); } \ 399 static void NAME(void) 400 401 # else /* not hpux */ 402 403 # define MAKE_FINI_FUNCTION(NAME) \ 404 void NAME(void) 405 406 # endif 407 408 #elif !defined(SHARED) || defined(LIB_UNLOAD_PREVENTED) 409 410 /* 411 * In this case, we just don't care about finalization. The code will still 412 * define the function, but we won't do anything with it. 413 */ 414 # define MAKE_FINI_FUNCTION(NAME) \ 415 static void NAME(void) UNUSED 416 417 #elif defined(__GNUC__) && defined(DESTRUCTOR_ATTR_WORKS) 418 /* If we're using gcc, if the C++ support works, the compiler should 419 build executables and shared libraries that support the use of 420 static constructors and destructors. The C compiler supports a 421 function attribute that makes use of the same facility as C++. 422 423 XXX How do we know if the C++ support actually works? */ 424 # define MAKE_FINI_FUNCTION(NAME) \ 425 static void NAME(void) __attribute__((destructor)) 426 427 #else 428 429 # error "Don't know how to do unload-time finalization for this configuration." 430 431 #endif 432 433 #ifndef SIZE_MAX 434 # define SIZE_MAX ((size_t)((size_t)0 - 1)) 435 #endif 436 437 #ifdef _WIN32 438 # define SSIZE_MAX ((ssize_t)(SIZE_MAX/2)) 439 #endif 440 441 /* Read and write integer values as (unaligned) octet strings in 442 specific byte orders. Add per-platform optimizations as 443 needed. */ 444 445 #if HAVE_ENDIAN_H 446 # include <endian.h> 447 #elif HAVE_MACHINE_ENDIAN_H 448 # include <machine/endian.h> 449 #endif 450 /* Check for BIG/LITTLE_ENDIAN macros. If exactly one is defined, use 451 it. If both are defined, then BYTE_ORDER should be defined and 452 match one of them. Try those symbols, then try again with an 453 underscore prefix. */ 454 #if defined(BIG_ENDIAN) && defined(LITTLE_ENDIAN) 455 # if BYTE_ORDER == BIG_ENDIAN 456 # define K5_BE 457 # endif 458 # if BYTE_ORDER == LITTLE_ENDIAN 459 # define K5_LE 460 # endif 461 #elif defined(BIG_ENDIAN) 462 # define K5_BE 463 #elif defined(LITTLE_ENDIAN) 464 # define K5_LE 465 #elif defined(_BIG_ENDIAN) && defined(_LITTLE_ENDIAN) 466 # if _BYTE_ORDER == _BIG_ENDIAN 467 # define K5_BE 468 # endif 469 # if _BYTE_ORDER == _LITTLE_ENDIAN 470 # define K5_LE 471 # endif 472 #elif defined(_BIG_ENDIAN) 473 # define K5_BE 474 #elif defined(_LITTLE_ENDIAN) 475 # define K5_LE 476 #elif defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__) 477 # define K5_BE 478 #elif defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__) 479 # define K5_LE 480 #endif 481 #if !defined(K5_BE) && !defined(K5_LE) 482 /* Look for some architectures we know about. 483 484 MIPS can use either byte order, but the preprocessor tells us which 485 mode we're compiling for. The GCC config files indicate that 486 variants of Alpha and IA64 might be out there with both byte 487 orders, but until we encounter the "wrong" ones in the real world, 488 just go with the default (unless there are cpp predefines to help 489 us there too). 490 491 As far as I know, only PDP11 and ARM (which we don't handle here) 492 have strange byte orders where an 8-byte value isn't laid out as 493 either 12345678 or 87654321. */ 494 # if defined(__i386__) || defined(_MIPSEL) || defined(__alpha__) || (defined(__ia64__) && !defined(__hpux)) 495 # define K5_LE 496 # endif 497 # if defined(__hppa__) || defined(__rs6000__) || defined(__sparc__) || defined(_MIPSEB) || defined(__m68k__) || defined(__sparc64__) || defined(__ppc__) || defined(__ppc64__) || (defined(__hpux) && defined(__ia64__)) 498 # define K5_BE 499 # endif 500 #endif 501 #if defined(K5_BE) && defined(K5_LE) 502 # error "oops, check the byte order macros" 503 #endif 504 505 /* Optimize for GCC on platforms with known byte orders. 506 507 GCC's packed structures can be written to with any alignment; the 508 compiler will use byte operations, unaligned-word operations, or 509 normal memory ops as appropriate for the architecture. 510 511 This assumes the availability of uint##_t types, which should work 512 on most of our platforms except Windows, where we're not using 513 GCC. */ 514 #ifdef __GNUC__ 515 # define PUT(SIZE,PTR,VAL) (((struct { uint##SIZE##_t i; } __attribute__((packed)) *)(PTR))->i = (VAL)) 516 # define GET(SIZE,PTR) (((const struct { uint##SIZE##_t i; } __attribute__((packed)) *)(PTR))->i) 517 # define PUTSWAPPED(SIZE,PTR,VAL) PUT(SIZE,PTR,SWAP##SIZE(VAL)) 518 # define GETSWAPPED(SIZE,PTR) SWAP##SIZE(GET(SIZE,PTR)) 519 #endif 520 /* To do: Define SWAP16, SWAP32, SWAP64 macros to byte-swap values 521 with the indicated numbers of bits. 522 523 Linux: byteswap.h, bswap_16 etc. 524 Solaris 10: none 525 macOS: machine/endian.h or byte_order.h, NXSwap{Short,Int,LongLong} 526 NetBSD: sys/bswap.h, bswap16 etc. */ 527 528 #if defined(HAVE_BYTESWAP_H) && defined(HAVE_BSWAP_16) 529 # include <byteswap.h> 530 # define SWAP16 bswap_16 531 # define SWAP32 bswap_32 532 # ifdef HAVE_BSWAP_64 533 # define SWAP64 bswap_64 534 # endif 535 #elif TARGET_OS_MAC 536 # include <architecture/byte_order.h> 537 # define SWAP16 k5_swap16 538 static inline unsigned int k5_swap16 (unsigned int x) { 539 x &= 0xffff; 540 return (x >> 8) | ((x & 0xff) << 8); 541 } 542 # define SWAP32 OSSwapInt32 543 # define SWAP64 OSSwapInt64 544 #elif defined(HAVE_SYS_BSWAP_H) 545 /* XXX NetBSD/x86 5.0.1 defines bswap16 and bswap32 as inline 546 functions only, so autoconf doesn't pick up on their existence. 547 So, no feature macro test for them here. The 64-bit version isn't 548 inline at all, though, for whatever reason. */ 549 # include <sys/bswap.h> 550 # define SWAP16 bswap16 551 # define SWAP32 bswap32 552 /* However, bswap64 causes lots of warnings about 'long long' 553 constants; probably only on 32-bit platforms. */ 554 # if LONG_MAX > 0x7fffffffL 555 # define SWAP64 bswap64 556 # endif 557 #endif 558 559 /* Note that on Windows at least this file can be included from C++ 560 source, so casts *from* void* are required. */ 561 static inline void 562 store_16_be (unsigned int val, void *vp) 563 { 564 unsigned char *p = (unsigned char *) vp; 565 #if defined(__GNUC__) && defined(K5_BE) && !defined(__cplusplus) 566 PUT(16,p,val); 567 #elif defined(__GNUC__) && defined(K5_LE) && defined(SWAP16) && !defined(__cplusplus) 568 PUTSWAPPED(16,p,val); 569 #else 570 p[0] = (val >> 8) & 0xff; 571 p[1] = (val ) & 0xff; 572 #endif 573 } 574 static inline void 575 store_32_be (unsigned int val, void *vp) 576 { 577 unsigned char *p = (unsigned char *) vp; 578 #if defined(__GNUC__) && defined(K5_BE) && !defined(__cplusplus) 579 PUT(32,p,val); 580 #elif defined(__GNUC__) && defined(K5_LE) && defined(SWAP32) && !defined(__cplusplus) 581 PUTSWAPPED(32,p,val); 582 #else 583 p[0] = (val >> 24) & 0xff; 584 p[1] = (val >> 16) & 0xff; 585 p[2] = (val >> 8) & 0xff; 586 p[3] = (val ) & 0xff; 587 #endif 588 } 589 static inline void 590 store_64_be (uint64_t val, void *vp) 591 { 592 unsigned char *p = (unsigned char *) vp; 593 #if defined(__GNUC__) && defined(K5_BE) && !defined(__cplusplus) 594 PUT(64,p,val); 595 #elif defined(__GNUC__) && defined(K5_LE) && defined(SWAP64) && !defined(__cplusplus) 596 PUTSWAPPED(64,p,val); 597 #else 598 p[0] = (unsigned char)((val >> 56) & 0xff); 599 p[1] = (unsigned char)((val >> 48) & 0xff); 600 p[2] = (unsigned char)((val >> 40) & 0xff); 601 p[3] = (unsigned char)((val >> 32) & 0xff); 602 p[4] = (unsigned char)((val >> 24) & 0xff); 603 p[5] = (unsigned char)((val >> 16) & 0xff); 604 p[6] = (unsigned char)((val >> 8) & 0xff); 605 p[7] = (unsigned char)((val ) & 0xff); 606 #endif 607 } 608 static inline unsigned short 609 load_16_be (const void *cvp) 610 { 611 const unsigned char *p = (const unsigned char *) cvp; 612 #if defined(__GNUC__) && defined(K5_BE) && !defined(__cplusplus) 613 return GET(16,p); 614 #elif defined(__GNUC__) && defined(K5_LE) && defined(SWAP16) && !defined(__cplusplus) 615 return GETSWAPPED(16,p); 616 #else 617 return (p[1] | (p[0] << 8)); 618 #endif 619 } 620 static inline unsigned int 621 load_32_be (const void *cvp) 622 { 623 const unsigned char *p = (const unsigned char *) cvp; 624 #if defined(__GNUC__) && defined(K5_BE) && !defined(__cplusplus) 625 return GET(32,p); 626 #elif defined(__GNUC__) && defined(K5_LE) && defined(SWAP32) && !defined(__cplusplus) 627 return GETSWAPPED(32,p); 628 #else 629 return (p[3] | (p[2] << 8) 630 | ((uint32_t) p[1] << 16) 631 | ((uint32_t) p[0] << 24)); 632 #endif 633 } 634 static inline uint64_t 635 load_64_be (const void *cvp) 636 { 637 const unsigned char *p = (const unsigned char *) cvp; 638 #if defined(__GNUC__) && defined(K5_BE) && !defined(__cplusplus) 639 return GET(64,p); 640 #elif defined(__GNUC__) && defined(K5_LE) && defined(SWAP64) && !defined(__cplusplus) 641 return GETSWAPPED(64,p); 642 #else 643 return ((uint64_t)load_32_be(p) << 32) | load_32_be(p+4); 644 #endif 645 } 646 static inline void 647 store_16_le (unsigned int val, void *vp) 648 { 649 unsigned char *p = (unsigned char *) vp; 650 #if defined(__GNUC__) && defined(K5_LE) && !defined(__cplusplus) 651 PUT(16,p,val); 652 #elif defined(__GNUC__) && defined(K5_BE) && defined(SWAP16) && !defined(__cplusplus) 653 PUTSWAPPED(16,p,val); 654 #else 655 p[1] = (val >> 8) & 0xff; 656 p[0] = (val ) & 0xff; 657 #endif 658 } 659 static inline void 660 store_32_le (unsigned int val, void *vp) 661 { 662 unsigned char *p = (unsigned char *) vp; 663 #if defined(__GNUC__) && defined(K5_LE) && !defined(__cplusplus) 664 PUT(32,p,val); 665 #elif defined(__GNUC__) && defined(K5_BE) && defined(SWAP32) && !defined(__cplusplus) 666 PUTSWAPPED(32,p,val); 667 #else 668 p[3] = (val >> 24) & 0xff; 669 p[2] = (val >> 16) & 0xff; 670 p[1] = (val >> 8) & 0xff; 671 p[0] = (val ) & 0xff; 672 #endif 673 } 674 static inline void 675 store_64_le (uint64_t val, void *vp) 676 { 677 unsigned char *p = (unsigned char *) vp; 678 #if defined(__GNUC__) && defined(K5_LE) && !defined(__cplusplus) 679 PUT(64,p,val); 680 #elif defined(__GNUC__) && defined(K5_BE) && defined(SWAP64) && !defined(__cplusplus) 681 PUTSWAPPED(64,p,val); 682 #else 683 p[7] = (unsigned char)((val >> 56) & 0xff); 684 p[6] = (unsigned char)((val >> 48) & 0xff); 685 p[5] = (unsigned char)((val >> 40) & 0xff); 686 p[4] = (unsigned char)((val >> 32) & 0xff); 687 p[3] = (unsigned char)((val >> 24) & 0xff); 688 p[2] = (unsigned char)((val >> 16) & 0xff); 689 p[1] = (unsigned char)((val >> 8) & 0xff); 690 p[0] = (unsigned char)((val ) & 0xff); 691 #endif 692 } 693 static inline unsigned short 694 load_16_le (const void *cvp) 695 { 696 const unsigned char *p = (const unsigned char *) cvp; 697 #if defined(__GNUC__) && defined(K5_LE) && !defined(__cplusplus) 698 return GET(16,p); 699 #elif defined(__GNUC__) && defined(K5_BE) && defined(SWAP16) && !defined(__cplusplus) 700 return GETSWAPPED(16,p); 701 #else 702 return (p[0] | (p[1] << 8)); 703 #endif 704 } 705 static inline unsigned int 706 load_32_le (const void *cvp) 707 { 708 const unsigned char *p = (const unsigned char *) cvp; 709 #if defined(__GNUC__) && defined(K5_LE) && !defined(__cplusplus) 710 return GET(32,p); 711 #elif defined(__GNUC__) && defined(K5_BE) && defined(SWAP32) && !defined(__cplusplus) 712 return GETSWAPPED(32,p); 713 #else 714 return (p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24)); 715 #endif 716 } 717 static inline uint64_t 718 load_64_le (const void *cvp) 719 { 720 const unsigned char *p = (const unsigned char *) cvp; 721 #if defined(__GNUC__) && defined(K5_LE) && !defined(__cplusplus) 722 return GET(64,p); 723 #elif defined(__GNUC__) && defined(K5_BE) && defined(SWAP64) && !defined(__cplusplus) 724 return GETSWAPPED(64,p); 725 #else 726 return ((uint64_t)load_32_le(p+4) << 32) | load_32_le(p); 727 #endif 728 } 729 730 #define UINT16_TYPE uint16_t 731 #define UINT32_TYPE uint32_t 732 733 static inline void 734 store_16_n (unsigned int val, void *vp) 735 { 736 UINT16_TYPE n = val; 737 memcpy(vp, &n, 2); 738 } 739 static inline void 740 store_32_n (unsigned int val, void *vp) 741 { 742 UINT32_TYPE n = val; 743 memcpy(vp, &n, 4); 744 } 745 static inline void 746 store_64_n (uint64_t val, void *vp) 747 { 748 uint64_t n = val; 749 memcpy(vp, &n, 8); 750 } 751 static inline unsigned short 752 load_16_n (const void *p) 753 { 754 UINT16_TYPE n; 755 memcpy(&n, p, 2); 756 return n; 757 } 758 static inline unsigned int 759 load_32_n (const void *p) 760 { 761 UINT32_TYPE n; 762 memcpy(&n, p, 4); 763 return n; 764 } 765 static inline uint64_t 766 load_64_n (const void *p) 767 { 768 uint64_t n; 769 memcpy(&n, p, 8); 770 return n; 771 } 772 #undef UINT16_TYPE 773 #undef UINT32_TYPE 774 775 /* Assume for simplicity that these swaps are identical. */ 776 static inline uint64_t 777 k5_htonll (uint64_t val) 778 { 779 #ifdef K5_BE 780 return val; 781 #elif defined K5_LE && defined SWAP64 782 return SWAP64 (val); 783 #else 784 return load_64_be ((unsigned char *)&val); 785 #endif 786 } 787 static inline uint64_t 788 k5_ntohll (uint64_t val) 789 { 790 return k5_htonll (val); 791 } 792 793 /* Make the interfaces to getpwnam and getpwuid consistent. 794 Model the wrappers on the POSIX thread-safe versions, but 795 use the unsafe system versions if the safe ones don't exist 796 or we can't figure out their interfaces. */ 797 798 /* int k5_getpwnam_r(const char *, blah blah) */ 799 #ifdef HAVE_GETPWNAM_R 800 # ifndef GETPWNAM_R_4_ARGS 801 /* POSIX */ 802 # define k5_getpwnam_r(NAME, REC, BUF, BUFSIZE, OUT) \ 803 (getpwnam_r(NAME,REC,BUF,BUFSIZE,OUT) == 0 \ 804 ? (*(OUT) == NULL ? -1 : 0) : -1) 805 # else 806 /* POSIX drafts? */ 807 # ifdef GETPWNAM_R_RETURNS_INT 808 # define k5_getpwnam_r(NAME, REC, BUF, BUFSIZE, OUT) \ 809 (getpwnam_r(NAME,REC,BUF,BUFSIZE) == 0 \ 810 ? (*(OUT) = REC, 0) \ 811 : (*(OUT) = NULL, -1)) 812 # else 813 # define k5_getpwnam_r(NAME, REC, BUF, BUFSIZE, OUT) \ 814 (*(OUT) = getpwnam_r(NAME,REC,BUF,BUFSIZE), *(OUT) == NULL ? -1 : 0) 815 # endif 816 # endif 817 #else /* no getpwnam_r, or can't figure out #args or return type */ 818 /* Will get warnings about unused variables. */ 819 # define k5_getpwnam_r(NAME, REC, BUF, BUFSIZE, OUT) \ 820 (*(OUT) = getpwnam(NAME), *(OUT) == NULL ? -1 : 0) 821 #endif 822 823 /* int k5_getpwuid_r(uid_t, blah blah) */ 824 #ifdef HAVE_GETPWUID_R 825 # ifndef GETPWUID_R_4_ARGS 826 /* POSIX */ 827 # define k5_getpwuid_r(UID, REC, BUF, BUFSIZE, OUT) \ 828 (getpwuid_r(UID,REC,BUF,BUFSIZE,OUT) == 0 \ 829 ? (*(OUT) == NULL ? -1 : 0) : -1) 830 # else 831 /* POSIX drafts? Yes, I mean to test GETPWNAM... here. Less junk to 832 do at configure time. */ 833 # ifdef GETPWNAM_R_RETURNS_INT 834 # define k5_getpwuid_r(UID, REC, BUF, BUFSIZE, OUT) \ 835 (getpwuid_r(UID,REC,BUF,BUFSIZE) == 0 \ 836 ? (*(OUT) = REC, 0) \ 837 : (*(OUT) = NULL, -1)) 838 # else 839 # define k5_getpwuid_r(UID, REC, BUF, BUFSIZE, OUT) \ 840 (*(OUT) = getpwuid_r(UID,REC,BUF,BUFSIZE), *(OUT) == NULL ? -1 : 0) 841 # endif 842 # endif 843 #else /* no getpwuid_r, or can't figure out #args or return type */ 844 /* Will get warnings about unused variables. */ 845 # define k5_getpwuid_r(UID, REC, BUF, BUFSIZE, OUT) \ 846 (*(OUT) = getpwuid(UID), *(OUT) == NULL ? -1 : 0) 847 #endif 848 849 /* Ensure, if possible, that the indicated file descriptor won't be 850 kept open if we exec another process (e.g., launching a ccapi 851 server). If we don't know how to do it... well, just go about our 852 business. Probably most callers won't check the return status 853 anyways. */ 854 855 /* Macros make the Sun compiler happier, and all variants of this do a 856 single evaluation of the argument, and fcntl and fileno should 857 produce reasonable error messages on type mismatches, on any system 858 with F_SETFD. */ 859 #ifdef F_SETFD 860 # ifdef FD_CLOEXEC 861 # define set_cloexec_fd(FD) ((void)fcntl((FD), F_SETFD, FD_CLOEXEC)) 862 # else 863 # define set_cloexec_fd(FD) ((void)fcntl((FD), F_SETFD, 1)) 864 # endif 865 #else 866 # define set_cloexec_fd(FD) ((void)(FD)) 867 #endif 868 #define set_cloexec_file(F) set_cloexec_fd(fileno(F)) 869 870 /* Since the original ANSI C spec left it undefined whether or 871 how you could copy around a va_list, C 99 added va_copy. 872 For old implementations, let's do our best to fake it. 873 874 XXX Doesn't yet handle implementations with __va_copy (early draft) 875 or GCC's __builtin_va_copy. */ 876 #if defined(HAS_VA_COPY) || defined(va_copy) 877 /* Do nothing. */ 878 #elif defined(CAN_COPY_VA_LIST) 879 #define va_copy(dest, src) ((dest) = (src)) 880 #else 881 /* Assume array type, but still simply copyable. 882 883 There is, theoretically, the possibility that va_start will 884 allocate some storage pointed to by the va_list, and in that case 885 we'll just lose. If anyone cares, we could try to devise a test 886 for that case. */ 887 #define va_copy(dest, src) memcpy(dest, src, sizeof(va_list)) 888 #endif 889 890 /* Provide strlcpy/strlcat interfaces. */ 891 #ifndef HAVE_STRLCPY 892 #define strlcpy krb5int_strlcpy 893 #define strlcat krb5int_strlcat 894 extern size_t krb5int_strlcpy(char *dst, const char *src, size_t siz); 895 extern size_t krb5int_strlcat(char *dst, const char *src, size_t siz); 896 #endif 897 898 /* Provide fnmatch interface. */ 899 #ifndef HAVE_FNMATCH 900 #define fnmatch k5_fnmatch 901 int k5_fnmatch(const char *pattern, const char *string, int flags); 902 #define FNM_NOMATCH 1 /* Match failed. */ 903 #define FNM_NOSYS 2 /* Function not implemented. */ 904 #define FNM_NORES 3 /* Out of resources */ 905 #define FNM_NOESCAPE 0x01 /* Disable backslash escaping. */ 906 #define FNM_PATHNAME 0x02 /* Slash must be matched by slash. */ 907 #define FNM_PERIOD 0x04 /* Period must be matched by period. */ 908 #define FNM_CASEFOLD 0x08 /* Pattern is matched case-insensitive */ 909 #define FNM_LEADING_DIR 0x10 /* Ignore /<tail> after Imatch. */ 910 #endif 911 912 /* Provide [v]asprintf interfaces. */ 913 #ifndef HAVE_VSNPRINTF 914 #ifdef _WIN32 915 static inline int 916 vsnprintf(char *str, size_t size, const char *format, va_list args) 917 { 918 va_list args_copy; 919 int length; 920 921 va_copy(args_copy, args); 922 length = _vscprintf(format, args_copy); 923 va_end(args_copy); 924 if (size > 0) { 925 _vsnprintf(str, size, format, args); 926 str[size - 1] = '\0'; 927 } 928 return length; 929 } 930 static inline int 931 snprintf(char *str, size_t size, const char *format, ...) 932 { 933 va_list args; 934 int n; 935 936 va_start(args, format); 937 n = vsnprintf(str, size, format, args); 938 va_end(args); 939 return n; 940 } 941 #else /* not win32 */ 942 #error We need an implementation of vsnprintf. 943 #endif /* win32? */ 944 #endif /* no vsnprintf */ 945 946 #ifndef HAVE_VASPRINTF 947 948 extern int krb5int_vasprintf(char **, const char *, va_list) 949 #if !defined(__cplusplus) && (__GNUC__ > 2) 950 __attribute__((__format__(__printf__, 2, 0))) 951 #endif 952 ; 953 extern int krb5int_asprintf(char **, const char *, ...) 954 #if !defined(__cplusplus) && (__GNUC__ > 2) 955 __attribute__((__format__(__printf__, 2, 3))) 956 #endif 957 ; 958 959 #define vasprintf krb5int_vasprintf 960 /* Assume HAVE_ASPRINTF iff HAVE_VASPRINTF. */ 961 #define asprintf krb5int_asprintf 962 963 #elif defined(NEED_VASPRINTF_PROTO) 964 965 extern int vasprintf(char **, const char *, va_list) 966 #if !defined(__cplusplus) && (__GNUC__ > 2) 967 __attribute__((__format__(__printf__, 2, 0))) 968 #endif 969 ; 970 extern int asprintf(char **, const char *, ...) 971 #if !defined(__cplusplus) && (__GNUC__ > 2) 972 __attribute__((__format__(__printf__, 2, 3))) 973 #endif 974 ; 975 976 #endif /* have vasprintf and prototype? */ 977 978 /* Return true if the snprintf return value RESULT reflects a buffer 979 overflow for the buffer size SIZE. 980 981 We cast the result to unsigned int for two reasons. First, old 982 implementations of snprintf (such as the one in Solaris 9 and 983 prior) return -1 on a buffer overflow. Casting the result to -1 984 will convert that value to UINT_MAX, which should compare larger 985 than any reasonable buffer size. Second, comparing signed and 986 unsigned integers will generate warnings with some compilers, and 987 can have unpredictable results, particularly when the relative 988 widths of the types is not known (size_t may be the same width as 989 int or larger). 990 */ 991 #define SNPRINTF_OVERFLOW(result, size) \ 992 ((unsigned int)(result) >= (size_t)(size)) 993 994 #if defined(_WIN32) || !defined(HAVE_STRERROR_R) || defined(STRERROR_R_CHAR_P) 995 #define strerror_r k5_strerror_r 996 #endif 997 extern int k5_strerror_r(int errnum, char *buf, size_t buflen); 998 999 #ifndef HAVE_MKSTEMP 1000 extern int krb5int_mkstemp(char *); 1001 #define mkstemp krb5int_mkstemp 1002 #endif 1003 1004 #ifndef HAVE_GETTIMEOFDAY 1005 extern int krb5int_gettimeofday(struct timeval *tp, void *ignore); 1006 #define gettimeofday krb5int_gettimeofday 1007 #endif 1008 1009 /* 1010 * Attempt to zero memory in a way that compilers won't optimize out. 1011 * 1012 * This mechanism should work even for heap storage about to be freed, 1013 * or automatic storage right before we return from a function. 1014 * 1015 * Then, even if we leak uninitialized memory someplace, or UNIX 1016 * "core" files get created with world-read access, some of the most 1017 * sensitive data in the process memory will already be safely wiped. 1018 * 1019 * We're not going so far -- yet -- as to try to protect key data that 1020 * may have been written into swap space.... 1021 */ 1022 #ifdef _WIN32 1023 # define zap(ptr, len) SecureZeroMemory(ptr, len) 1024 #elif defined(__STDC_LIB_EXT1__) 1025 /* 1026 * Use memset_s() which cannot be optimized out. Avoid memset_s(NULL, 0, 0, 0) 1027 * which would cause a runtime constraint violation. 1028 */ 1029 static inline void zap(void *ptr, size_t len) 1030 { 1031 if (len > 0) 1032 memset_s(ptr, len, 0, len); 1033 } 1034 #elif defined(HAVE_EXPLICIT_BZERO) 1035 # define zap(ptr, len) explicit_bzero(ptr, len) 1036 #elif defined(HAVE_EXPLICIT_MEMSET) 1037 # define zap(ptr, len) explicit_memset(ptr, 0, len) 1038 #elif defined(__GNUC__) || defined(__clang__) 1039 /* 1040 * Use an asm statement which declares a memory clobber to force the memset to 1041 * be carried out. Avoid memset(NULL, 0, 0) which has undefined behavior. 1042 */ 1043 static inline void zap(void *ptr, size_t len) 1044 { 1045 if (len > 0) 1046 memset(ptr, 0, len); 1047 __asm__ __volatile__("" : : "g" (ptr) : "memory"); 1048 } 1049 #else 1050 /* 1051 * Use a function from libkrb5support to defeat inlining unless link-time 1052 * optimization is used. The function uses a volatile pointer, which prevents 1053 * current compilers from optimizing out the memset. 1054 */ 1055 # define zap(ptr, len) krb5int_zap(ptr, len) 1056 #endif 1057 1058 extern void krb5int_zap(void *ptr, size_t len); 1059 1060 /* 1061 * Return 0 if the n-byte memory regions p1 and p2 are equal, and nonzero if 1062 * they are not. The function is intended to take the same amount of time 1063 * regardless of how many bytes of p1 and p2 are equal. 1064 */ 1065 int k5_bcmp(const void *p1, const void *p2, size_t n); 1066 1067 /* 1068 * Split a path into parent directory and basename. Either output parameter 1069 * may be NULL if the caller doesn't need it. parent_out will be empty if path 1070 * has no basename. basename_out will be empty if path ends with a path 1071 * separator. Returns 0 on success or ENOMEM on allocation failure. 1072 */ 1073 long k5_path_split(const char *path, char **parent_out, char **basename_out); 1074 1075 /* 1076 * Compose two path components, inserting the platform-appropriate path 1077 * separator if needed. If path2 is an absolute path, path1 will be discarded 1078 * and path_out will be a copy of path2. Returns 0 on success or ENOMEM on 1079 * allocation failure. 1080 */ 1081 long k5_path_join(const char *path1, const char *path2, char **path_out); 1082 1083 /* Return 1 if path is absolute, 0 if it is relative. */ 1084 int k5_path_isabs(const char *path); 1085 1086 /* 1087 * Localization macros. If we have gettext, define _ appropriately for 1088 * translating a string. If we do not have gettext, define _ and 1089 * bindtextdomain as no-ops. N_ is always a no-op; it marks a string for 1090 * extraction to pot files but does not translate it. 1091 */ 1092 #ifdef ENABLE_NLS 1093 #include <libintl.h> 1094 #define KRB5_TEXTDOMAIN "mit-krb5" 1095 #define _(s) dgettext(KRB5_TEXTDOMAIN, s) 1096 #else 1097 #define _(s) s 1098 #define dgettext(d, m) m 1099 #define ngettext(m1, m2, n) (((n) == 1) ? m1 : m2) 1100 #define bindtextdomain(p, d) 1101 #endif 1102 #define N_(s) s 1103 1104 #if !defined(HAVE_GETOPT) || !defined(HAVE_UNISTD_H) 1105 /* Data objects imported from DLLs must be declared as such on Windows. */ 1106 #if defined(_WIN32) && !defined(K5_GETOPT_C) 1107 #define K5_GETOPT_DECL __declspec(dllimport) 1108 #else 1109 #define K5_GETOPT_DECL 1110 #endif 1111 K5_GETOPT_DECL extern int k5_opterr; 1112 K5_GETOPT_DECL extern int k5_optind; 1113 K5_GETOPT_DECL extern int k5_optopt; 1114 K5_GETOPT_DECL extern char *k5_optarg; 1115 #define opterr k5_opterr 1116 #define optind k5_optind 1117 #define optopt k5_optopt 1118 #define optarg k5_optarg 1119 1120 extern int k5_getopt(int nargc, char * const nargv[], const char *ostr); 1121 #define getopt k5_getopt 1122 #endif /* HAVE_GETOPT */ 1123 1124 #ifdef HAVE_GETOPT_LONG 1125 #include <getopt.h> 1126 #else 1127 1128 struct option 1129 { 1130 const char *name; 1131 int has_arg; 1132 int *flag; 1133 int val; 1134 }; 1135 1136 #define no_argument 0 1137 #define required_argument 1 1138 #define optional_argument 2 1139 1140 extern int k5_getopt_long(int nargc, char **nargv, char *options, 1141 struct option *long_options, int *index); 1142 #define getopt_long k5_getopt_long 1143 #endif /* HAVE_GETOPT_LONG */ 1144 1145 #if defined(_WIN32) 1146 /* On Windows there is never a need to ignore the process environment. */ 1147 #define secure_getenv getenv 1148 #elif !defined(HAVE_SECURE_GETENV) 1149 #define secure_getenv k5_secure_getenv 1150 extern char *k5_secure_getenv(const char *name); 1151 #endif 1152 1153 /* Set *fnames_out to a null-terminated list of filenames within dirname, 1154 * sorted according to strcmp(). Return 0 on success, or ENOENT/ENOMEM. */ 1155 int k5_dir_filenames(const char *dirname, char ***fnames_out); 1156 void k5_free_filenames(char **fnames); 1157 1158 #ifdef __cplusplus 1159 } 1160 #endif 1161 1162 #endif /* K5_PLATFORM_H */ 1163