mirror of
https://github.com/troglobit/finit.git
synced 2026-11-03 13:28:27 +00:00
initctl: the status views over D-Bus
The summary table, the per-service detail, JSON and the quiet and ident forms all read state Finit already publishes, so they read it from the bus like everything else rather than through a second path that has to be kept in step. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
1 parent
ebc0ef62e6
commit
6310d9e760
16 files changed
+1271
-315
No files matched your search
@@ -333,6 +333,7 @@ static int handle_properties_get(link_connection_t *conn, const struct link_msg
|
||||
if (!p->getter)
|
||||
break;
|
||||
__w_init(&w, conn->txbuf, sizeof(conn->txbuf));
|
||||
__w_sig(&w, p->sig ? p->sig : "s");
|
||||
if (p->getter(&w, e->userdata) != 0 || (blen = __w_finish(&w)) < 0)
|
||||
return __send_error(conn, m,
|
||||
"org.freedesktop.DBus.Error.Failed",
|
||||
@@ -380,6 +381,7 @@ static int handle_properties_get_all(link_connection_t *conn, const struct link_
|
||||
continue;
|
||||
__w_struct_begin(&w);
|
||||
__w_string(&w, p->name);
|
||||
__w_sig(&w, p->sig ? p->sig : "s");
|
||||
if (p->getter(&w, e->userdata) != 0)
|
||||
return __send_error(conn, m,
|
||||
"org.freedesktop.DBus.Error.Failed",
|
||||
|
||||
@@ -312,6 +312,8 @@ int link_r_bool (link_reader_t *r, int *o) { return __r_bool (r, o);
|
||||
int link_r_u32 (link_reader_t *r, uint32_t *o) { return __r_u32 (r, o); }
|
||||
int link_r_string(link_reader_t *r, const char **o) { return __r_string(r, o); }
|
||||
int link_r_path (link_reader_t *r, const char **o) { return __r_path (r, o); }
|
||||
int link_r_variant_begin (link_reader_t *r, char *type) { return __r_variant_begin(r, type); }
|
||||
int link_r_skip_basic (link_reader_t *r, char type) { return __r_skip_basic(r, type); }
|
||||
int link_r_variant_string(link_reader_t *r, const char **o) { return __r_variant_string(r, o); }
|
||||
int link_r_align (link_reader_t *r, size_t n) { return __r_align (r, n); }
|
||||
int link_r_array_begin(link_reader_t *r, size_t *e) { return __r_array_begin(r, e); }
|
||||
|
||||
+7
-3
@@ -129,9 +129,11 @@ typedef struct {
|
||||
} link_method_t;
|
||||
|
||||
/* A read-only property descriptor. Set via the Properties.Set side
|
||||
* is not yet implemented; only Get and GetAll are. The getter writes
|
||||
* the property's value as a D-Bus variant (use link_w_variant_string
|
||||
* for "s"-typed properties) into the provided writer. */
|
||||
* is not yet implemented; only Get and GetAll are. The framework
|
||||
* emits the variant signature from `sig`; the getter writes only the
|
||||
* bare value into the provided writer (link_w_string for "s",
|
||||
* link_w_u32 for "u", ...), so the declared type is the single
|
||||
* source of truth. */
|
||||
typedef int (*link_property_getter_fn)(link_writer_t *w, void *userdata);
|
||||
|
||||
typedef struct {
|
||||
@@ -329,6 +331,8 @@ int link_r_bool (link_reader_t *r, int *out);
|
||||
int link_r_u32 (link_reader_t *r, uint32_t *out);
|
||||
int link_r_string (link_reader_t *r, const char **out); /* "s" */
|
||||
int link_r_path (link_reader_t *r, const char **out); /* "o" */
|
||||
int link_r_variant_begin (link_reader_t *r, char *type); /* sig header, cursor at value */
|
||||
int link_r_skip_basic (link_reader_t *r, char type); /* skip one basic value */
|
||||
int link_r_variant_string(link_reader_t *r, const char **out); /* "v" containing "s" */
|
||||
int link_r_align (link_reader_t *r, size_t n); /* skip to next n-byte boundary */
|
||||
int link_r_done (const link_reader_t *r);
|
||||
|
||||
+73
-16
@@ -110,6 +110,7 @@ void __w_variant_string(struct link_writer *w, const char *s)
|
||||
__w_string(w, s);
|
||||
}
|
||||
|
||||
|
||||
static size_t element_align(char c)
|
||||
{
|
||||
switch (c) {
|
||||
@@ -262,32 +263,88 @@ static int read_string_like(struct link_reader *r, const char **out)
|
||||
int __r_string(struct link_reader *r, const char **out) { return read_string_like(r, out); }
|
||||
int __r_path (struct link_reader *r, const char **out) { return read_string_like(r, out); }
|
||||
|
||||
/*
|
||||
* Parse a variant's signature header, i.e. "g" wire form: 1-byte
|
||||
* length, bytes, NUL. Only single-character inner signatures are
|
||||
* supported. On success the cursor sits at the value and the type
|
||||
* code is returned in *type.
|
||||
*/
|
||||
int __r_variant_begin(struct link_reader *r, char *type)
|
||||
{
|
||||
uint8_t sig_len;
|
||||
|
||||
if (r_skip_align(r, 1) < 0 || r->off + 1 > r->cap)
|
||||
goto fail;
|
||||
sig_len = r->base[r->off++];
|
||||
if (sig_len != 1 || r->off + 2 > r->cap)
|
||||
goto fail;
|
||||
if (r->base[r->off + 1] != 0)
|
||||
goto fail;
|
||||
*type = (char)r->base[r->off];
|
||||
r->off += 2;
|
||||
return 0;
|
||||
fail:
|
||||
r->err = 1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Read a variant "v" expected to contain a string. Fails if the
|
||||
* inner signature is anything other than "s" (returns -1, *out set
|
||||
* to NULL). */
|
||||
int __r_variant_string(struct link_reader *r, const char **out)
|
||||
{
|
||||
uint8_t sig_len;
|
||||
uint32_t slen;
|
||||
char type;
|
||||
|
||||
*out = NULL;
|
||||
|
||||
/* signature is "g" wire form: 1-byte length, bytes, NUL */
|
||||
if (r_skip_align(r, 1) < 0 || r->off + 1 > r->cap) { r->err = 1; return -1; }
|
||||
sig_len = r->base[r->off++];
|
||||
if (sig_len != 1 || r->off + 2 > r->cap) { r->err = 1; return -1; }
|
||||
if (r->base[r->off] != 's' || r->base[r->off + 1] != 0) { r->err = 1; return -1; }
|
||||
r->off += 2;
|
||||
|
||||
/* now a normal string */
|
||||
if (__r_u32(r, &slen) < 0) return -1;
|
||||
if (r->off + (size_t)slen + 1 > r->cap || r->base[r->off + slen] != 0) {
|
||||
if (__r_variant_begin(r, &type) < 0)
|
||||
return -1;
|
||||
if (type != 's') {
|
||||
r->err = 1;
|
||||
return -1;
|
||||
}
|
||||
*out = (const char *)(r->base + r->off);
|
||||
r->off += (size_t)slen + 1;
|
||||
return 0;
|
||||
return read_string_like(r, out);
|
||||
}
|
||||
|
||||
/*
|
||||
* Skip one basic value of the given type code, as returned by
|
||||
* __r_variant_begin(). Lets a{sv} consumers tolerate value types
|
||||
* they don't know. Returns -1 on non-basic types.
|
||||
*/
|
||||
int __r_skip_basic(struct link_reader *r, char type)
|
||||
{
|
||||
const char *s;
|
||||
uint32_t u;
|
||||
uint8_t y;
|
||||
|
||||
switch (type) {
|
||||
case 's':
|
||||
case 'o':
|
||||
return read_string_like(r, &s);
|
||||
case 'b':
|
||||
case 'u':
|
||||
case 'i':
|
||||
return __r_u32(r, &u);
|
||||
case 'y':
|
||||
return __r_byte(r, &y);
|
||||
default:
|
||||
r->err = 1;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Read a variant "v" expected to contain a uint32. */
|
||||
int __r_variant_u32(struct link_reader *r, uint32_t *out)
|
||||
{
|
||||
char type;
|
||||
|
||||
if (__r_variant_begin(r, &type) < 0)
|
||||
return -1;
|
||||
if (type != 'u') {
|
||||
r->err = 1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return __r_u32(r, out);
|
||||
}
|
||||
|
||||
int __r_done(const struct link_reader *r)
|
||||
|
||||
@@ -44,7 +44,10 @@ int __r_bool (struct link_reader *r, int *out);
|
||||
int __r_u32 (struct link_reader *r, uint32_t *out);
|
||||
int __r_string(struct link_reader *r, const char **out); /* "s" */
|
||||
int __r_path (struct link_reader *r, const char **out); /* "o" */
|
||||
int __r_variant_begin (struct link_reader *r, char *type); /* sig header, cursor at value */
|
||||
int __r_skip_basic (struct link_reader *r, char type); /* skip one basic value */
|
||||
int __r_variant_string(struct link_reader *r, const char **out); /* "v" containing "s" */
|
||||
int __r_variant_u32 (struct link_reader *r, uint32_t *out); /* "v" containing "u" */
|
||||
int __r_align (struct link_reader *r, size_t n); /* skip to n-byte boundary */
|
||||
int __r_array_begin(struct link_reader *r, size_t *out_end);
|
||||
int __r_done (const struct link_reader *r);
|
||||
|
||||
Reference in new issue
Block a user