From: Lennart Poettering Date: Wed, 15 Jun 2011 13:31:54 +0000 (+0200) Subject: dbus: introduce UnsetAndSetEnvironment() X-Git-Tag: v30~174 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8d0e38a2b966799af884e78a54fd6a2dffa44788;p=systemd dbus: introduce UnsetAndSetEnvironment() --- diff --git a/TODO b/TODO index 8e43b382..71ad0777 100644 --- a/TODO +++ b/TODO @@ -27,6 +27,10 @@ Features: * kernel: add device_type = "fb", "fbcon" to class "graphics" +* hostnamed: make file updates atomic + +* support sd_notify() style notificatio when reload is finished (RELOADED=1) + * verify that the AF_UNIX sockets of a service in the fs still exist when we start a service in order to avoid confusion when a user assumes starting a service is enough to make it accessible @@ -46,8 +50,6 @@ Features: * move /selinux to /sys/fs/selinux -* unset cgroup agents on shutdown - * add prefix match to sysctl, tmpfiles, ... * send out "finished" signal when we are finished booting @@ -154,8 +156,6 @@ Features: * Support --test based on current system state -* systemctl enable as D-Bus call - * consider services with any kind of link in /etc/systemd/system enabled * show failure error string in "systemctl status" diff --git a/src/dbus-common.c b/src/dbus-common.c index cb43bbdd..e439a424 100644 --- a/src/dbus-common.c +++ b/src/dbus-common.c @@ -737,3 +737,62 @@ unsigned bus_events_to_flags(uint32_t events) { return flags; } + +int bus_parse_strv(DBusMessage *m, char ***_l) { + DBusMessageIter iter; + + assert(m); + assert(_l); + + if (!dbus_message_iter_init(m, &iter)) + return -EINVAL; + + return bus_parse_strv_iter(&iter, _l); +} + +int bus_parse_strv_iter(DBusMessageIter *iter, char ***_l) { + DBusMessageIter sub; + unsigned n = 0, i = 0; + char **l; + + assert(iter); + assert(_l); + + if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(iter) != DBUS_TYPE_STRING) + return -EINVAL; + + dbus_message_iter_recurse(iter, &sub); + + while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { + n++; + dbus_message_iter_next(&sub); + } + + if (!(l = new(char*, n+1))) + return -ENOMEM; + + dbus_message_iter_recurse(iter, &sub); + + while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { + const char *s; + + assert_se(dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING); + dbus_message_iter_get_basic(&sub, &s); + + if (!(l[i++] = strdup(s))) { + strv_free(l); + return -ENOMEM; + } + + dbus_message_iter_next(&sub); + } + + assert(i == n); + l[i] = NULL; + + if (_l) + *_l = l; + + return 0; +} diff --git a/src/dbus-common.h b/src/dbus-common.h index e321a2c8..9368f751 100644 --- a/src/dbus-common.h +++ b/src/dbus-common.h @@ -158,4 +158,7 @@ DBusMessage* bus_properties_changed_new(const char *path, const char *interface, uint32_t bus_flags_to_events(DBusWatch *bus_watch); unsigned bus_events_to_flags(uint32_t events); +int bus_parse_strv(DBusMessage *m, char ***_l); +int bus_parse_strv_iter(DBusMessageIter *iter, char ***_l); + #endif diff --git a/src/dbus-manager.c b/src/dbus-manager.c index 797e53d1..cc2b4d01 100644 --- a/src/dbus-manager.c +++ b/src/dbus-manager.c @@ -128,6 +128,10 @@ " \n" \ " \n" \ " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ " \n" #define BUS_MANAGER_INTERFACE_SIGNALS \ @@ -1035,6 +1039,58 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, strv_free(m->environment); m->environment = e; + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "UnsetAndSetEnvironment")) { + char **l_set = NULL, **l_unset = NULL, **e = NULL, **f = NULL; + DBusMessageIter iter; + + if (!dbus_message_iter_init(message, &iter)) + return bus_send_error_reply(connection, message, NULL, -EINVAL); + + r = bus_parse_strv_iter(&iter, &l_unset); + if (r < 0) { + if (r == -ENOMEM) + goto oom; + + return bus_send_error_reply(connection, message, NULL, r); + } + + if (!dbus_message_iter_next(&iter)) { + strv_free(l_unset); + return bus_send_error_reply(connection, message, NULL, -EINVAL); + } + + r = bus_parse_strv_iter(&iter, &l_set); + if (r < 0) { + strv_free(l_unset); + if (r == -ENOMEM) + goto oom; + + return bus_send_error_reply(connection, message, NULL, r); + } + + e = strv_env_delete(m->environment, 1, l_unset); + strv_free(l_unset); + + if (!e) { + strv_free(l_set); + goto oom; + } + + f = strv_env_merge(2, e, l_set); + strv_free(l_set); + strv_free(e); + + if (!f) + goto oom; + + if (!(reply = dbus_message_new_method_return(message))) { + strv_free(f); + goto oom; + } + + strv_free(m->environment); + m->environment = f; + } else return bus_default_message_handler(connection, message, NULL, INTERFACES_LIST, properties); diff --git a/src/dbus.c b/src/dbus.c index e153c35a..2a379a2b 100644 --- a/src/dbus.c +++ b/src/dbus.c @@ -1212,55 +1212,6 @@ int bus_broadcast(Manager *m, DBusMessage *message) { return oom ? -ENOMEM : 0; } -int bus_parse_strv(DBusMessage *m, char ***_l) { - DBusMessageIter iter, sub; - unsigned n = 0, i = 0; - char **l; - - assert(m); - assert(_l); - - if (!dbus_message_iter_init(m, &iter) || - dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY || - dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRING) - return -EINVAL; - - dbus_message_iter_recurse(&iter, &sub); - - while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { - n++; - dbus_message_iter_next(&sub); - } - - if (!(l = new(char*, n+1))) - return -ENOMEM; - - assert_se(dbus_message_iter_init(m, &iter)); - dbus_message_iter_recurse(&iter, &sub); - - while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { - const char *s; - - assert_se(dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING); - dbus_message_iter_get_basic(&sub, &s); - - if (!(l[i++] = strdup(s))) { - strv_free(l); - return -ENOMEM; - } - - dbus_message_iter_next(&sub); - } - - assert(i == n); - l[i] = NULL; - - if (_l) - *_l = l; - - return 0; -} - bool bus_has_subscriber(Manager *m) { Iterator i; DBusConnection *c; diff --git a/src/dbus.h b/src/dbus.h index 8387ffaa..c47e7826 100644 --- a/src/dbus.h +++ b/src/dbus.h @@ -38,8 +38,6 @@ int bus_query_pid(Manager *m, const char *name); int bus_broadcast(Manager *m, DBusMessage *message); -int bus_parse_strv(DBusMessage *m, char ***_l); - bool bus_has_subscriber(Manager *m); bool bus_connection_has_subscriber(Manager *m, DBusConnection *c); diff --git a/src/service.c b/src/service.c index 1f748688..62027f3a 100644 --- a/src/service.c +++ b/src/service.c @@ -280,10 +280,10 @@ static int sysv_translate_facility(const char *name, const char *filename, char /* LSB defined facilities */ "local_fs", SPECIAL_LOCAL_FS_TARGET, #ifndef TARGET_MANDRIVA - /* Due to unfortunate name selection in Mandriva, - * $network is provided by network-up which is ordered - * after network which actually starts interfaces. - * To break the loop, just ignore it */ + /* Due to unfortunate name selection in Mandriva, + * $network is provided by network-up which is ordered + * after network which actually starts interfaces. + * To break the loop, just ignore it */ "network", SPECIAL_NETWORK_TARGET, #endif "named", SPECIAL_NSS_LOOKUP_TARGET, diff --git a/src/util.c b/src/util.c index b291e2f7..81d247ca 100644 --- a/src/util.c +++ b/src/util.c @@ -4692,6 +4692,7 @@ int conf_files_list(char ***strv, const char *suffix, const char *dir, ...) { } qsort(files, hashmap_size(fh), sizeof(char *), base_cmp); + finish: strv_free(dirs); hashmap_free(fh);