1 /* HMACROS.H (c) Copyright Roger Bowler, 1999-2014 */ 2 /* Hercules macros */ 3 4 #ifndef _HMACROS_H 5 #define _HMACROS_H 6 7 #include "hercules.h" 8 9 /*-------------------------------------------------------------------*/ 10 /* "Portability" macros for handling _MSVC_ port... */ 11 /*-------------------------------------------------------------------*/ 12 13 /* PROGRAMMING NOTE: the following 'tape' portability macros are 14 only for physical (SCSI) tape devices, not emulated aws files */ 15 16 #ifdef _MSVC_ 17 #define open_tape w32_open_tape 18 #define read_tape w32_read_tape 19 #define write_tape w32_write_tape 20 #define ioctl_tape w32_ioctl_tape 21 #define close_tape w32_close_tape 22 #else 23 #define open_tape open 24 #define read_tape read 25 #define write_tape write 26 #define ioctl_tape ioctl 27 #define close_tape close 28 #endif 29 30 #ifdef _MSVC_ 31 #define create_pipe(a) socketpair(AF_INET,SOCK_STREAM,IPPROTO_IP,a) 32 #define read_pipe(f,b,n) recv(f,b,n,0) 33 #define write_pipe(f,b,n) send(f,b,(int)n,0) 34 #define close_pipe(f) closesocket(f) 35 #else 36 #define create_pipe(f) pipe(f) 37 #define read_pipe(f,b,n) read(f,b,n) 38 #define write_pipe(f,b,n) write(f,b,n) 39 #define close_pipe(f) close(f) 40 #endif 41 42 #ifdef _MSVC_ 43 #define socket w32_socket 44 /* Now defined in hsocket.h 45 int read_socket(int fd, char *ptr, int nbytes); 46 int write_socket(int fd, const char *ptr, int nbytes); 47 */ 48 #define close_socket(f) closesocket(f) 49 #else 50 /* Now defined in hsocket.h 51 int read_socket(int fd, char *ptr, int nbytes); 52 int write_socket(int fd, const char *ptr, int nbytes); 53 */ 54 #define close_socket(f) close(f) 55 #endif 56 57 #ifdef _MSVC_ 58 #undef FD_SET 59 #undef FD_ISSET 60 #define FD_SET w32_FD_SET 61 #define FD_ISSET w32_FD_ISSET 62 #define select(n,r,w,e,t) w32_select((n),(r),(w),(e),(t),__FILE__,__LINE__) 63 #define fdopen w32_fdopen 64 #define fwrite w32_fwrite 65 #define fprintf w32_fprintf 66 #define fclose w32_fclose 67 #endif 68 69 #ifdef _MSVC_ 70 #define fdatasync _commit 71 #define atoll _atoi64 72 #else 73 #if !defined(HAVE_FDATASYNC_SUPPORTED) 74 #ifdef HAVE_FSYNC 75 #define fdatasync fsync 76 #else 77 #error Required 'fdatasync' function is missing and alternate 'fsync' function also missing 78 #endif 79 #endif 80 #define atoll(s) strtoll(s,NULL,0) 81 #endif 82 83 /*-------------------------------------------------------------------*/ 84 /* Portable macro for copying 'va_list' variable arguments variable */ 85 /*-------------------------------------------------------------------*/ 86 87 // ZZ FIXME: this should probably be handled in configure.ac... 88 89 #if !defined( va_copy ) 90 #if defined( __va_copy ) 91 #define va_copy __va_copy 92 #elif defined( _MSVC_ ) 93 #define va_copy(to,from) (to) = (from) 94 #else 95 #define va_copy(to,from) memcpy((to),(from),sizeof(va_list)) 96 #endif 97 #endif 98 99 /*-------------------------------------------------------------------*/ 100 /* some handy array/struct macros... */ 101 /*-------------------------------------------------------------------*/ 102 103 #ifndef _countof 104 #define _countof(x) ( sizeof(x) / sizeof(x[0]) ) 105 #endif 106 #ifndef arraysize 107 #define arraysize(x) _countof(x) 108 #endif 109 #ifndef sizeof_member 110 #define sizeof_member(_struct,_member) sizeof(((_struct*)0)->_member) 111 #endif 112 #ifndef offsetof 113 #define offsetof(_struct,_member) (size_t)&(((_struct*)0)->_member) 114 #endif 115 116 /*-------------------------------------------------------------------*/ 117 /* Large File Support portability... */ 118 /*-------------------------------------------------------------------*/ 119 120 #ifdef _MSVC_ 121 /* "Native" 64-bit Large File Support */ 122 #define off_t __int64 123 #if (_MSC_VER >= 1400) 124 #define ftruncate _chsize_s 125 #define ftell _ftelli64 126 #define fseek _fseeki64 127 #else // (_MSC_VER < 1400) 128 #define ftruncate w32_ftrunc64 129 #define ftell w32_ftelli64 130 #define fseek w32_fseeki64 131 #endif 132 #define lseek _lseeki64 133 #define fstat _fstati64 134 #define stat _stati64 135 #elif defined(_LFS_LARGEFILE) || ( defined(SIZEOF_OFF_T) && SIZEOF_OFF_T > 4 ) 136 /* Native 64-bit Large File Support */ 137 #if defined(HAVE_FSEEKO) 138 #define ftell ftello 139 #define fseek fseeko 140 #else 141 #if defined(SIZEOF_LONG) && SIZEOF_LONG <= 4 142 #warning fseek/ftell use offset arguments of insufficient size 143 #endif 144 #endif 145 #elif defined(_LFS64_LARGEFILE) 146 /* Transitional 64-bit Large File Support */ 147 #define off_t off64_t 148 #define ftruncate ftruncate64 149 #define ftell ftello64 150 #define fseek fseeko64 151 #define lseek lseek64 152 #define fstat fstat64 153 #define stat stat64 154 #else // !defined(_LFS_LARGEFILE) && !defined(_LFS64_LARGEFILE) && (!defined(SIZEOF_OFF_T) || SIZEOF_OFF_T <= 4) 155 /* No 64-bit Large File Support at all */ 156 #warning Large File Support missing 157 #endif 158 159 /*-------------------------------------------------------------------*/ 160 /* Macro definitions for version number */ 161 /*-------------------------------------------------------------------*/ 162 163 #define STRINGMAC(x) #x 164 #define MSTRING(x) STRINGMAC(x) 165 166 /*-------------------------------------------------------------------*/ 167 /* Use these to suppress unreferenced variable warnings... */ 168 /*-------------------------------------------------------------------*/ 169 170 #define UNREFERENCED(x) ((x)=(x)) 171 #define UNREFERENCED_370(x) ((x)=(x)) 172 #define UNREFERENCED_390(x) ((x)=(x)) 173 #define UNREFERENCED_900(x) ((x)=(x)) 174 175 /*-------------------------------------------------------------------*/ 176 /* Macro for Debugging / Tracing... */ 177 /*-------------------------------------------------------------------*/ 178 179 /* Add message prefix filename:linenumber: to messages 180 when compiled with debug enabled - JJ 30/12/99 */ 181 /* But only if OPTION_DEBUG_MESSAGES defined in featall.h - Fish */ 182 183 #define DEBUG_MSG_Q( _string ) #_string 184 #define DEBUG_MSG_M( _string ) DEBUG_MSG_Q( _string ) 185 #define DEBUG_MSG( _string ) __FILE__ ":" DEBUG_MSG_M( __LINE__ ) ":" _string 186 #define D_( _string ) DEBUG_MSG( _string ) 187 188 #if defined(OPTION_DEBUG_MESSAGES) && defined(DEBUG) 189 #define DEBUG_( _string ) D_( _string ) 190 #else 191 #define DEBUG_( _string ) _string 192 #endif 193 194 #define _(_string) (DEBUG_(_string)) 195 196 #if defined(DEBUG) || defined(_DEBUG) 197 198 #ifdef _MSVC_ 199 200 #define TRACE(...) \ 201 do \ 202 { \ 203 IsDebuggerPresent() ? DebugTrace (__VA_ARGS__): \ 204 logmsg (__VA_ARGS__); \ 205 } \ 206 while (0) 207 208 #undef ASSERT /* For VS9 2008 */ 209 #define ASSERT(a) \ 210 do \ 211 { \ 212 if (!(a)) \ 213 { \ 214 TRACE("HHCxx999W *** Assertion Failed! *** %s(%d); function: %s\n",__FILE__,__LINE__,__FUNCTION__); \ 215 if (IsDebuggerPresent()) DebugBreak(); /* (break into debugger) */ \ 216 } \ 217 } \ 218 while(0) 219 220 #else // ! _MSVC_ 221 222 #define TRACE logmsg 223 224 #define ASSERT(a) \ 225 do \ 226 { \ 227 if (!(a)) \ 228 { \ 229 TRACE("HHCxx999W *** Assertion Failed! *** %s(%d)\n",__FILE__,__LINE__); \ 230 } \ 231 } \ 232 while(0) 233 234 #endif // _MSVC_ 235 236 #define VERIFY ASSERT 237 238 #else // non-debug build... 239 240 #ifdef _MSVC_ 241 242 #define TRACE __noop 243 #undef ASSERT /* For VS9 2008 */ 244 #define ASSERT(a) __noop 245 #define VERIFY(a) ((void)(a)) 246 247 #else // ! _MSVC_ 248 249 #define TRACE 1 ? ((void)0) : logmsg 250 #define ASSERT(a) 251 #define VERIFY(a) ((void)(a)) 252 253 #endif // _MSVC_ 254 255 #endif 256 257 /* Opcode routing table function pointer */ 258 typedef void (ATTR_REGPARM(2)*FUNC)(); 259 260 /* Program Interrupt function pointer */ 261 typedef void (ATTR_REGPARM(2) *pi_func) (REGS *regs, int pcode); 262 263 /* trace_br function */ 264 typedef U32 (*s390_trace_br_func) (int amode, U32 ia, REGS *regs); 265 typedef U64 (*z900_trace_br_func) (int amode, U64 ia, REGS *regs); 266 267 /*-------------------------------------------------------------------*/ 268 /* Compiler optimization hints (for performance) */ 269 /*-------------------------------------------------------------------*/ 270 271 #undef likely 272 #undef unlikely 273 274 #ifdef _MSVC_ 275 276 #define likely(_c) ( (_c) ? ( __assume((_c)), 1 ) : 0 ) 277 #define unlikely(_c) ( (_c) ? 1 : ( __assume(!(_c)), 0 ) ) 278 279 #else // !_MSVC_ 280 281 #if __GNUC__ >= 3 282 #define likely(_c) __builtin_expect((_c),1) 283 #define unlikely(_c) __builtin_expect((_c),0) 284 #else 285 #define likely(_c) (_c) 286 #define unlikely(_c) (_c) 287 #endif 288 289 #endif // _MSVC_ 290 291 /*-------------------------------------------------------------------*/ 292 /* CPU state related macros and constants... */ 293 /*-------------------------------------------------------------------*/ 294 295 /* Definitions for CPU state */ 296 #define CPUSTATE_STARTED 1 /* CPU is started */ 297 #define CPUSTATE_STOPPING 2 /* CPU is stopping */ 298 #define CPUSTATE_STOPPED 3 /* CPU is stopped */ 299 300 #define IS_CPU_ONLINE(_cpu) \ 301 (sysblk.regs[(_cpu)] != NULL) 302 303 #if defined(_FEATURE_CPU_RECONFIG) 304 #define MAX_CPU sysblk.maxcpu 305 #else 306 #define MAX_CPU sysblk.numcpu 307 #endif 308 309 #define HI_CPU sysblk.hicpu 310 311 #define MAX_REPORTED_MIPSRATE (250000000) /* instructions / second */ 312 #define MAX_REPORTED_SIOSRATE (10000) /* SIOs per second */ 313 314 /* Instruction count for a CPU */ 315 #define INSTCOUNT(_regs) \ 316 ((_regs)->hostregs->prevcount + (_regs)->hostregs->instcount) 317 318 /*-------------------------------------------------------------------*/ 319 /* Obtain/Release mainlock. */ 320 /* mainlock is only obtained by a CPU thread */ 321 /*-------------------------------------------------------------------*/ 322 323 #define OBTAIN_MAINLOCK(_regs) \ 324 do { \ 325 if ((_regs)->hostregs->cpubit != (_regs)->sysblk->started_mask) { \ 326 obtain_lock(&(_regs)->sysblk->mainlock); \ 327 (_regs)->sysblk->mainowner = regs->hostregs->cpuad; \ 328 } \ 329 } while (0) 330 331 #define RELEASE_MAINLOCK(_regs) \ 332 do { \ 333 if ((_regs)->sysblk->mainowner == (_regs)->hostregs->cpuad) { \ 334 (_regs)->sysblk->mainowner = LOCK_OWNER_NONE; \ 335 release_lock(&(_regs)->sysblk->mainlock); \ 336 } \ 337 } while (0) 338 339 /*-------------------------------------------------------------------*/ 340 /* Obtain/Release intlock. */ 341 /* intlock can be obtained by any thread */ 342 /* if obtained by a cpu thread, check to see if synchronize_cpus */ 343 /* is in progress. */ 344 /*-------------------------------------------------------------------*/ 345 346 #define OBTAIN_INTLOCK(_iregs) \ 347 do { \ 348 REGS *_regs = (_iregs); \ 349 if ((_regs)) \ 350 (_regs)->hostregs->intwait = 1; \ 351 obtain_lock (&sysblk.intlock); \ 352 if ((_regs)) { \ 353 while (sysblk.syncing) { \ 354 sysblk.sync_mask &= ~(_regs)->hostregs->cpubit; \ 355 if (!sysblk.sync_mask) \ 356 signal_condition(&sysblk.sync_cond); \ 357 wait_condition(&sysblk.sync_bc_cond, &sysblk.intlock); \ 358 } \ 359 (_regs)->hostregs->intwait = 0; \ 360 sysblk.intowner = (_regs)->hostregs->cpuad; \ 361 } else \ 362 sysblk.intowner = LOCK_OWNER_OTHER; \ 363 } while (0) 364 365 #define RELEASE_INTLOCK(_regs) \ 366 do { \ 367 sysblk.intowner = LOCK_OWNER_NONE; \ 368 release_lock(&sysblk.intlock); \ 369 } while (0) 370 371 /*-------------------------------------------------------------------*/ 372 /* Returns when all other CPU threads are blocked on intlock */ 373 /*-------------------------------------------------------------------*/ 374 375 #define SYNCHRONIZE_CPUS(_regs) \ 376 do { \ 377 int _i, _n = 0; \ 378 CPU_BITMAP _mask = sysblk.started_mask \ 379 ^ (sysblk.waiting_mask | (_regs)->hostregs->cpubit); \ 380 for (_i = 0; _mask && _i < sysblk.hicpu; _i++) { \ 381 if ((_mask & CPU_BIT(_i))) { \ 382 if (sysblk.regs[_i]->intwait || sysblk.regs[_i]->syncio) \ 383 _mask ^= CPU_BIT(_i); \ 384 else { \ 385 ON_IC_INTERRUPT(sysblk.regs[_i]); \ 386 if (SIE_MODE(sysblk.regs[_i])) \ 387 ON_IC_INTERRUPT(sysblk.regs[_i]->guestregs); \ 388 _n++; \ 389 } \ 390 } \ 391 } \ 392 if (_n) { \ 393 if (_n < hostinfo.num_procs) { \ 394 for (_n = 1; _mask; _n++) { \ 395 if (_n & 0xff) \ 396 sched_yield(); \ 397 else \ 398 usleep(1); \ 399 for (_i = 0; _i < sysblk.hicpu; _i++) \ 400 if ((_mask & CPU_BIT(_i)) && sysblk.regs[_i]->intwait) \ 401 _mask ^= CPU_BIT(_i); \ 402 } \ 403 } else { \ 404 sysblk.sync_mask = sysblk.started_mask \ 405 ^ (sysblk.waiting_mask | (_regs)->hostregs->cpubit); \ 406 sysblk.syncing = 1; \ 407 sysblk.intowner = LOCK_OWNER_NONE; \ 408 wait_condition(&sysblk.sync_cond, &sysblk.intlock); \ 409 sysblk.intowner = (_regs)->hostregs->cpuad; \ 410 sysblk.syncing = 0; \ 411 broadcast_condition(&sysblk.sync_bc_cond); \ 412 } \ 413 } \ 414 } while (0) 415 416 /*-------------------------------------------------------------------*/ 417 /* Macros to signal interrupt condition to a CPU[s]... */ 418 /*-------------------------------------------------------------------*/ 419 420 #define WAKEUP_CPU(_regs) \ 421 do { \ 422 signal_condition(&(_regs)->intcond); \ 423 } while (0) 424 425 #define WAKEUP_CPU_MASK(_mask) \ 426 do { \ 427 int i; \ 428 CPU_BITMAP mask = (_mask); \ 429 for (i = 0; mask; i++) { \ 430 if (mask & 1) \ 431 { \ 432 signal_condition(&sysblk.regs[i]->intcond); \ 433 break; \ 434 } \ 435 mask >>= 1; \ 436 } \ 437 } while (0) 438 439 #define WAKEUP_CPUS_MASK(_mask) \ 440 do { \ 441 int i; \ 442 CPU_BITMAP mask = (_mask); \ 443 for (i = 0; mask; i++) { \ 444 if (mask & 1) \ 445 signal_condition(&sysblk.regs[i]->intcond); \ 446 mask >>= 1; \ 447 } \ 448 } while (0) 449 450 /*-------------------------------------------------------------------*/ 451 /* Macros to queue/dequeue a device on the I/O interrupt queue... */ 452 /*-------------------------------------------------------------------*/ 453 454 /* NOTE: sysblk.iointqlk ALWAYS needed to examine sysblk.iointq */ 455 456 #define QUEUE_IO_INTERRUPT(_io) \ 457 do { \ 458 obtain_lock(&sysblk.iointqlk); \ 459 QUEUE_IO_INTERRUPT_QLOCKED((_io)); \ 460 release_lock(&sysblk.iointqlk); \ 461 } while (0) 462 463 #define QUEUE_IO_INTERRUPT_QLOCKED(_io) \ 464 do { \ 465 IOINT *prev; \ 466 for (prev = (IOINT *)&sysblk.iointq; prev->next != NULL; prev = prev->next) \ 467 if (prev->next == (_io) || prev->next->priority > (_io)->dev->priority) \ 468 break; \ 469 if (prev->next != (_io)) { \ 470 (_io)->next = prev->next; \ 471 prev->next = (_io); \ 472 (_io)->priority = (_io)->dev->priority; \ 473 } \ 474 if ((_io)->pending) (_io)->dev->pending = 1; \ 475 else if ((_io)->pcipending) (_io)->dev->pcipending = 1; \ 476 else if ((_io)->attnpending) (_io)->dev->attnpending = 1; \ 477 } while (0) 478 479 #define DEQUEUE_IO_INTERRUPT(_io) \ 480 do { \ 481 obtain_lock(&sysblk.iointqlk); \ 482 DEQUEUE_IO_INTERRUPT_QLOCKED((_io)); \ 483 release_lock(&sysblk.iointqlk); \ 484 } while (0) 485 486 #define DEQUEUE_IO_INTERRUPT_QLOCKED(_io) \ 487 do { \ 488 IOINT *prev; \ 489 for (prev = (IOINT *)&sysblk.iointq; prev->next != NULL; prev = prev->next) \ 490 if (prev->next == (_io)) { \ 491 prev->next = (_io)->next; \ 492 if ((_io)->pending) (_io)->dev->pending = 0; \ 493 else if ((_io)->pcipending) (_io)->dev->pcipending = 0; \ 494 else if ((_io)->attnpending) (_io)->dev->attnpending = 0; \ 495 break; \ 496 } \ 497 } while (0) 498 499 /* NOTE: sysblk.iointqlk needed to examine sysblk.iointq, 500 sysblk.intlock (which MUST be held before calling these 501 macros) needed in order to set/reset IC_IOPENDING flag */ 502 503 #define UPDATE_IC_IOPENDING() \ 504 do { \ 505 obtain_lock(&sysblk.iointqlk); \ 506 UPDATE_IC_IOPENDING_QLOCKED(); \ 507 release_lock(&sysblk.iointqlk); \ 508 } while (0) 509 510 #define UPDATE_IC_IOPENDING_QLOCKED() \ 511 do { \ 512 if (sysblk.iointq == NULL) \ 513 OFF_IC_IOPENDING; \ 514 else { \ 515 ON_IC_IOPENDING; \ 516 WAKEUP_CPU_MASK (sysblk.waiting_mask); \ 517 } \ 518 } while (0) 519 520 /*-------------------------------------------------------------------*/ 521 /* Handy utility macro for channel.c */ 522 /*-------------------------------------------------------------------*/ 523 524 #define IS_CCW_IMMEDIATE(_dev) \ 525 ( \ 526 ( (_dev)->hnd->immed && (_dev)->hnd->immed[(_dev)->code]) \ 527 || ( (_dev)->immed && (_dev)->immed[(_dev)->code]) \ 528 || IS_CCW_NOP((_dev)->code) \ 529 ) 530 531 /*-------------------------------------------------------------------*/ 532 /* Hercules Dynamic Loader macro to call optional function override */ 533 /*-------------------------------------------------------------------*/ 534 535 #if defined(OPTION_DYNAMIC_LOAD) 536 #define HDC1(_func, _arg1) \ 537 ((_func) ? (_func) ((_arg1)) : (NULL)) 538 #define HDC2(_func, _arg1,_arg2) \ 539 ((_func) ? (_func) ((_arg1),(_arg2)) : (NULL)) 540 #define HDC3(_func, _arg1,_arg2,_arg3) \ 541 ((_func) ? (_func) ((_arg1),(_arg2),(_arg3)) : (NULL)) 542 #define HDC4(_func, _arg1,_arg2,_arg3,_arg4) \ 543 ((_func) ? (_func) ((_arg1),(_arg2),(_arg3),(_arg4)) : (NULL)) 544 #define HDC5(_func, _arg1,_arg2,_arg3,_arg4,_arg5) \ 545 ((_func) ? (_func) ((_arg1),(_arg2),(_arg3),(_arg4),(_arg5)) : (NULL)) 546 #define HDC6(_func, _arg1,_arg2,_arg3,_arg4,_arg5,_arg6) \ 547 ((_func) ? (_func) ((_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6)) : (NULL)) 548 #else 549 #define HDC1(_func, _arg1) \ 550 (NULL) 551 #define HDC2(_func, _arg1,_arg2) \ 552 (NULL) 553 #define HDC3(_func, _arg1,_arg2,_arg3) \ 554 (NULL) 555 #define HDC4(_func, _arg1,_arg2,arg3,arg4) \ 556 (NULL) 557 #define HDC5(_func, _arg1,_arg2,_arg3,_arg4,_arg5) \ 558 (NULL) 559 #define HDC6(_func, _arg1,_arg2,_arg3,_arg4,_arg5,_arg6) \ 560 (NULL) 561 #endif 562 563 /*-------------------------------------------------------------------*/ 564 /* sleep for as long as we like */ 565 /*-------------------------------------------------------------------*/ 566 567 #define SLEEP(_n) \ 568 do { \ 569 unsigned int rc = (_n); \ 570 while (rc) \ 571 if ((rc = sleep (rc))) \ 572 sched_yield(); \ 573 } while (0) 574 575 /*-------------------------------------------------------------------*/ 576 /* Perform standard utility initialization */ 577 /*-------------------------------------------------------------------*/ 578 579 #if !defined(EXTERNALGUI) 580 #define INITIALIZE_EXTERNAL_GUI() 581 #else 582 #define INITIALIZE_EXTERNAL_GUI() \ 583 do { \ 584 if (argc >= 1 && strncmp(argv[argc-1],"EXTERNALGUI",11) == 0) { \ 585 extgui = 1; \ 586 argv[argc-1] = NULL; \ 587 argc--; \ 588 setvbuf(stderr, NULL, _IONBF, 0); \ 589 setvbuf(stdout, NULL, _IONBF, 0); \ 590 } \ 591 } while (0) 592 #endif 593 594 #define INITIALIZE_UTILITY(name) \ 595 do { \ 596 SET_THREAD_NAME(name); \ 597 INITIALIZE_EXTERNAL_GUI(); \ 598 memset (&sysblk, 0, sizeof(SYSBLK)); \ 599 initialize_detach_attr (DETACHED); \ 600 initialize_join_attr (JOINABLE); \ 601 set_codepage(NULL); \ 602 init_hostinfo( &hostinfo ); \ 603 } while (0) 604 605 /*-------------------------------------------------------------------*/ 606 /* Macro for Setting a Thread Name (mostly for debugging purposes) */ 607 /*-------------------------------------------------------------------*/ 608 609 #ifdef _MSVC_ 610 #define SET_THREAD_NAME_ID(t,n) w32_set_thread_name((t),(n)) 611 #define SET_THREAD_NAME(n) SET_THREAD_NAME_ID(GetCurrentThreadId(),(n)) 612 #else 613 #define SET_THREAD_NAME_ID(t,n) 614 #define SET_THREAD_NAME(n) 615 #endif 616 617 #if !defined(NO_SETUID) 618 619 /* SETMODE(INIT) 620 * sets the saved uid to the effective uid, and 621 * sets the effective uid to the real uid, such 622 * that the program is running with normal user 623 * attributes, other then that it may switch to 624 * the saved uid by SETMODE(ROOT). This call is 625 * usually made upon entry to the setuid program. 626 * 627 * SETMODE(ROOT) 628 * sets the saved uid to the real uid, and 629 * sets the real and effective uid to the saved uid. 630 * A setuid root program will enter 'root mode' and 631 * will have all the appropriate access. 632 * 633 * SETMODE(USER) 634 * sets the real and effective uid to the uid of the 635 * caller. The saved uid will be the effective uid 636 * upon entry to the program (as before SETMODE(INIT)) 637 * 638 * SETMODE(TERM) 639 * sets real, effective and saved uid to the real uid 640 * upon entry to the program. This call will revoke 641 * any setuid access that the thread/process has. It 642 * is important to issue this call before an exec to a 643 * shell or other program that could introduce integrity 644 * exposures when running with root access. 645 */ 646 647 #if defined(HAVE_SYS_CAPABILITY_H) && defined(HAVE_SYS_PRCTL_H) && defined(OPTION_CAPABILITIES) 648 649 #define SETMODE(_x) 650 #define DROP_PRIVILEGES(_capa) drop_privileges(_capa) 651 #define DROP_ALL_CAPS() drop_all_caps() 652 653 #else 654 655 #define DROP_PRIVILEGES(_capa) 656 #define DROP_ALL_CAPS() 657 658 #if defined(HAVE_SETRESUID) 659 660 #define _SETMODE_INIT \ 661 do { \ 662 getresuid(&sysblk.ruid,&sysblk.euid,&sysblk.suid); \ 663 getresgid(&sysblk.rgid,&sysblk.egid,&sysblk.sgid); \ 664 setresuid(sysblk.ruid,sysblk.ruid,sysblk.euid); \ 665 setresgid(sysblk.rgid,sysblk.rgid,sysblk.egid); \ 666 } while(0) 667 668 #define _SETMODE_ROOT \ 669 do { \ 670 setresuid(sysblk.suid,sysblk.suid,sysblk.ruid); \ 671 } while(0) 672 673 #define _SETMODE_USER \ 674 do { \ 675 setresuid(sysblk.ruid,sysblk.ruid,sysblk.suid); \ 676 } while(0) 677 678 #define _SETMODE_TERM \ 679 do { \ 680 setresuid(sysblk.ruid,sysblk.ruid,sysblk.ruid); \ 681 setresgid(sysblk.rgid,sysblk.rgid,sysblk.rgid); \ 682 } while(0) 683 684 #elif defined(HAVE_SETREUID) 685 686 #define _SETMODE_INIT \ 687 do { \ 688 sysblk.ruid = getuid(); \ 689 sysblk.euid = geteuid(); \ 690 sysblk.rgid = getgid(); \ 691 sysblk.egid = getegid(); \ 692 setreuid(sysblk.euid, sysblk.ruid); \ 693 setregid(sysblk.egid, sysblk.rgid); \ 694 } while (0) 695 696 #define _SETMODE_ROOT \ 697 do { \ 698 setreuid(sysblk.ruid, sysblk.euid); \ 699 setregid(sysblk.rgid, sysblk.egid); \ 700 } while (0) 701 702 #define _SETMODE_USER \ 703 do { \ 704 setregid(sysblk.egid, sysblk.rgid); \ 705 setreuid(sysblk.euid, sysblk.ruid); \ 706 } while (0) 707 708 #define _SETMODE_TERM \ 709 do { \ 710 setuid(sysblk.ruid); \ 711 setgid(sysblk.rgid); \ 712 } while (0) 713 714 #else /* defined(HAVE_SETRESUID) || defined(HAVE_SETEREUID) */ 715 716 #error Cannot figure out how to swap effective UID/GID, maybe you should define NO_SETUID? 717 718 #endif /* defined(HAVE_SETREUID) || defined(HAVE_SETRESUID) */ 719 720 #define SETMODE(_func) _SETMODE_ ## _func 721 722 #endif /* !defined(HAVE_SYS_CAPABILITY_H) */ 723 724 #else /* !defined(NO_SETUID) */ 725 726 #define SETMODE(_func) 727 #define DROP_PRIVILEGES(_capa) 728 #define DROP_ALL_CAPS() 729 730 #endif /* !defined(NO_SETUID) */ 731 732 /* min/max macros */ 733 734 #if !defined(MIN) 735 #define MIN(_x,_y) ( ( ( _x ) < ( _y ) ) ? ( _x ) : ( _y ) ) 736 #endif /*!defined(MIN)*/ 737 738 #if !defined(MAX) 739 #define MAX(_x,_y) ( ( ( _x ) > ( _y ) ) ? ( _x ) : ( _y ) ) 740 #endif /*!defined(MAX)*/ 741 742 #if !defined(MINMAX) 743 #define MINMAX(_x,_y,_z) ((_x) = MIN(MAX((_x),(_y)),(_z))) 744 #endif /*!defined(MINMAX)*/ 745 746 #endif // _HMACROS_H 747