]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
format-table: make UID/GID/PID fields first class citizens + add signal cell type
authorLennart Poettering <lennart@poettering.net>
Tue, 9 Feb 2021 15:36:07 +0000 (16:36 +0100)
committerLennart Poettering <lennart@poettering.net>
Wed, 10 Feb 2021 11:21:17 +0000 (12:21 +0100)
This way we can display invalid UIDs/GIDs/PIDs as n/a while still
storing them as is.

Also, let's add a new cell type for unix signal, that is stored as
integer, but displayed as signal name string.

src/shared/format-table.c
src/shared/format-table.h

index e3d8a051a22824e836f36524e6c77ffce3720c77..92f82dd5b251198d7861f4c09408940a5252393f 100644 (file)
 #include "parse-util.h"
 #include "path-util.h"
 #include "pretty-print.h"
+#include "process-util.h"
+#include "signal-util.h"
 #include "sort-util.h"
 #include "string-util.h"
 #include "strxcpyx.h"
 #include "terminal-util.h"
 #include "time-util.h"
+#include "user-util.h"
 #include "utf8.h"
 #include "util.h"
 
@@ -100,6 +103,9 @@ typedef struct TableData {
                 int ifindex;
                 union in_addr_union address;
                 sd_id128_t id128;
+                uid_t uid;
+                gid_t gid;
+                pid_t pid;
                 /* … add more here as we start supporting more cell data types … */
         };
 } TableData;
@@ -284,6 +290,7 @@ static size_t table_data_size(TableDataType type, const void *data) {
         case TABLE_UINT:
         case TABLE_PERCENT:
         case TABLE_IFINDEX:
+        case TABLE_SIGNAL:
                 return sizeof(int);
 
         case TABLE_IN_ADDR:
@@ -296,6 +303,13 @@ static size_t table_data_size(TableDataType type, const void *data) {
         case TABLE_ID128:
                 return sizeof(sd_id128_t);
 
+        case TABLE_UID:
+                return sizeof(uid_t);
+        case TABLE_GID:
+                return sizeof(gid_t);
+        case TABLE_PID:
+                return sizeof(pid_t);
+
         default:
                 assert_not_reached("Uh? Unexpected cell type");
         }
@@ -801,6 +815,9 @@ int table_add_many_internal(Table *t, TableDataType first_type, ...) {
                         bool b;
                         union in_addr_union address;
                         sd_id128_t id128;
+                        uid_t uid;
+                        gid_t gid;
+                        pid_t pid;
                 } buffer;
 
                 switch (type) {
@@ -840,6 +857,7 @@ int table_add_many_internal(Table *t, TableDataType first_type, ...) {
                         break;
 
                 case TABLE_INT:
+                case TABLE_SIGNAL:
                         buffer.int_val = va_arg(ap, int);
                         data = &buffer.int_val;
                         break;
@@ -931,6 +949,21 @@ int table_add_many_internal(Table *t, TableDataType first_type, ...) {
                         data = &buffer.id128;
                         break;
 
+                case TABLE_UID:
+                        buffer.uid = va_arg(ap, uid_t);
+                        data = &buffer.uid;
+                        break;
+
+                case TABLE_GID:
+                        buffer.gid = va_arg(ap, gid_t);
+                        data = &buffer.gid;
+                        break;
+
+                case TABLE_PID:
+                        buffer.pid = va_arg(ap, pid_t);
+                        data = &buffer.pid;
+                        break;
+
                 case TABLE_SET_MINIMUM_WIDTH: {
                         size_t w = va_arg(ap, size_t);
 
@@ -1189,6 +1222,7 @@ static int cell_data_compare(TableData *a, size_t index_a, TableData *b, size_t
                         return CMP(a->size, b->size);
 
                 case TABLE_INT:
+                case TABLE_SIGNAL:
                         return CMP(a->int_val, b->int_val);
 
                 case TABLE_INT8:
@@ -1234,6 +1268,15 @@ static int cell_data_compare(TableData *a, size_t index_a, TableData *b, size_t
                 case TABLE_ID128:
                         return memcmp(&a->id128, &b->id128, sizeof(sd_id128_t));
 
+                case TABLE_UID:
+                        return CMP(a->uid, b->uid);
+
+                case TABLE_GID:
+                        return CMP(a->gid, b->gid);
+
+                case TABLE_PID:
+                        return CMP(a->pid, b->pid);
+
                 default:
                         ;
                 }
@@ -1618,6 +1661,67 @@ static const char *table_data_format(Table *t, TableData *d, bool avoid_uppercas
                 break;
         }
 
+        case TABLE_UID: {
+                _cleanup_free_ char *p = NULL;
+
+                if (!uid_is_valid(d->uid))
+                        return "n/a";
+
+                p = new(char, DECIMAL_STR_WIDTH(d->uid) + 1);
+                if (!p)
+                        return NULL;
+
+                sprintf(p, UID_FMT, d->uid);
+                d->formatted = TAKE_PTR(p);
+                break;
+        }
+
+        case TABLE_GID: {
+                _cleanup_free_ char *p = NULL;
+
+                if (!gid_is_valid(d->gid))
+                        return "n/a";
+
+                p = new(char, DECIMAL_STR_WIDTH(d->gid) + 1);
+                if (!p)
+                        return NULL;
+
+                sprintf(p, GID_FMT, d->gid);
+                d->formatted = TAKE_PTR(p);
+                break;
+        }
+
+        case TABLE_PID: {
+                _cleanup_free_ char *p = NULL;
+
+                if (!pid_is_valid(d->pid))
+                        return "n/a";
+
+                p = new(char, DECIMAL_STR_WIDTH(d->pid) + 1);
+                if (!p)
+                        return NULL;
+
+                sprintf(p, PID_FMT, d->pid);
+                d->formatted = TAKE_PTR(p);
+                break;
+        }
+
+        case TABLE_SIGNAL: {
+                _cleanup_free_ char *p = NULL;
+                const char *suffix;
+
+                suffix = signal_to_string(d->int_val);
+                if (!suffix)
+                        return "n/a";
+
+                p = strjoin("SIG", suffix);
+                if (!p)
+                        return NULL;
+
+                d->formatted = TAKE_PTR(p);
+                break;
+        }
+
         default:
                 assert_not_reached("Unexpected type?");
         }
@@ -2392,6 +2496,30 @@ static int table_data_to_json(TableData *d, JsonVariant **ret) {
                 return json_variant_new_string(ret, id128_to_uuid_string(d->id128, buf));
         }
 
+        case TABLE_UID:
+                if (!uid_is_valid(d->uid))
+                        return json_variant_new_null(ret);
+
+                return json_variant_new_integer(ret, d->uid);
+
+        case TABLE_GID:
+                if (!gid_is_valid(d->gid))
+                        return json_variant_new_null(ret);
+
+                return json_variant_new_integer(ret, d->gid);
+
+        case TABLE_PID:
+                if (!pid_is_valid(d->pid))
+                        return json_variant_new_null(ret);
+
+                return json_variant_new_integer(ret, d->pid);
+
+        case TABLE_SIGNAL:
+                if (!SIGNAL_VALID(d->int_val))
+                        return json_variant_new_null(ret);
+
+                return json_variant_new_integer(ret, d->int_val);
+
         default:
                 return -EINVAL;
         }
index 6627a291f3452e14864f90cd7fa6a701c52efd56..732abf27ec66901a85ed221c2a9575c9fde35539 100644 (file)
@@ -39,6 +39,10 @@ typedef enum TableDataType {
         TABLE_IN6_ADDR, /* Takes a union in_addr_union (or a struct in6_addr) */
         TABLE_ID128,
         TABLE_UUID,
+        TABLE_UID,
+        TABLE_GID,
+        TABLE_PID,
+        TABLE_SIGNAL,
         _TABLE_DATA_TYPE_MAX,
 
         /* The following are not really data types, but commands for table_add_cell_many() to make changes to
@@ -57,16 +61,6 @@ typedef enum TableDataType {
         _TABLE_DATA_TYPE_INVALID = -1,
 } TableDataType;
 
-/* PIDs are just 32bit signed integers on Linux */
-#define TABLE_PID TABLE_INT32
-assert_cc(sizeof(pid_t) == sizeof(int32_t));
-
-/* UIDs/GIDs are just 32bit unsigned integers on Linux */
-#define TABLE_UID TABLE_UINT32
-#define TABLE_GID TABLE_UINT32
-assert_cc(sizeof(uid_t) == sizeof(uint32_t));
-assert_cc(sizeof(gid_t) == sizeof(uint32_t));
-
 typedef struct Table Table;
 typedef struct TableCell TableCell;