chiark / gitweb /
util: properly detect what the last capability is
[elogind.git] / src / util.c
index 425a732344f68fff89bd14ab91cf5d176bb819ec..e93e6f6cf5c962e90ac7b8a4a29cc8cfe00a80ce 100644 (file)
@@ -2307,8 +2307,10 @@ int chvt(int vt) {
                         0
                 };
 
-                if (ioctl(fd, TIOCLINUX, tiocl) < 0)
-                        return -errno;
+                if (ioctl(fd, TIOCLINUX, tiocl) < 0) {
+                        r = -errno;
+                        goto fail;
+                }
 
                 vt = tiocl[0] <= 0 ? 1 : tiocl[0];
         }
@@ -2316,7 +2318,8 @@ int chvt(int vt) {
         if (ioctl(fd, VT_ACTIVATE, vt) < 0)
                 r = -errno;
 
-        close_nointr_nofail(r);
+fail:
+        close_nointr_nofail(fd);
         return r;
 }
 
@@ -5682,3 +5685,54 @@ bool kexec_loaded(void) {
        }
        return loaded;
 }
+
+int strdup_or_null(const char *a, char **b) {
+        char *c;
+
+        assert(b);
+
+        if (!a) {
+                *b = NULL;
+                return 0;
+        }
+
+        c = strdup(a);
+        if (!c)
+                return -ENOMEM;
+
+        *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;
+}