There are no less than 3 of each for the process uid and gid, real, effective, and saved, and 3 system calls that set them, setuid/setgid, seteuid/seteguid, and two I've just added to the SRFI and my Chibi Scheme implementation, setreuid/setregid, used by the new SRFI APIs set-user-real-and-effective-uid/-gid.  The last allow fine grained setting, and the details and interactions with the saved IDs and the processes' privilege are said to be important in the context of the exec functions, which I'm saving for after I knock out the simple stuff.

I bring this up because explaining the fiddly details of all of these set uid/gid functions, especially the two new ones, with set-user-real-and-effective-gid being particularly complicated, is looking to get beyond the scope of the SRFI document.  I'm certainly being tempted to crib more than I should from the POSIX document, and I'm thinking we might want fall back to saying the SRFI's procedures are completely straightforward wrappers for these functions.  All of which take integers, even -1 for the -and- functions which means don't change that value, and all return 0 or -1 and errno.

See for yourself, setregid provides links to all of the other set functions.  Between the complexity, and as of yet unexplored by myself context of their being useful in the exec function context, pointing to their general man page documentation, and e.g. Stevens presumably and others who tell you how to use them all to do things securely, we'd be covered without trying to write some near essay level material for what are from the SRFI's viewpoint trivial wrappers.

And speaking of wrappers, I'm finding the Chibi Scheme automagic C FFI marvelous and ideal for a demonstration implementation of this SRFI, only failings of note so far are not being able to pass parameterized array sizes, e.g. for user-supplementary-gids, I'm currently doing

(define-c int (%getgroups getgroups) ((value 65537 int) (result (array gid_t 65537))))

which is the max for stock Bionic Beaver Linux ... when it's 17 for stock OpenBSD.  I do really need to make sure this huge immutable list of almost entirely garbage integers is GCed....

Plus an inability to pass an array of two timespec structs to set file times to nanosecond precision, the argument type (array (struct timespec) 2) doesn't do the right thing:

lib/srfi/170/170.c: In function ‘sexp_25_futimens_stub’:
lib/srfi/170/170.c:207:41: warning: passing argument 2 of ‘futimens’ from incompatible pointer type [-Wincompatible-pointer-types]
   err = futimens(sexp_sint_value(arg0), tmp1);
                                         ^~~~
In file included from include/chibi/sexp.h:93:0,
                 from include/chibi/eval.h:12,
                 from lib/srfi/170/170.c:3:
/usr/include/x86_64-linux-gnu/sys/stat.h:368:12: note: expected ‘const struct timespec *’ but argument is of type ‘struct timespec **’
extern int futimens (int __fd, const struct timespec __times[2]) __THROW;
            ^~~~~~~~

That's quite impressive for 59 working library or system call wrapper definitions so far, most written straight from the Linux and/or POSIX man page.  Oh, and this is the first time I've used an FFI....  All in all an extremely satisfying process, and the (chibi test) library is great.

- Harold