// uid/gid + job-control regression for GNO (punch-list #11).  Exercises the
// non-destructive getter surface -- getuid/geteuid/getgid/getegid, getpid, and
// getpgrp -- and asserts the boot-independent invariants: real == effective
// ids, a valid (non-error) process group, and a positive pid.  The MUTATING
// calls (setuid/setgid/setpgid/tcsetpgrp) are deliberately NOT driven here:
// they would alter this process' credentials / process group under gsh and make
// the run non-deterministic.  tcgetpgrp/setsid are ENOSYS stubs and need no run.
//
// Bank-2 absolute markers (DBR-independent), per the gnoHeapProbe convention.
//   0x025000  C0DE  reached end
//   0x025010  0001  getuid()  == geteuid()   (real/effective uid consistent)
//   0x025012  0001  getgid()  == getegid()   (real/effective gid consistent)
//   0x025014  0001  getpgrp() >= 0           (K_getpgrp did not fail)
//   0x025016  0001  getpid()  >  0           (valid pid)
#include <stdint.h>
#include <unistd.h>

#define M(a) (*(volatile uint16_t *)(a))


int main(void) {
    int uid;
    int euid;
    int gid;
    int egid;
    int pid;
    int pgrp;

    M(0x025000UL) = 0x0000;
    uid  = (int)getuid();
    euid = (int)geteuid();
    gid  = (int)getgid();
    egid = (int)getegid();
    pid  = getpid();
    pgrp = (int)getpgrp();

    M(0x025010UL) = (uid  == euid) ? 0x0001 : 0xDEAD;
    M(0x025012UL) = (gid  == egid) ? 0x0001 : 0xDEAD;
    M(0x025014UL) = (pgrp >= 0)    ? 0x0001 : 0xDEAD;
    M(0x025016UL) = (pid  >  0)    ? 0x0001 : 0xDEAD;
    M(0x025018UL) = (uint16_t)pgrp;         // informational
    M(0x02501AUL) = (uint16_t)uid;          // informational
    M(0x025000UL) = 0xC0DE;                 // reached end
    for (volatile unsigned long j = 0; j < 300000UL; j++) {
    }
    return 0;
}
