bus-control.c revision f8c2425287c8362ae3a3c9acfb9e23a16862b38a
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering This file is part of systemd.
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering Copyright 2013 Lennart Poettering
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering systemd is free software; you can redistribute it and/or modify it
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering under the terms of the GNU Lesser General Public License as published by
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering (at your option) any later version.
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering systemd is distributed in the hope that it will be useful, but
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering Lesser General Public License for more details.
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering You should have received a copy of the GNU Lesser General Public License
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering_public_ int sd_bus_get_unique_name(sd_bus *bus, const char **unique) {
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering assert_return(!bus_pid_changed(bus), -ECHILD);
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poetteringstatic int bus_request_name_kernel(sd_bus *bus, const char *name, uint64_t flags) {
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering size = offsetof(struct kdbus_cmd_name, items) + KDBUS_ITEM_SIZE(l + 1);
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering kdbus_translate_request_name_flags(flags, (uint64_t *) &n->flags);
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering n->items[0].size = KDBUS_ITEM_HEADER_SIZE + l + 1;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering r = ioctl(bus->input_fd, KDBUS_CMD_NAME_ACQUIRE, n);
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poetteringstatic int bus_request_name_dbus1(sd_bus *bus, const char *name, uint64_t flags) {
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering if (flags & SD_BUS_NAME_ALLOW_REPLACEMENT)
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering if (flags & SD_BUS_NAME_REPLACE_EXISTING)
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering "org.freedesktop.DBus",
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering "org.freedesktop.DBus",
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering "RequestName",
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering r = sd_bus_message_read(reply, "u", &ret);
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering_public_ int sd_bus_request_name(sd_bus *bus, const char *name, uint64_t flags) {
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering assert_return(!bus_pid_changed(bus), -ECHILD);
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering assert_return(!(flags & ~(SD_BUS_NAME_ALLOW_REPLACEMENT|SD_BUS_NAME_REPLACE_EXISTING|SD_BUS_NAME_QUEUE)), -EINVAL);
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering assert_return(service_name_is_valid(name), -EINVAL);
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering return bus_request_name_kernel(bus, name, flags);
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering return bus_request_name_dbus1(bus, name, flags);
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poetteringstatic int bus_release_name_kernel(sd_bus *bus, const char *name) {
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering size = offsetof(struct kdbus_cmd_name, items) + KDBUS_ITEM_SIZE(l + 1);
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering n->items[0].size = KDBUS_ITEM_HEADER_SIZE + l + 1;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering r = ioctl(bus->input_fd, KDBUS_CMD_NAME_RELEASE, n);
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poetteringstatic int bus_release_name_dbus1(sd_bus *bus, const char *name) {
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering "org.freedesktop.DBus",
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering "org.freedesktop.DBus",
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering "ReleaseName",
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering r = sd_bus_message_read(reply, "u", &ret);
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering_public_ int sd_bus_release_name(sd_bus *bus, const char *name) {
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering assert_return(!bus_pid_changed(bus), -ECHILD);
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering assert_return(service_name_is_valid(name), -EINVAL);
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering return bus_release_name_kernel(bus, name);
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering return bus_release_name_dbus1(bus, name);
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poetteringstatic int kernel_get_list(sd_bus *bus, uint64_t flags, char ***x) {
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering /* Caller will free half-constructed list on failure... */
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering r = ioctl(bus->input_fd, KDBUS_CMD_NAME_LIST, &cmd);
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering name_list = (struct kdbus_name_list *) ((uint8_t *) bus->kdbus_buffer + cmd.offset);
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering KDBUS_ITEM_FOREACH(name, name_list, names) {
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering if ((flags & KDBUS_NAME_LIST_UNIQUE) && name->owner_id != previous_id) {
71dc3ed1d95dfe246004018c2ca85156fc73c146Lennart Poettering if (asprintf(&n, ":1.%llu", (unsigned long long) name->owner_id) < 0)
return -ENOMEM;
return -errno;
if (acquired) {
if (activatable) {
*activatable = y;
y = NULL;
if (acquired) {
*acquired = x;
x = NULL;
if (acquired) {
r = sd_bus_call_method(
bus,
"/org/freedesktop/DBus",
NULL,
&reply,
NULL);
if (activatable) {
r = sd_bus_call_method(
bus,
"/org/freedesktop/DBus",
NULL,
&reply,
NULL);
*activatable = y;
y = NULL;
if (acquired) {
*acquired = x;
x = NULL;
return -ENOTCONN;
static int bus_get_owner_kdbus(
const char *name,
return -errno;
c = bus_creds_new();
return -ENOMEM;
return -ENOMEM;
case KDBUS_ITEM_CREDS:
c->mask |= m;
case KDBUS_ITEM_PID_COMM:
if (!c->comm) {
r = -ENOMEM;
goto fail;
case KDBUS_ITEM_TID_COMM:
if (!c->tid_comm) {
r = -ENOMEM;
goto fail;
case KDBUS_ITEM_EXE:
if (!c->exe) {
r = -ENOMEM;
goto fail;
case KDBUS_ITEM_CMDLINE:
if (!c->cmdline) {
r = -ENOMEM;
goto fail;
case KDBUS_ITEM_CGROUP:
if (!c->cgroup) {
r = -ENOMEM;
goto fail;
goto fail;
if (!c->cgroup_root) {
r = -ENOMEM;
goto fail;
c->mask |= m;
case KDBUS_ITEM_CAPS:
if (!c->capability) {
r = -ENOMEM;
goto fail;
c->mask |= m;
case KDBUS_ITEM_SECLABEL:
if (!c->label) {
r = -ENOMEM;
goto fail;
case KDBUS_ITEM_AUDIT:
c->mask |= m;
case KDBUS_ITEM_NAME:
goto fail;
case KDBUS_ITEM_CONN_NAME:
if (!c->conn_name) {
r = -ENOMEM;
goto fail;
if (creds) {
*creds = c;
c = NULL;
fail:
static int bus_get_owner_dbus1(
const char *name,
r = sd_bus_call_method(
bus,
"/org/freedesktop/DBus",
NULL,
name);
if (mask != 0) {
c = bus_creds_new();
return -ENOMEM;
if (!c->unique_name)
return -ENOMEM;
SD_BUS_CREDS_CGROUP|SD_BUS_CREDS_UNIT|SD_BUS_CREDS_USER_UNIT|SD_BUS_CREDS_SLICE|SD_BUS_CREDS_SESSION|SD_BUS_CREDS_OWNER_UID|
SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS|
uint32_t u;
r = sd_bus_call_method(
bus,
"/org/freedesktop/DBus",
NULL,
&reply,
pid = u;
c->pid = u;
uint32_t u;
r = sd_bus_call_method(
bus,
"/org/freedesktop/DBus",
NULL,
&reply,
c->uid = u;
const void *p = NULL;
r = sd_bus_call_method(
bus,
"/org/freedesktop/DBus",
NULL,
&reply,
if (!c->label)
return -ENOMEM;
if (creds) {
*creds = c;
c = NULL;
const char *name,
return -ENOTCONN;
const char *name,
const char *old_owner,
const char *new_owner) {
if (name) {
if (is_name_id < 0)
if (is_name_id <= 0) {
struct kdbus_cmd_match *m;
if (name)
return -errno;
return -errno;
return -errno;
if (is_name_id != 0) {
struct kdbus_cmd_match *m;
sizeof(struct kdbus_notify_id_change));
sizeof(struct kdbus_notify_id_change);
return -errno;
return -errno;
unsigned n_components,
struct kdbus_cmd_match *m;
bool using_bloom = false;
bool matches_name_change = true;
for (i = 0; i < n_components; i++) {
switch (c->type) {
case BUS_MATCH_SENDER:
matches_name_change = false;
case BUS_MATCH_MESSAGE_TYPE:
matches_name_change = false;
bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, "message-type", bus_message_type_to_string(c->value_u8));
using_bloom = true;
case BUS_MATCH_INTERFACE:
matches_name_change = false;
using_bloom = true;
case BUS_MATCH_MEMBER:
matches_name_change = false;
using_bloom = true;
case BUS_MATCH_PATH:
matches_name_change = false;
using_bloom = true;
case BUS_MATCH_PATH_NAMESPACE:
using_bloom = true;
using_bloom = true;
using_bloom = true;
using_bloom = true;
case BUS_MATCH_DESTINATION:
case BUS_MATCH_ROOT:
case BUS_MATCH_VALUE:
case BUS_MATCH_LEAF:
case _BUS_MATCH_NODE_TYPE_MAX:
if (using_bloom)
if (using_bloom) {
if (sender) {
return -errno;
if (matches_name_change) {
static int bus_add_match_internal_dbus1(
const char *match) {
return sd_bus_call_method(
bus,
"/org/freedesktop/DBus",
NULL,
NULL,
const char *match,
unsigned n_components,
struct kdbus_cmd_match m;
zero(m);
return -errno;
static int bus_remove_match_internal_dbus1(
const char *match) {
return sd_bus_call_method(
bus,
"/org/freedesktop/DBus",
NULL,
NULL,
const char *match,
const char *mid;
return -ENOTCONN;
bus,
name,
r = sd_bus_message_set_auto_start(m, false);