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