[systemd-commits] 2 commits - src/libsystemd-bus src/systemd
Lennart Poettering
lennart at kemper.freedesktop.org
Tue Nov 5 02:26:55 CET 2013
src/libsystemd-bus/bus-message.c | 182 ++++++++++++++++++++++++++++++----
src/libsystemd-bus/test-bus-marshal.c | 30 +++++
src/systemd/sd-bus.h | 1
3 files changed, 195 insertions(+), 18 deletions(-)
New commits:
commit 9b07511d658fa367f71de9f55fb60c37f0f596ad
Author: Lennart Poettering <lennart at poettering.net>
Date: Tue Nov 5 02:25:24 2013 +0100
bus: add sd_bus_message_skip() to skip over multiple fields
diff --git a/src/libsystemd-bus/bus-message.c b/src/libsystemd-bus/bus-message.c
index 8cf273c..78adf11 100644
--- a/src/libsystemd-bus/bus-message.c
+++ b/src/libsystemd-bus/bus-message.c
@@ -3324,7 +3324,6 @@ static int message_read_ap(
r = sd_bus_message_read_basic(m, *t, p);
if (r < 0)
return r;
-
if (r == 0) {
if (n_loop <= 1)
return 0;
@@ -3453,12 +3452,9 @@ int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
va_list ap;
int r;
- if (!m)
- return -EINVAL;
- if (!m->sealed)
- return -EPERM;
- if (!types)
- return -EINVAL;
+ assert_return(m, -EINVAL);
+ assert_return(m->sealed, -EPERM);
+ assert_return(types, -EINVAL);
va_start(ap, types);
r = message_read_ap(m, types, ap);
@@ -3467,6 +3463,148 @@ int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
return r;
}
+int sd_bus_message_skip(sd_bus_message *m, const char *types) {
+ int r;
+
+ assert_return(m, -EINVAL);
+ assert_return(m->sealed, -EPERM);
+ assert_return(types, -EINVAL);
+
+ if (isempty(types))
+ return 0;
+
+ switch (*types) {
+
+ case SD_BUS_TYPE_BYTE:
+ case SD_BUS_TYPE_BOOLEAN:
+ case SD_BUS_TYPE_INT16:
+ case SD_BUS_TYPE_UINT16:
+ case SD_BUS_TYPE_INT32:
+ case SD_BUS_TYPE_UINT32:
+ case SD_BUS_TYPE_INT64:
+ case SD_BUS_TYPE_UINT64:
+ case SD_BUS_TYPE_DOUBLE:
+ case SD_BUS_TYPE_STRING:
+ case SD_BUS_TYPE_OBJECT_PATH:
+ case SD_BUS_TYPE_SIGNATURE:
+ case SD_BUS_TYPE_UNIX_FD:
+
+ r = sd_bus_message_read_basic(m, *types, NULL);
+ if (r <= 0)
+ return r;
+
+ r = sd_bus_message_skip(m, types + 1);
+ if (r < 0)
+ return r;
+
+ return 1;
+
+ case SD_BUS_TYPE_ARRAY: {
+ size_t k;
+
+ r = signature_element_length(types + 1, &k);
+ if (r < 0)
+ return r;
+
+ {
+ char s[k+1];
+ memcpy(s, types+1, k);
+ s[k] = 0;
+
+ r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
+ if (r <= 0)
+ return r;
+
+ for (;;) {
+ r = sd_bus_message_skip(m, s);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ break;
+ }
+
+ r = sd_bus_message_exit_container(m);
+ if (r < 0)
+ return r;
+ }
+
+ r = sd_bus_message_skip(m, types + 1 + k);
+ if (r < 0)
+ return r;
+
+ return 1;
+ }
+
+ case SD_BUS_TYPE_VARIANT: {
+ const char *contents;
+ char x;
+
+ r = sd_bus_message_peek_type(m, &x, &contents);
+ if (r <= 0)
+ return r;
+
+ if (x != SD_BUS_TYPE_VARIANT)
+ return -ENXIO;
+
+ r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, contents);
+ if (r <= 0)
+ return r;
+
+ r = sd_bus_message_skip(m, contents);
+ if (r < 0)
+ return r;
+ assert(r != 0);
+
+ r = sd_bus_message_exit_container(m);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_skip(m, types + 1);
+ if (r < 0)
+ return r;
+
+ return 1;
+ }
+
+ case SD_BUS_TYPE_STRUCT_BEGIN:
+ case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
+ size_t k;
+
+ r = signature_element_length(types, &k);
+ if (r < 0)
+ return r;
+
+ {
+ char s[k-1];
+ memcpy(s, types+1, k-2);
+ s[k-2] = 0;
+
+ r = sd_bus_message_enter_container(m, *types == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
+ if (r <= 0)
+ return r;
+
+ r = sd_bus_message_skip(m, s);
+ if (r < 0)
+ return r;
+ assert(r != 0);
+
+ r = sd_bus_message_exit_container(m);
+ if (r < 0)
+ return r;
+ }
+
+ r = sd_bus_message_skip(m, types + k);
+ if (r < 0)
+ return r;
+
+ return 1;
+ }
+
+ default:
+ return -EINVAL;
+ }
+}
+
int sd_bus_message_read_array(sd_bus_message *m, char type, const void **ptr, size_t *size) {
struct bus_container *c;
void *p;
diff --git a/src/libsystemd-bus/test-bus-marshal.c b/src/libsystemd-bus/test-bus-marshal.c
index baa269c..8f27089 100644
--- a/src/libsystemd-bus/test-bus-marshal.c
+++ b/src/libsystemd-bus/test-bus-marshal.c
@@ -232,5 +232,35 @@ int main(int argc, char *argv[]) {
assert_se(first_size == third_size);
assert_se(memcmp(first, third, third_size) == 0);
+ r = sd_bus_message_rewind(m, true);
+ assert_se(r >= 0);
+
+ assert_se(sd_bus_message_verify_type(m, 's', NULL) > 0);
+
+ r = sd_bus_message_skip(m, "sas");
+ assert_se(r > 0);
+
+ assert_se(sd_bus_message_verify_type(m, 's', NULL) > 0);
+
+ r = sd_bus_message_skip(m, "sass");
+ assert_se(r >= 0);
+
+ assert_se(sd_bus_message_verify_type(m, 'a', "{yv}") > 0);
+
+ r = sd_bus_message_skip(m, "a{yv}");
+ assert_se(r >= 0);
+
+ assert_se(sd_bus_message_verify_type(m, 'b', NULL) > 0);
+
+ r = sd_bus_message_read(m, "ba(ss)", &boolean, 3, &x, &y, &a, &b, &c, &d);
+ assert_se(r > 0);
+ assert_se(boolean);
+ assert_se(streq(x, "aaa"));
+ assert_se(streq(y, "1"));
+ assert_se(streq(a, "bbb"));
+ assert_se(streq(b, "2"));
+ assert_se(streq(c, "ccc"));
+ assert_se(streq(d, "3"));
+
return 0;
}
diff --git a/src/systemd/sd-bus.h b/src/systemd/sd-bus.h
index affd309..e0a6041 100644
--- a/src/systemd/sd-bus.h
+++ b/src/systemd/sd-bus.h
@@ -197,6 +197,7 @@ int sd_bus_message_copy(sd_bus_message *m, sd_bus_message *source, int all);
int sd_bus_message_read(sd_bus_message *m, const char *types, ...);
int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p);
int sd_bus_message_read_array(sd_bus_message *m, char type, const void **ptr, size_t *size);
+int sd_bus_message_skip(sd_bus_message *m, const char *types);
int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents);
int sd_bus_message_exit_container(sd_bus_message *m);
int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents);
commit 0dcd14b940e4a6c9904e11952c8a98e9152938f3
Author: Lennart Poettering <lennart at poettering.net>
Date: Tue Nov 5 02:24:53 2013 +0100
bus: allow that if the destination pointer in sd_bus_message_read_basic() is NULL we skip over a field
diff --git a/src/libsystemd-bus/bus-message.c b/src/libsystemd-bus/bus-message.c
index bd0079d..8cf273c 100644
--- a/src/libsystemd-bus/bus-message.c
+++ b/src/libsystemd-bus/bus-message.c
@@ -2642,8 +2642,8 @@ static bool validate_object_path(const char *s, size_t l) {
int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
struct bus_container *c;
- int r;
void *q;
+ int r;
if (!m)
return -EINVAL;
@@ -2651,8 +2651,6 @@ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
return -EPERM;
if (!bus_type_is_basic(type))
return -EINVAL;
- if (!p)
- return -EINVAL;
c = message_get_container(m);
@@ -2693,7 +2691,9 @@ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
}
m->rindex = rindex;
- *(const char**) p = q;
+ if (p)
+ *(const char**) p = q;
+
break;
}
@@ -2717,7 +2717,9 @@ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
return -EBADMSG;
m->rindex = rindex;
- *(const char**) p = q;
+
+ if (p)
+ *(const char**) p = q;
break;
}
@@ -2737,27 +2739,32 @@ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
switch (type) {
case SD_BUS_TYPE_BYTE:
- *(uint8_t*) p = *(uint8_t*) q;
+ if (p)
+ *(uint8_t*) p = *(uint8_t*) q;
break;
case SD_BUS_TYPE_BOOLEAN:
- *(unsigned*) p = !!*(uint32_t*) q;
+ if (p)
+ *(unsigned*) p = !!*(uint32_t*) q;
break;
case SD_BUS_TYPE_INT16:
case SD_BUS_TYPE_UINT16:
- *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
+ if (p)
+ *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
break;
case SD_BUS_TYPE_INT32:
case SD_BUS_TYPE_UINT32:
- *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
+ if (p)
+ *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
break;
case SD_BUS_TYPE_INT64:
case SD_BUS_TYPE_UINT64:
case SD_BUS_TYPE_DOUBLE:
- *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
+ if (p)
+ *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
break;
case SD_BUS_TYPE_UNIX_FD: {
@@ -2767,7 +2774,8 @@ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
if (j >= m->n_fds)
return -EBADMSG;
- *(int*) p = m->fds[j];
+ if (p)
+ *(int*) p = m->fds[j];
break;
}
More information about the systemd-commits
mailing list