From: Lennart Poettering Date: Tue, 9 Feb 2021 15:36:07 +0000 (+0100) Subject: format-table: make UID/GID/PID fields first class citizens + add signal cell type X-Git-Tag: v248-rc1~171^2~4 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=a7273eaf32e9d0f8abe5f368bdd801803aaaa0ec;p=thirdparty%2Fsystemd.git format-table: make UID/GID/PID fields first class citizens + add signal cell type 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. --- diff --git a/src/shared/format-table.c b/src/shared/format-table.c index e3d8a051a22..92f82dd5b25 100644 --- a/src/shared/format-table.c +++ b/src/shared/format-table.c @@ -20,11 +20,14 @@ #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; } diff --git a/src/shared/format-table.h b/src/shared/format-table.h index 6627a291f34..732abf27ec6 100644 --- a/src/shared/format-table.h +++ b/src/shared/format-table.h @@ -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;