X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Futil.c;h=e93e6f6cf5c962e90ac7b8a4a29cc8cfe00a80ce;hb=d68af58657ce0e99594dff199fbb9b319cf6af96;hp=e46606dabb39551e0b0b5b3df5a39ef311ee861b;hpb=678abaf91e2308f02fb679c2dc2679a3b6a5b8be;p=elogind.git diff --git a/src/util.c b/src/util.c index e46606dab..e93e6f6cf 100644 --- a/src/util.c +++ b/src/util.c @@ -5703,3 +5703,36 @@ int strdup_or_null(const char *a, char **b) { *b = c; return 0; } + +unsigned long cap_last_cap(void) { + static __thread unsigned long saved; + static __thread bool valid = false; + unsigned long p; + + if (valid) + return saved; + + p = (unsigned long) CAP_LAST_CAP; + + if (prctl(PR_CAPBSET_READ, p) < 0) { + + /* Hmm, look downwards, until we find one that + * works */ + for (p--; p > 0; p --) + if (prctl(PR_CAPBSET_READ, p) >= 0) + break; + + } else { + + /* Hmm, look upwards, until we find one that doesn't + * work */ + for (;; p++) + if (prctl(PR_CAPBSET_READ, p+1) < 0) + break; + } + + saved = p; + valid = true; + + return p; +}