bus: rework message handlers to always take an error argument

Message handler callbacks can be simplified drastically if the
dispatcher automatically replies to method calls if errors are returned.

Thus: add an sd_bus_error argument to all message handlers. When we
dispatch a message handler and it returns negative or a set sd_bus_error
we send this as message error back to the client. This means errors
returned by handlers by default are given back to clients instead of
rippling all the way up to the event loop, which is desirable to make
things robust.

As a side-effect we can now easily turn the SELinux checks into normal
function calls, since the method call dispatcher will generate the right
error replies automatically now.

Also, make sure we always pass the error structure to all property and
method handlers as last argument to follow the usual style of passing
variables for return values as last argument.
This commit is contained in:
Lennart Poettering 2013-11-21 19:34:37 +01:00
parent 0ccad099d4
commit ebcf1f97de
42 changed files with 1203 additions and 1134 deletions

4
TODO
View File

@ -43,6 +43,8 @@ CGroup Rework Completion:
Features:
* add API to clone sd_bus_message objects
* sd-bus: synthesized messages should get serial number (uint32_t) -1
* sd-event: allow multiple signal handlers per signal
@ -62,8 +64,6 @@ Features:
* sd-bus: enforce signatures on response messages
* sd-bus: make message handlers take an sd_bus_error and generate error replies automatically if they are set
* sd-bus: see if we can drop more message validation on the sending side
* sd-bus: introduce sd_bus_creds object and attach it to messages as well as allow querying it for names

View File

@ -33,8 +33,8 @@ static int property_get_blockio_device_weight(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
CGroupContext *c = userdata;
CGroupBlockIODeviceWeight *w;
@ -63,8 +63,8 @@ static int property_get_blockio_device_bandwidths(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
CGroupContext *c = userdata;
CGroupBlockIODeviceBandwidth *b;
@ -97,8 +97,8 @@ static int property_get_device_allow(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
CGroupContext *c = userdata;
CGroupDeviceAllow *a;

View File

@ -19,6 +19,7 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#include "bus-util.h"
#include "dbus-client-track.h"
static unsigned tracked_client_hash(const void *a) {
@ -43,7 +44,7 @@ static int tracked_client_compare(const void *a, const void *b) {
return 0;
}
static int on_name_owner_changed(sd_bus *bus, sd_bus_message *message, void *userdata) {
static int on_name_owner_changed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
BusTrackedClient *c = userdata;
const char *name, *old, *new;
int r;
@ -53,8 +54,8 @@ static int on_name_owner_changed(sd_bus *bus, sd_bus_message *message, void *use
r = sd_bus_message_read(message, "sss", &name, &old, &new);
if (r < 0) {
log_debug("Failed to parse NameOwnerChanged message.");
return 0;
bus_log_parse_error(r);
return r;
}
bus_client_untrack(c->set, bus, name);

View File

@ -40,8 +40,8 @@ static int property_get_environment_files(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
ExecContext *c = userdata;
char **j;
@ -72,8 +72,8 @@ static int property_get_rlimit(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
struct rlimit *rl;
uint64_t u;
@ -106,8 +106,8 @@ static int property_get_oom_score_adjust(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
ExecContext *c = userdata;
@ -136,8 +136,8 @@ static int property_get_nice(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
ExecContext *c = userdata;
@ -165,8 +165,8 @@ static int property_get_ioprio(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
ExecContext *c = userdata;
@ -193,8 +193,8 @@ static int property_get_cpu_sched_policy(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
ExecContext *c = userdata;
int32_t n;
@ -220,8 +220,8 @@ static int property_get_cpu_sched_priority(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
ExecContext *c = userdata;
int32_t n;
@ -250,8 +250,8 @@ static int property_get_cpu_affinity(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
ExecContext *c = userdata;
@ -271,8 +271,8 @@ static int property_get_timer_slack_nsec(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
ExecContext *c = userdata;
uint64_t u;
@ -295,8 +295,8 @@ static int property_get_capability_bounding_set(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
ExecContext *c = userdata;
@ -315,8 +315,8 @@ static int property_get_capabilities(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
ExecContext *c = userdata;
char *t = NULL;
@ -349,8 +349,8 @@ static int property_get_syscall_filter(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
ExecContext *c = userdata;
@ -434,8 +434,8 @@ int bus_property_get_exec_command(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *ret_error) {
ExecCommand *c = *(ExecCommand**) userdata;
int r;

View File

@ -36,5 +36,5 @@
extern const sd_bus_vtable bus_exec_vtable[];
int bus_property_get_exec_output(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, sd_bus_error *error, void *userdata);
int bus_property_get_exec_command(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, sd_bus_error *error, void *userdata);
int bus_property_get_exec_output(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *ret_error);
int bus_property_get_exec_command(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *ret_error);

View File

@ -35,8 +35,8 @@ static int property_get_unit(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
_cleanup_free_ char *p = NULL;
Job *j = userdata;
@ -52,14 +52,18 @@ static int property_get_unit(
return sd_bus_message_append(reply, "(so)", j->unit->id, p);
}
static int method_cancel(sd_bus *bus, sd_bus_message *message, void *userdata) {
static int method_cancel(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
Job *j = userdata;
int r;
assert(bus);
assert(message);
assert(j);
SELINUX_UNIT_ACCESS_CHECK(j->unit, bus, message, "stop");
r = selinux_unit_access_check(j->unit, bus, message, "stop", error);
if (r < 0)
return r;
job_finish_and_invalidate(j, JOB_CANCELED, true);
return sd_bus_reply_method_return(message, NULL);

File diff suppressed because it is too large Load Diff

View File

@ -34,8 +34,8 @@ static int property_get_what(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
Mount *m = userdata;
const char *d;
@ -60,8 +60,8 @@ static int property_get_options(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
Mount *m = userdata;
const char *d;
@ -86,8 +86,8 @@ static int property_get_type(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
Mount *m = userdata;
const char *d;

View File

@ -33,8 +33,8 @@ static int property_get_paths(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
Path *p = userdata;
PathSpec *k;
@ -63,8 +63,8 @@ static int property_get_unit(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
Unit *p = userdata, *trigger;

View File

@ -25,14 +25,17 @@
#include "dbus-unit.h"
#include "dbus-snapshot.h"
int bus_snapshot_method_remove(sd_bus *bus, sd_bus_message *message, void *userdata) {
int bus_snapshot_method_remove(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
Snapshot *s = userdata;
int r;
assert(bus);
assert(message);
assert(s);
SELINUX_UNIT_ACCESS_CHECK(UNIT(s), bus, message, "stop");
r = selinux_unit_access_check(UNIT(s), bus, message, "stop", error);
if (r < 0)
return r;
snapshot_remove(s);

View File

@ -25,4 +25,4 @@
extern const sd_bus_vtable bus_snapshot_vtable[];
int bus_snapshot_method_remove(sd_bus *bus, sd_bus_message *message, void *userdata);
int bus_snapshot_method_remove(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error);

View File

@ -37,8 +37,8 @@ static int property_get_listen(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
Socket *s = SOCKET(userdata);

View File

@ -35,8 +35,8 @@ static int property_get_priority(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
Swap *s = SWAP(userdata);
int p;

View File

@ -33,8 +33,8 @@ static int property_get_monotonic_timers(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
Timer *t = userdata;
TimerValue *v;
@ -82,8 +82,8 @@ static int property_get_calendar_timers(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
Timer *t = userdata;
TimerValue *v;
@ -121,8 +121,8 @@ static int property_get_unit(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
Unit *u = userdata, *trigger;

View File

@ -39,8 +39,8 @@ static int property_get_names(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
Unit *u = userdata;
Iterator i;
@ -70,8 +70,8 @@ static int property_get_following(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
Unit *u = userdata, *f;
@ -89,8 +89,8 @@ static int property_get_dependencies(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
Set *s = *(Set**) userdata;
Iterator j;
@ -119,8 +119,8 @@ static int property_get_description(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
Unit *u = userdata;
@ -137,8 +137,8 @@ static int property_get_active_state(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
Unit *u = userdata;
@ -155,8 +155,8 @@ static int property_get_sub_state(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
Unit *u = userdata;
@ -173,8 +173,8 @@ static int property_get_unit_file_state(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
Unit *u = userdata;
@ -191,8 +191,8 @@ static int property_get_can_start(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
Unit *u = userdata;
@ -209,8 +209,8 @@ static int property_get_can_stop(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
Unit *u = userdata;
@ -230,8 +230,8 @@ static int property_get_can_reload(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
Unit *u = userdata;
@ -248,8 +248,8 @@ static int property_get_can_isolate(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
Unit *u = userdata;
@ -266,8 +266,8 @@ static int property_get_job(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
_cleanup_free_ char *p = NULL;
Unit *u = userdata;
@ -292,8 +292,8 @@ static int property_get_need_daemon_reload(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
Unit *u = userdata;
@ -310,8 +310,8 @@ static int property_get_conditions(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
Unit *u = userdata;
Condition *c;
@ -341,8 +341,8 @@ static int property_get_load_error(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
_cleanup_bus_error_free_ sd_bus_error e = SD_BUS_ERROR_NULL;
Unit *u = userdata;
@ -357,7 +357,7 @@ static int property_get_load_error(
return sd_bus_message_append(reply, "(ss)", e.name, e.message);
}
int bus_unit_method_start_generic(sd_bus *bus, sd_bus_message *message, Unit *u, JobType job_type, bool reload_if_possible) {
int bus_unit_method_start_generic(sd_bus *bus, sd_bus_message *message, Unit *u, JobType job_type, bool reload_if_possible, sd_bus_error *error) {
const char *smode;
JobMode mode;
int r;
@ -369,45 +369,44 @@ int bus_unit_method_start_generic(sd_bus *bus, sd_bus_message *message, Unit *u,
r = sd_bus_message_read(message, "s", &smode);
if (r < 0)
return sd_bus_reply_method_errno(message, r, NULL);
return r;
mode = job_mode_from_string(smode);
if (mode < 0)
return sd_bus_reply_method_errorf(message, SD_BUS_ERROR_INVALID_ARGS, "Job mode %s invalid", smode);
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Job mode %s invalid", smode);
return bus_unit_queue_job(bus, message, u, job_type, mode, reload_if_possible);
return bus_unit_queue_job(bus, message, u, job_type, mode, reload_if_possible, error);
}
static int method_start(sd_bus *bus, sd_bus_message *message, void *userdata) {
return bus_unit_method_start_generic(bus, message, userdata, JOB_START, false);
static int method_start(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
return bus_unit_method_start_generic(bus, message, userdata, JOB_START, false, error);
}
static int method_stop(sd_bus *bus, sd_bus_message *message, void *userdata) {
return bus_unit_method_start_generic(bus, message, userdata, JOB_STOP, false);
static int method_stop(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
return bus_unit_method_start_generic(bus, message, userdata, JOB_STOP, false, error);
}
static int method_reload(sd_bus *bus, sd_bus_message *message, void *userdata) {
return bus_unit_method_start_generic(bus, message, userdata, JOB_RELOAD, false);
static int method_reload(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
return bus_unit_method_start_generic(bus, message, userdata, JOB_RELOAD, false, error);
}
static int method_restart(sd_bus *bus, sd_bus_message *message, void *userdata) {
return bus_unit_method_start_generic(bus, message, userdata, JOB_RESTART, false);
static int method_restart(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
return bus_unit_method_start_generic(bus, message, userdata, JOB_RESTART, false, error);
}
static int method_try_restart(sd_bus *bus, sd_bus_message *message, void *userdata) {
return bus_unit_method_start_generic(bus, message, userdata, JOB_TRY_RESTART, false);
static int method_try_restart(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
return bus_unit_method_start_generic(bus, message, userdata, JOB_TRY_RESTART, false, error);
}
static int method_reload_or_restart(sd_bus *bus, sd_bus_message *message, void *userdata) {
return bus_unit_method_start_generic(bus, message, userdata, JOB_RESTART, true);
static int method_reload_or_restart(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
return bus_unit_method_start_generic(bus, message, userdata, JOB_RESTART, true, error);
}
static int method_reload_or_try_restart(sd_bus *bus, sd_bus_message *message, void *userdata) {
return bus_unit_method_start_generic(bus, message, userdata, JOB_TRY_RESTART, true);
static int method_reload_or_try_restart(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
return bus_unit_method_start_generic(bus, message, userdata, JOB_TRY_RESTART, true, error);
}
int bus_unit_method_kill(sd_bus *bus, sd_bus_message *message, void *userdata) {
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
int bus_unit_method_kill(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
Unit *u = userdata;
const char *swho;
int32_t signo;
@ -420,44 +419,48 @@ int bus_unit_method_kill(sd_bus *bus, sd_bus_message *message, void *userdata) {
r = sd_bus_message_read(message, "si", &swho, &signo);
if (r < 0)
return sd_bus_reply_method_errno(message, r, NULL);
return r;
if (isempty(swho))
who = KILL_ALL;
else {
who = kill_who_from_string(swho);
if (who < 0)
return sd_bus_reply_method_errorf(message, SD_BUS_ERROR_INVALID_ARGS, "Invalid who argument %s", swho);
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid who argument %s", swho);
}
if (signo <= 0 || signo >= _NSIG)
return sd_bus_reply_method_errorf(message, SD_BUS_ERROR_INVALID_ARGS, "Signal number out of range.");
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Signal number out of range.");
SELINUX_UNIT_ACCESS_CHECK(u, bus, message, "stop");
r = unit_kill(u, who, signo, &error);
r = selinux_unit_access_check(u, bus, message, "stop", error);
if (r < 0)
return sd_bus_reply_method_errno(message, r, &error);
return r;
r = unit_kill(u, who, signo, error);
if (r < 0)
return r;
return sd_bus_reply_method_return(message, NULL);
}
int bus_unit_method_reset_failed(sd_bus *bus, sd_bus_message *message, void *userdata) {
int bus_unit_method_reset_failed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
Unit *u = userdata;
int r;
assert(bus);
assert(message);
assert(u);
SELINUX_UNIT_ACCESS_CHECK(u, bus, message, "reload");
r = selinux_unit_access_check(u, bus, message, "reload", error);
if (r < 0)
return r;
unit_reset_failed(u);
return sd_bus_reply_method_return(message, NULL);
}
int bus_unit_method_set_properties(sd_bus *bus, sd_bus_message *message, void *userdata) {
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
int bus_unit_method_set_properties(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
Unit *u = userdata;
int runtime, r;
@ -467,21 +470,23 @@ int bus_unit_method_set_properties(sd_bus *bus, sd_bus_message *message, void *u
r = sd_bus_message_read(message, "b", &runtime);
if (r < 0)
return sd_bus_reply_method_errno(message, r, NULL);
return r;
SELINUX_UNIT_ACCESS_CHECK(u, bus, message, "start");
r = selinux_unit_access_check(u, bus, message, "start", error);
if (r < 0)
return r;
r = sd_bus_message_enter_container(message, 'a', "(sv)");
if (r < 0)
return sd_bus_reply_method_errno(message, r, NULL);
return r;
r = bus_unit_set_properties(u, message, runtime ? UNIT_RUNTIME : UNIT_PERSISTENT, true, &error);
r = bus_unit_set_properties(u, message, runtime ? UNIT_RUNTIME : UNIT_PERSISTENT, true, error);
if (r < 0)
return sd_bus_reply_method_errno(message, r, &error);
return r;
r = sd_bus_message_exit_container(message);
if (r < 0)
return sd_bus_reply_method_errno(message, r, NULL);
return r;
return sd_bus_reply_method_return(message, NULL);
}
@ -568,8 +573,8 @@ static int property_get_slice(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
Unit *u = userdata;
@ -728,9 +733,9 @@ int bus_unit_queue_job(
Unit *u,
JobType type,
JobMode mode,
bool reload_if_possible) {
bool reload_if_possible,
sd_bus_error *error) {
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_free_ char *path = NULL;
Job *j;
int r;
@ -748,31 +753,34 @@ int bus_unit_queue_job(
type = JOB_RELOAD;
}
SELINUX_UNIT_ACCESS_CHECK(u, bus, message,
(type == JOB_START || type == JOB_RESTART || type == JOB_TRY_RESTART) ? "start" :
type == JOB_STOP ? "stop" : "reload");
r = selinux_unit_access_check(
u, bus, message,
(type == JOB_START || type == JOB_RESTART || type == JOB_TRY_RESTART) ? "start" :
type == JOB_STOP ? "stop" : "reload", error);
if (r < 0)
return r;
if (type == JOB_STOP &&
(u->load_state == UNIT_NOT_FOUND || u->load_state == UNIT_ERROR) &&
unit_active_state(u) == UNIT_INACTIVE)
return sd_bus_reply_method_errorf(message, BUS_ERROR_NO_SUCH_UNIT, "Unit %s not loaded.", u->id);
return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s not loaded.", u->id);
if ((type == JOB_START && u->refuse_manual_start) ||
(type == JOB_STOP && u->refuse_manual_stop) ||
((type == JOB_RESTART || type == JOB_TRY_RESTART) && (u->refuse_manual_start || u->refuse_manual_stop)))
return sd_bus_reply_method_errorf(message, BUS_ERROR_ONLY_BY_DEPENDENCY, "Operation refused, unit %s may be requested by dependency only.", u->id);
return sd_bus_error_setf(error, BUS_ERROR_ONLY_BY_DEPENDENCY, "Operation refused, unit %s may be requested by dependency only.", u->id);
r = manager_add_job(u->manager, type, u, mode, true, &error, &j);
r = manager_add_job(u->manager, type, u, mode, true, error, &j);
if (r < 0)
return sd_bus_reply_method_errno(message, r, &error);
return r;
r = bus_client_track(&j->subscribed, bus, sd_bus_message_get_sender(message));
if (r < 0)
return sd_bus_reply_method_errno(message, r, NULL);
return r;
path = job_dbus_path(j);
if (!path)
return sd_bus_reply_method_errno(message, r, NULL);
return r;
return sd_bus_reply_method_return(message, "o", path);
}

View File

@ -30,10 +30,10 @@ extern const sd_bus_vtable bus_unit_cgroup_vtable[];
void bus_unit_send_change_signal(Unit *u);
void bus_unit_send_removed_signal(Unit *u);
int bus_unit_method_start_generic(sd_bus *bus, sd_bus_message *message, Unit *u, JobType job_type, bool reload_if_possible);
int bus_unit_method_kill(sd_bus *bus, sd_bus_message *message, void *userdata);
int bus_unit_method_reset_failed(sd_bus *bus, sd_bus_message *message, void *userdata);
int bus_unit_method_start_generic(sd_bus *bus, sd_bus_message *message, Unit *u, JobType job_type, bool reload_if_possible, sd_bus_error *error);
int bus_unit_method_kill(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error);
int bus_unit_method_reset_failed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error);
int bus_unit_queue_job(sd_bus *bus, sd_bus_message *message, Unit *u, JobType type, JobMode mode, bool reload_if_possible);
int bus_unit_queue_job(sd_bus *bus, sd_bus_message *message, Unit *u, JobType type, JobMode mode, bool reload_if_possible, sd_bus_error *error);
int bus_unit_set_properties(Unit *u, sd_bus_message *message, UnitSetPropertiesMode mode, bool commit, sd_bus_error *error);
int bus_unit_method_set_properties(sd_bus *bus, sd_bus_message *message, void *userdata);
int bus_unit_method_set_properties(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error);

View File

@ -71,7 +71,7 @@ int bus_send_queued_message(Manager *m) {
return 0;
}
static int signal_agent_released(sd_bus *bus, sd_bus_message *message, void *userdata) {
static int signal_agent_released(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
Manager *m = userdata;
const char *cgroup;
int r;
@ -100,7 +100,7 @@ static int signal_agent_released(sd_bus *bus, sd_bus_message *message, void *use
return 0;
}
static int signal_disconnected(sd_bus *bus, sd_bus_message *message, void *userdata) {
static int signal_disconnected(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
Manager *m = userdata;
assert(bus);
@ -119,7 +119,7 @@ static int signal_disconnected(sd_bus *bus, sd_bus_message *message, void *userd
return 0;
}
static int signal_name_owner_changed(sd_bus *bus, sd_bus_message *message, void *userdata) {
static int signal_name_owner_changed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
const char *name, *old_owner, *new_owner;
Manager *m = userdata;
int r;
@ -142,7 +142,7 @@ static int signal_name_owner_changed(sd_bus *bus, sd_bus_message *message, void
return 0;
}
static int signal_activation_request(sd_bus *bus, sd_bus_message *message, void *userdata) {
static int signal_activation_request(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *ret_error) {
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
Manager *m = userdata;

View File

@ -314,7 +314,7 @@ static int get_calling_context(
If the machine is in permissive mode it will return ok. Audit messages will
still be generated if the access would be denied in enforcing mode.
*/
int selinux_access_check(
int selinux_generic_access_check(
sd_bus *bus,
sd_bus_message *message,
const char *path,
@ -391,7 +391,7 @@ finish:
#else
int selinux_access_check(
int selinux_generic_access_check(
sd_bus *bus,
sd_bus_message *message,
const char *path,

View File

@ -27,36 +27,18 @@
void selinux_access_free(void);
int selinux_access_check(sd_bus *bus, sd_bus_message *message, const char *path, const char *permission, sd_bus_error *error);
int selinux_generic_access_check(sd_bus *bus, sd_bus_message *message, const char *path, const char *permission, sd_bus_error *error);
#ifdef HAVE_SELINUX
#define SELINUX_ACCESS_CHECK(bus, message, permission) \
do { \
_cleanup_bus_error_free_ sd_bus_error _error = SD_BUS_ERROR_NULL; \
sd_bus_message *_m = (message); \
sd_bus *_b = (bus); \
int _r; \
_r = selinux_access_check(_b, _m, NULL, (permission), &_error); \
if (_r < 0) \
return sd_bus_reply_method_errno(_m, _r, &_error); \
} while (false)
#define SELINUX_UNIT_ACCESS_CHECK(unit, bus, message, permission) \
do { \
_cleanup_bus_error_free_ sd_bus_error _error = SD_BUS_ERROR_NULL; \
sd_bus_message *_m = (message); \
sd_bus *_b = (bus); \
Unit *_u = (unit); \
int _r; \
_r = selinux_access_check(_b, _m, _u->source_path ?: _u->fragment_path, (permission), &_error); \
if (_r < 0) \
return sd_bus_reply_method_errno(_m, _r, &_error); \
} while (false)
#define selinux_access_check(bus, message, permission, error) \
selinux_generic_access_check(bus, message, NULL, permission, error)
#define selinux_unit_access_check(unit, bus, message, permission, error) \
({ Unit *_unit = (unit); selinux_generic_access_check(bus, message, _unit->fragment_path ?: _unit->fragment_path, permission, error); })
#else
#define SELINUX_ACCESS_CHECK(bus, message, permission) do { } while (false)
#define SELINUX_UNIT_ACCESS_CHECK(unit, bus, message, permission) do { } while (false)
#define selinux_access_check(bus, message, permission, error) 0
#define selinux_unit_access_check(unit, bus, message, permission, error) 0
#endif

View File

@ -315,13 +315,12 @@ static int property_get_icon_name(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
_cleanup_free_ char *n = NULL;
Context *c = userdata;
const char *name;
int r;
if (isempty(c->data[PROP_ICON_NAME]))
name = n = context_fallback_icon_name(c);
@ -331,11 +330,7 @@ static int property_get_icon_name(
if (!name)
return -ENOMEM;
r = sd_bus_message_append(reply, "s", name);
if (r < 0)
return r;
return 1;
return sd_bus_message_append(reply, "s", name);
}
static int property_get_chassis(
@ -344,27 +339,21 @@ static int property_get_chassis(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
Context *c = userdata;
const char *name;
int r;
if (isempty(c->data[PROP_CHASSIS]))
name = fallback_chassis();
else
name = c->data[PROP_CHASSIS];
r = sd_bus_message_append(reply, "s", name);
if (r < 0)
return r;
return 1;
return sd_bus_message_append(reply, "s", name);
}
static int method_set_hostname(sd_bus *bus, sd_bus_message *m, void *userdata) {
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
static int method_set_hostname(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
Context *c = userdata;
const char *name;
int interactive;
@ -373,7 +362,7 @@ static int method_set_hostname(sd_bus *bus, sd_bus_message *m, void *userdata) {
r = sd_bus_message_read(m, "sb", &name, &interactive);
if (r < 0)
return sd_bus_reply_method_errno(m, r, NULL);
return r;
if (isempty(name))
name = c->data[PROP_STATIC_HOSTNAME];
@ -382,20 +371,20 @@ static int method_set_hostname(sd_bus *bus, sd_bus_message *m, void *userdata) {
name = "localhost";
if (!hostname_is_valid(name))
return sd_bus_reply_method_errorf(m, SD_BUS_ERROR_INVALID_ARGS, "Invalid hostname '%s'", name);
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid hostname '%s'", name);
if (streq_ptr(name, c->data[PROP_HOSTNAME]))
return sd_bus_reply_method_return(m, NULL);
r = bus_verify_polkit_async(bus, &c->polkit_registry, m, "org.freedesktop.hostname1.set-hostname", interactive, &error, method_set_hostname, c);
r = bus_verify_polkit_async(bus, &c->polkit_registry, m, "org.freedesktop.hostname1.set-hostname", interactive, error, method_set_hostname, c);
if (r < 0)
return sd_bus_reply_method_errno(m, r, &error);
return r;
if (r == 0)
return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
h = strdup(name);
if (!h)
return log_oom();
return -ENOMEM;
free(c->data[PROP_HOSTNAME]);
c->data[PROP_HOSTNAME] = h;
@ -403,7 +392,7 @@ static int method_set_hostname(sd_bus *bus, sd_bus_message *m, void *userdata) {
r = context_write_data_hostname(c);
if (r < 0) {
log_error("Failed to set host name: %s", strerror(-r));
return sd_bus_reply_method_errnof(m, r, "Failed to set hostname: %s", strerror(-r));
return sd_bus_error_set_errnof(error, r, "Failed to set hostname: %s", strerror(-r));
}
log_info("Changed host name to '%s'", strna(c->data[PROP_HOSTNAME]));
@ -413,8 +402,7 @@ static int method_set_hostname(sd_bus *bus, sd_bus_message *m, void *userdata) {
return sd_bus_reply_method_return(m, NULL);
}
static int method_set_static_hostname(sd_bus *bus, sd_bus_message *m, void *userdata) {
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
static int method_set_static_hostname(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
Context *c = userdata;
const char *name;
int interactive;
@ -422,7 +410,7 @@ static int method_set_static_hostname(sd_bus *bus, sd_bus_message *m, void *user
r = sd_bus_message_read(m, "sb", &name, &interactive);
if (r < 0)
return sd_bus_reply_method_errno(m, r, NULL);
return r;
if (isempty(name))
name = NULL;
@ -430,9 +418,9 @@ static int method_set_static_hostname(sd_bus *bus, sd_bus_message *m, void *user
if (streq_ptr(name, c->data[PROP_STATIC_HOSTNAME]))
return sd_bus_reply_method_return(m, NULL);
r = bus_verify_polkit_async(bus, &c->polkit_registry, m, "org.freedesktop.hostname1.set-static-hostname", interactive, &error, method_set_static_hostname, c);
r = bus_verify_polkit_async(bus, &c->polkit_registry, m, "org.freedesktop.hostname1.set-static-hostname", interactive, error, method_set_static_hostname, c);
if (r < 0)
return sd_bus_reply_method_errno(m, r, &error);
return r;
if (r == 0)
return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
@ -443,11 +431,11 @@ static int method_set_static_hostname(sd_bus *bus, sd_bus_message *m, void *user
char *h;
if (!hostname_is_valid(name))
return sd_bus_reply_method_errorf(m, SD_BUS_ERROR_INVALID_ARGS, "Invalid static hostname '%s'", name);
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid static hostname '%s'", name);
h = strdup(name);
if (!h)
return log_oom();
return -ENOMEM;
free(c->data[PROP_STATIC_HOSTNAME]);
c->data[PROP_STATIC_HOSTNAME] = h;
@ -456,7 +444,7 @@ static int method_set_static_hostname(sd_bus *bus, sd_bus_message *m, void *user
r = context_write_data_static_hostname(c);
if (r < 0) {
log_error("Failed to write static host name: %s", strerror(-r));
return sd_bus_reply_method_errnof(m, r, "Failed to set static hostname: %s", strerror(-r));
return sd_bus_error_set_errnof(error, r, "Failed to set static hostname: %s", strerror(-r));
}
log_info("Changed static host name to '%s'", strna(c->data[PROP_STATIC_HOSTNAME]));
@ -466,8 +454,7 @@ static int method_set_static_hostname(sd_bus *bus, sd_bus_message *m, void *user
return sd_bus_reply_method_return(m, NULL);
}
static int set_machine_info(Context *c, sd_bus *bus, sd_bus_message *m, int prop, sd_bus_message_handler_t cb) {
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
static int set_machine_info(Context *c, sd_bus *bus, sd_bus_message *m, int prop, sd_bus_message_handler_t cb, sd_bus_error *error) {
int interactive;
const char *name;
int r;
@ -478,7 +465,7 @@ static int set_machine_info(Context *c, sd_bus *bus, sd_bus_message *m, int prop
r = sd_bus_message_read(m, "sb", &name, &interactive);
if (r < 0)
return sd_bus_reply_method_errno(m, r, NULL);
return r;
if (isempty(name))
name = NULL;
@ -492,9 +479,9 @@ static int set_machine_info(Context *c, sd_bus *bus, sd_bus_message *m, int prop
r = bus_verify_polkit_async(bus, &c->polkit_registry, m, prop == PROP_PRETTY_HOSTNAME ?
"org.freedesktop.hostname1.set-static-hostname" :
"org.freedesktop.hostname1.set-machine-info", interactive, &error, cb, c);
"org.freedesktop.hostname1.set-machine-info", interactive, error, cb, c);
if (r < 0)
return sd_bus_reply_method_errno(m, r, &error);
return r;
if (r == 0)
return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
@ -508,16 +495,16 @@ static int set_machine_info(Context *c, sd_bus *bus, sd_bus_message *m, int prop
* name, so better be safe than sorry */
if (prop == PROP_ICON_NAME && !filename_is_safe(name))
return sd_bus_reply_method_errorf(m, SD_BUS_ERROR_INVALID_ARGS, "Invalid icon name '%s'", name);
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid icon name '%s'", name);
if (prop == PROP_PRETTY_HOSTNAME &&
(string_has_cc(name) || chars_intersect(name, "\t")))
return sd_bus_reply_method_errorf(m, SD_BUS_ERROR_INVALID_ARGS, "Invalid pretty host name '%s'", name);
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid pretty host name '%s'", name);
if (prop == PROP_CHASSIS && !valid_chassis(name))
return sd_bus_reply_method_errorf(m, SD_BUS_ERROR_INVALID_ARGS, "Invalid chassis '%s'", name);
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid chassis '%s'", name);
h = strdup(name);
if (!h)
return log_oom();
return -ENOMEM;
free(c->data[prop]);
c->data[prop] = h;
@ -526,7 +513,7 @@ static int set_machine_info(Context *c, sd_bus *bus, sd_bus_message *m, int prop
r = context_write_data_other(c);
if (r < 0) {
log_error("Failed to write machine info: %s", strerror(-r));
return sd_bus_reply_method_errnof(m, r, "Failed to write machine info: %s", strerror(-r));
return sd_bus_error_set_errnof(error, r, "Failed to write machine info: %s", strerror(-r));
}
log_info("Changed %s to '%s'",
@ -540,16 +527,16 @@ static int set_machine_info(Context *c, sd_bus *bus, sd_bus_message *m, int prop
return sd_bus_reply_method_return(m, NULL);
}
static int method_set_pretty_hostname(sd_bus *bus, sd_bus_message *m, void *userdata) {
return set_machine_info(userdata, bus, m, PROP_PRETTY_HOSTNAME, method_set_pretty_hostname);
static int method_set_pretty_hostname(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
return set_machine_info(userdata, bus, m, PROP_PRETTY_HOSTNAME, method_set_pretty_hostname, error);
}
static int method_set_icon_name(sd_bus *bus, sd_bus_message *m, void *userdata) {
return set_machine_info(userdata, bus, m, PROP_ICON_NAME, method_set_icon_name);
static int method_set_icon_name(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
return set_machine_info(userdata, bus, m, PROP_ICON_NAME, method_set_icon_name, error);
}
static int method_set_chassis(sd_bus *bus, sd_bus_message *m, void *userdata) {
return set_machine_info(userdata, bus, m, PROP_CHASSIS, method_set_chassis);
static int method_set_chassis(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
return set_machine_info(userdata, bus, m, PROP_CHASSIS, method_set_chassis, error);
}
static const sd_bus_vtable hostname_vtable[] = {

View File

@ -22,6 +22,8 @@
#include "bus-internal.h"
#include "bus-message.h"
#include "bus-match.h"
#include "bus-error.h"
#include "bus-util.h"
/* Example:
*
@ -272,7 +274,10 @@ int bus_match_run(
/* Run the callback. And then invoke siblings. */
if (node->leaf.callback) {
r = node->leaf.callback(bus, m, node->leaf.userdata);
_cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
r = node->leaf.callback(bus, m, node->leaf.userdata, &error_buffer);
r = bus_maybe_reply_error(m, r, &error_buffer);
if (r != 0)
return r;
}

View File

@ -2133,7 +2133,7 @@ int bus_message_append_ap(
return r;
}
return 0;
return 1;
}
_public_ int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {

View File

@ -223,6 +223,8 @@ static int node_callbacks_run(
assert(found_object);
LIST_FOREACH(callbacks, c, first) {
_cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
if (bus->nodes_modified)
return 0;
@ -240,7 +242,8 @@ static int node_callbacks_run(
if (r < 0)
return r;
r = c->callback(bus, m, c->userdata);
r = c->callback(bus, m, c->userdata, &error_buffer);
r = bus_maybe_reply_error(m, r, &error_buffer);
if (r != 0)
return r;
}
@ -299,8 +302,13 @@ static int method_callbacks_run(
return 1;
}
if (c->vtable->x.method.handler)
return c->vtable->x.method.handler(bus, m, u);
if (c->vtable->x.method.handler) {
_cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
r = c->vtable->x.method.handler(bus, m, u, &error_buffer);
return bus_maybe_reply_error(m, r, &error_buffer);
}
/* If the method callback is NULL, make this a successful NOP */
r = sd_bus_reply_method_return(m, NULL);
@ -316,9 +324,9 @@ static int invoke_property_get(
const char *path,
const char *interface,
const char *property,
sd_bus_message *m,
sd_bus_error *error,
void *userdata) {
sd_bus_message *reply,
void *userdata,
sd_bus_error *error) {
const void *p;
@ -327,15 +335,15 @@ static int invoke_property_get(
assert(path);
assert(interface);
assert(property);
assert(m);
assert(reply);
if (v->x.property.get)
return v->x.property.get(bus, path, interface, property, m, error, userdata);
return v->x.property.get(bus, path, interface, property, reply, userdata, error);
/* Automatic handling if no callback is defined. */
if (streq(v->x.property.signature, "as"))
return sd_bus_message_append_strv(m, *(char***) userdata);
return sd_bus_message_append_strv(reply, *(char***) userdata);
assert(signature_is_single(v->x.property.signature, false));
assert(bus_type_is_basic(v->x.property.signature[0]));
@ -357,7 +365,7 @@ static int invoke_property_get(
break;
}
return sd_bus_message_append_basic(m, v->x.property.signature[0], p);
return sd_bus_message_append_basic(reply, v->x.property.signature[0], p);
}
static int invoke_property_set(
@ -367,8 +375,8 @@ static int invoke_property_set(
const char *interface,
const char *property,
sd_bus_message *value,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
int r;
@ -380,7 +388,7 @@ static int invoke_property_set(
assert(value);
if (v->x.property.set)
return v->x.property.set(bus, path, interface, property, value, error, userdata);
return v->x.property.set(bus, path, interface, property, value, userdata, error);
/* Automatic handling if no callback is defined. */
@ -428,8 +436,8 @@ static int property_get_set_callbacks_run(
bool is_get,
bool *found_object) {
_cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
void *u;
int r;
@ -465,17 +473,11 @@ static int property_get_set_callbacks_run(
if (r < 0)
return r;
r = invoke_property_get(bus, c->vtable, m->path, c->interface, c->member, reply, &error, u);
r = invoke_property_get(bus, c->vtable, m->path, c->interface, c->member, reply, u, &error);
if (r < 0)
return r;
if (sd_bus_error_is_set(&error)) {
r = sd_bus_reply_method_error(m, &error);
if (r < 0)
return r;
return 1;
}
return sd_bus_reply_method_errno(m, r, &error);
if (sd_bus_error_is_set(&error))
return sd_bus_reply_method_error(m, &error);
if (bus->nodes_modified)
return 0;
@ -486,33 +488,25 @@ static int property_get_set_callbacks_run(
} else {
if (c->vtable->type != _SD_BUS_VTABLE_WRITABLE_PROPERTY)
sd_bus_error_setf(&error, SD_BUS_ERROR_PROPERTY_READ_ONLY, "Property '%s' is not writable.", c->member);
else {
/* Avoid that we call the set routine more
* than once if the processing of this message
* got restarted because the node tree
* changed. */
if (c->last_iteration == bus->iteration_counter)
return 0;
return sd_bus_reply_method_errorf(m, SD_BUS_ERROR_PROPERTY_READ_ONLY, "Property '%s' is not writable.", c->member);
c->last_iteration = bus->iteration_counter;
/* Avoid that we call the set routine more than once
* if the processing of this message got restarted
* because the node tree changed. */
if (c->last_iteration == bus->iteration_counter)
return 0;
r = sd_bus_message_enter_container(m, 'v', c->vtable->x.property.signature);
if (r < 0)
return r;
c->last_iteration = bus->iteration_counter;
r = invoke_property_set(bus, c->vtable, m->path, c->interface, c->member, m, &error, u);
if (r < 0)
return r;
}
r = sd_bus_message_enter_container(m, 'v', c->vtable->x.property.signature);
if (r < 0)
return r;
if (sd_bus_error_is_set(&error)) {
r = sd_bus_reply_method_error(m, &error);
if (r < 0)
return r;
return 1;
}
r = invoke_property_set(bus, c->vtable, m->path, c->interface, c->member, m, u, &error);
if (r < 0)
return sd_bus_reply_method_errno(m, r, &error);
if (sd_bus_error_is_set(&error))
return sd_bus_reply_method_error(m, &error);
if (bus->nodes_modified)
return 0;
@ -561,11 +555,13 @@ static int vtable_append_all_properties(
if (r < 0)
return r;
r = invoke_property_get(bus, v, path, c->interface, v->x.property.member, reply, error, vtable_property_convert_userdata(v, userdata));
if (r < 0)
return r;
r = invoke_property_get(bus, v, path, c->interface, v->x.property.member, reply, vtable_property_convert_userdata(v, userdata), error);
if (sd_bus_error_is_set(error))
return 0;
if (r < 0) {
sd_bus_error_set_errno(error, r);
return 0;
}
if (bus->nodes_modified)
return 0;
@ -1944,9 +1940,11 @@ static int emit_properties_changed_on_interface(
if (r < 0)
return r;
r = invoke_property_get(bus, v->vtable, m->path, interface, *property, m, &error, vtable_property_convert_userdata(v->vtable, u));
r = invoke_property_get(bus, v->vtable, m->path, interface, *property, m, vtable_property_convert_userdata(v->vtable, u), &error);
if (r < 0)
return r;
if (sd_bus_error_is_set(&error))
return sd_bus_error_get_errno(&error);
if (bus->nodes_modified)
return 0;

View File

@ -31,10 +31,10 @@
#include "sd-bus.h"
#include "bus-error.h"
#include "bus-message.h"
#include "bus-util.h"
#include "bus-internal.h"
static int quit_callback(sd_bus *bus, sd_bus_message *m, void *userdata) {
static int quit_callback(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
sd_event *e = userdata;
assert(bus);
@ -103,25 +103,6 @@ int bus_event_loop_with_idle(sd_event *e, sd_bus *bus, const char *name, usec_t
return 0;
}
int bus_property_get_tristate(
sd_bus *bus,
const char *path,
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
int *tristate = userdata;
int r;
r = sd_bus_message_append(reply, "b", *tristate > 0);
if (r < 0)
return r;
return 1;
}
int bus_verify_polkit(
sd_bus *bus,
sd_bus_message *m,
@ -203,11 +184,30 @@ typedef struct AsyncPolkitQuery {
sd_bus_message_handler_t callback;
void *userdata;
uint64_t serial;
Hashmap *registry;
} AsyncPolkitQuery;
static int async_polkit_callback(sd_bus *bus, sd_bus_message *reply, void *userdata) {
AsyncPolkitQuery *q = userdata;
static void async_polkit_query_free(sd_bus *b, AsyncPolkitQuery *q) {
if (!q)
return;
if (q->serial > 0 && b)
sd_bus_call_async_cancel(b, q->serial);
if (q->registry && q->request)
hashmap_remove(q->registry, q->request);
sd_bus_message_unref(q->request);
sd_bus_message_unref(q->reply);
free(q);
}
static int async_polkit_callback(sd_bus *bus, sd_bus_message *reply, void *userdata, sd_bus_error *error) {
_cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
_cleanup_bus_message_unref_ sd_bus_message *m = NULL;
AsyncPolkitQuery *q = userdata;
int r;
assert(bus);
@ -217,30 +217,18 @@ static int async_polkit_callback(sd_bus *bus, sd_bus_message *reply, void *userd
q->reply = sd_bus_message_ref(reply);
q->serial = 0;
m = sd_bus_message_ref(q->request);
r = sd_bus_message_rewind(q->request, true);
if (r < 0) {
r = sd_bus_reply_method_errno(q->request, r, NULL);
goto finish;
}
r = sd_bus_message_rewind(m, true);
if (r < 0)
return r;
r = q->callback(bus, q->request, q->userdata, &error_buffer);
r = bus_maybe_reply_error(q->request, r, &error_buffer);
r = q->callback(bus, m, q->userdata);
if (r < 0)
return r;
return 1;
}
static void async_polkit_query_free(sd_bus *b, AsyncPolkitQuery *q) {
if (!q)
return;
if (q->serial > 0 && b)
sd_bus_call_async_cancel(b, q->serial);
sd_bus_message_unref(q->request);
sd_bus_message_unref(q->reply);
free(q);
finish:
async_polkit_query_free(bus, q);
return r;
}
#endif
@ -269,7 +257,7 @@ int bus_verify_polkit_async(
assert(action);
#ifdef ENABLE_POLKIT
q = hashmap_remove(*registry, m);
q = hashmap_get(*registry, m);
if (q) {
int authorized, challenge;
@ -281,26 +269,21 @@ int bus_verify_polkit_async(
if (sd_bus_message_is_method_error(q->reply, NULL)) {
const sd_bus_error *e;
/* Treat no PK available as access denied */
if (sd_bus_message_is_method_error(q->reply, SD_BUS_ERROR_SERVICE_UNKNOWN)) {
async_polkit_query_free(bus, q);
return -EACCES;
}
/* Copy error from polkit reply */
e = sd_bus_message_get_error(q->reply);
sd_bus_error_copy(error, e);
r = sd_bus_error_get_errno(e);
async_polkit_query_free(bus, q);
return r;
/* Treat no PK available as access denied */
if (sd_bus_error_has_name(e, SD_BUS_ERROR_SERVICE_UNKNOWN))
return -EACCES;
return sd_bus_error_get_errno(e);
}
r = sd_bus_message_enter_container(q->reply, 'r', "bba{ss}");
if (r >= 0)
r = sd_bus_message_read(q->reply, "bb", &authorized, &challenge);
async_polkit_query_free(bus, q);
if (r < 0)
return r;
@ -344,7 +327,7 @@ int bus_verify_polkit_async(
action,
0,
interactive ? 1 : 0,
"");
NULL);
if (r < 0)
return r;
@ -362,9 +345,13 @@ int bus_verify_polkit_async(
return r;
}
q->registry = *registry;
r = sd_bus_call_async(bus, pk, async_polkit_callback, q, 0, &q->serial);
if (r < 0)
if (r < 0) {
async_polkit_query_free(bus, q);
return r;
}
return 0;
#endif
@ -1000,14 +987,28 @@ int bus_open_transport_systemd(BusTransport transport, const char *host, bool us
return r;
}
int bus_property_get_tristate(
sd_bus *bus,
const char *path,
const char *interface,
const char *property,
sd_bus_message *reply,
void *userdata,
sd_bus_error *error) {
int *tristate = userdata;
return sd_bus_message_append(reply, "b", *tristate > 0);
}
int bus_property_get_bool(
sd_bus *bus,
const char *path,
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
int b = *(bool*) userdata;
@ -1021,8 +1022,8 @@ int bus_property_get_size(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
uint64_t sz = *(size_t*) userdata;
@ -1037,8 +1038,8 @@ int bus_property_get_long(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
int64_t l = *(long*) userdata;
@ -1051,8 +1052,8 @@ int bus_property_get_ulong(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
uint64_t ul = *(unsigned long*) userdata;
@ -1088,3 +1089,29 @@ int bus_parse_unit_info(sd_bus_message *message, UnitInfo *u) {
&u->job_type,
&u->job_path);
}
int bus_maybe_reply_error(sd_bus_message *m, int r, sd_bus_error *error) {
assert(m);
if (r < 0) {
if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL)
sd_bus_reply_method_errno(m, r, error);
} else if (sd_bus_error_is_set(error)) {
if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL)
sd_bus_reply_method_error(m, error);
} else
return r;
log_debug("Failed to process message [type=%s sender=%s path=%s interface=%s member=%s signature=%s]: %s",
bus_message_type_to_string(m->header->type),
strna(m->sender),
strna(m->path),
strna(m->interface),
strna(m->member),
strna(m->root_container.signature),
bus_error_message(error, r));
return 1;
}

View File

@ -72,8 +72,8 @@ int bus_open_transport_systemd(BusTransport transport, const char *host, bool us
int bus_print_property(const char *name, sd_bus_message *property, bool all);
int bus_print_all_properties(sd_bus *bus, const char *dest, const char *path, char **filter, bool all);
int bus_property_get_tristate(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, sd_bus_error *error, void *userdata);
int bus_property_get_bool(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, sd_bus_error *error, void *userdata);
int bus_property_get_tristate(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error);
int bus_property_get_bool(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error);
#define bus_property_get_usec ((sd_bus_property_get_t) NULL)
#define bus_property_set_usec ((sd_bus_property_set_t) NULL)
@ -89,15 +89,15 @@ assert_cc(sizeof(unsigned) == sizeof(unsigned));
#if __SIZEOF_SIZE_T__ == 8
#define bus_property_get_size ((sd_bus_property_get_t) NULL)
#else
int bus_property_get_size(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, sd_bus_error *error, void *userdata);
int bus_property_get_size(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error);
#endif
#if __SIZEOF_LONG__ == 8
#define bus_property_get_long ((sd_bus_property_get_t) NULL)
#define bus_property_get_ulong ((sd_bus_property_get_t) NULL)
#else
int bus_property_get_long(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, sd_bus_error *error, void *userdata);
int bus_property_get_ulong(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, sd_bus_error *error, void *userdata);
int bus_property_get_long(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error);
int bus_property_get_ulong(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error);
#endif
/* uid_t and friends on Linux 32 bit. This means we can just use the
@ -146,8 +146,8 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(sd_bus_message*, sd_bus_message_unref);
const char *interface, \
const char *property, \
sd_bus_message *reply, \
sd_bus_error *error, \
void *userdata) { \
void *userdata, \
sd_bus_error *error) { \
\
const char *value; \
type *field = userdata; \
@ -170,3 +170,5 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(sd_bus_message*, sd_bus_message_unref);
#define BUS_PROPERTY_DUAL_TIMESTAMP(name, offset, flags) \
SD_BUS_PROPERTY(name, "t", bus_property_get_usec, offset + offsetof(struct dual_timestamp, realtime), flags), \
SD_BUS_PROPERTY(name "Monotonic", "t", bus_property_get_usec, offset + offsetof(struct dual_timestamp, monotonic), flags)
int bus_maybe_reply_error(sd_bus_message *m, int r, sd_bus_error *error);

View File

@ -365,7 +365,7 @@ _public_ int sd_bus_set_anonymous(sd_bus *bus, int b) {
return 0;
}
static int hello_callback(sd_bus *bus, sd_bus_message *reply, void *userdata) {
static int hello_callback(sd_bus *bus, sd_bus_message *reply, void *userdata, sd_bus_error *error) {
const char *s;
int r;
@ -1824,6 +1824,7 @@ _public_ int sd_bus_get_timeout(sd_bus *bus, uint64_t *timeout_usec) {
}
static int process_timeout(sd_bus *bus) {
_cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
_cleanup_bus_message_unref_ sd_bus_message* m = NULL;
struct reply_callback *c;
usec_t n;
@ -1857,12 +1858,13 @@ static int process_timeout(sd_bus *bus) {
bus->current = m;
bus->iteration_counter ++;
r = c->callback(bus, m, c->userdata);
r = c->callback(bus, m, c->userdata, &error_buffer);
r = bus_maybe_reply_error(m, r, &error_buffer);
free(c);
bus->current = NULL;
return r < 0 ? r : 1;
return r;
}
static int process_hello(sd_bus *bus, sd_bus_message *m) {
@ -1888,6 +1890,7 @@ static int process_hello(sd_bus *bus, sd_bus_message *m) {
}
static int process_reply(sd_bus *bus, sd_bus_message *m) {
_cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
struct reply_callback *c;
int r;
@ -1909,13 +1912,15 @@ static int process_reply(sd_bus *bus, sd_bus_message *m) {
if (r < 0)
return r;
r = c->callback(bus, m, c->userdata);
r = c->callback(bus, m, c->userdata, &error_buffer);
r = bus_maybe_reply_error(m, r, &error_buffer);
free(c);
return r < 0 ? r : 1;
return r;
}
static int process_filter(sd_bus *bus, sd_bus_message *m) {
_cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
struct filter_callback *l;
int r;
@ -1940,7 +1945,8 @@ static int process_filter(sd_bus *bus, sd_bus_message *m) {
if (r < 0)
return r;
r = l->callback(bus, m, l->userdata);
r = l->callback(bus, m, &error_buffer, l->userdata);
r = bus_maybe_reply_error(m, r, &error_buffer);
if (r != 0)
return r;
@ -2123,6 +2129,8 @@ static int process_closing(sd_bus *bus, sd_bus_message **ret) {
c = hashmap_first(bus->reply_callbacks);
if (c) {
_cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
/* First, fail all outstanding method calls */
r = bus_message_new_synthetic_error(
bus,
@ -2144,12 +2152,10 @@ static int process_closing(sd_bus *bus, sd_bus_message **ret) {
bus->current = m;
bus->iteration_counter++;
r = c->callback(bus, m, c->userdata);
r = c->callback(bus, m, c->userdata, &error_buffer);
r = bus_maybe_reply_error(m, r, &error_buffer);
free(c);
if (r >= 0)
r = 1;
goto finish;
}

View File

@ -36,12 +36,12 @@
#include "bus-internal.h"
#include "bus-util.h"
static int match_callback(sd_bus *bus, sd_bus_message *m, void *userdata) {
static int match_callback(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
log_info("Match triggered! interface=%s member=%s", strna(sd_bus_message_get_interface(m)), strna(sd_bus_message_get_member(m)));
return 0;
}
static int object_callback(sd_bus *bus, sd_bus_message *m, void *userdata) {
static int object_callback(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
int r;
assert(bus);
@ -361,7 +361,7 @@ finish:
return INT_TO_PTR(r);
}
static int quit_callback(sd_bus *b, sd_bus_message *m, void *userdata) {
static int quit_callback(sd_bus *b, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
bool *x = userdata;
log_error("Quit callback: %s", strerror(sd_bus_message_get_errno(m)));

View File

@ -23,11 +23,11 @@
#include "log.h"
#include "bus-introspect.h"
static int prop_get(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, sd_bus_error *error, void *userdata) {
static int prop_get(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error) {
return -EINVAL;
}
static int prop_set(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, sd_bus_error *error, void *userdata) {
static int prop_set(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error) {
return -EINVAL;
}

View File

@ -31,7 +31,7 @@
static bool mask[32];
static int filter(sd_bus *b, sd_bus_message *m, void *userdata) {
static int filter(sd_bus *b, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
log_info("Ran %i", PTR_TO_INT(userdata));
mask[PTR_TO_INT(userdata)] = true;
return 0;

View File

@ -44,7 +44,7 @@ struct context {
uint32_t automatic_integer_property;
};
static int something_handler(sd_bus *bus, sd_bus_message *m, void *userdata) {
static int something_handler(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
struct context *c = userdata;
const char *s;
char *n = NULL;
@ -67,7 +67,7 @@ static int something_handler(sd_bus *bus, sd_bus_message *m, void *userdata) {
return 1;
}
static int exit_handler(sd_bus *bus, sd_bus_message *m, void *userdata) {
static int exit_handler(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
struct context *c = userdata;
int r;
@ -81,11 +81,11 @@ static int exit_handler(sd_bus *bus, sd_bus_message *m, void *userdata) {
return 1;
}
static int get_handler(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, sd_bus_error *error, void *userdata) {
static int get_handler(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error) {
struct context *c = userdata;
int r;
log_info("property get for %s called", property);
log_info("property get for %s called, returning \"%s\".", property, c->something);
r = sd_bus_message_append(reply, "s", c->something);
assert_se(r >= 0);
@ -93,7 +93,7 @@ static int get_handler(sd_bus *bus, const char *path, const char *interface, con
return 1;
}
static int set_handler(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *value, sd_bus_error *error, void *userdata) {
static int set_handler(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *value, void *userdata, sd_bus_error *error) {
struct context *c = userdata;
const char *s;
char *n;
@ -113,7 +113,7 @@ static int set_handler(sd_bus *bus, const char *path, const char *interface, con
return 1;
}
static int value_handler(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, sd_bus_error *error, void *userdata) {
static int value_handler(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error) {
_cleanup_free_ char *s = NULL;
const char *x;
int r;
@ -129,7 +129,7 @@ static int value_handler(sd_bus *bus, const char *path, const char *interface, c
return 1;
}
static int notify_test(sd_bus *bus, sd_bus_message *m, void *userdata) {
static int notify_test(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
int r;
assert_se(sd_bus_emit_properties_changed(bus, m->path, "org.freedesktop.systemd.ValueTest", "Value", NULL) >= 0);
@ -140,7 +140,7 @@ static int notify_test(sd_bus *bus, sd_bus_message *m, void *userdata) {
return 1;
}
static int emit_interfaces_added(sd_bus *bus, sd_bus_message *m, void *userdata) {
static int emit_interfaces_added(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
int r;
assert_se(sd_bus_emit_interfaces_added(bus, m->path, "org.freedesktop.systemd.test", NULL) >= 0);
@ -151,7 +151,7 @@ static int emit_interfaces_added(sd_bus *bus, sd_bus_message *m, void *userdata)
return 1;
}
static int emit_interfaces_removed(sd_bus *bus, sd_bus_message *m, void *userdata) {
static int emit_interfaces_removed(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
int r;
assert_se(sd_bus_emit_interfaces_removed(bus, m->path, "org.freedesktop.systemd.test", NULL) >= 0);
@ -435,7 +435,7 @@ static int client(struct context *c) {
}
int main(int argc, char *argv[]) {
struct context c;
struct context c = {};
pthread_t s;
void *p;
int r, q;

View File

@ -787,8 +787,15 @@ static int x11_convert_to_vconsole(Context *c, sd_bus *bus) {
return 0;
}
static int property_get_locale(sd_bus *bus, const char *path, const char *interface,
const char *property, sd_bus_message *reply, sd_bus_error *error, void *userdata) {
static int property_get_locale(
sd_bus *bus,
const char *path,
const char *interface,
const char *property,
sd_bus_message *reply,
void *userdata,
sd_bus_error *error) {
Context *c = userdata;
_cleanup_strv_free_ char **l = NULL;
int p, q;
@ -812,9 +819,8 @@ static int property_get_locale(sd_bus *bus, const char *path, const char *interf
return sd_bus_message_append_strv(reply, l);
}
static int method_set_locale(sd_bus *bus, sd_bus_message *m, void *userdata) {
static int method_set_locale(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
Context *c = userdata;
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_strv_free_ char **l = NULL;
char **i;
int interactive;
@ -825,11 +831,11 @@ static int method_set_locale(sd_bus *bus, sd_bus_message *m, void *userdata) {
r = bus_message_read_strv_extend(m, &l);
if (r < 0)
return sd_bus_reply_method_errno(m, r, NULL);
return r;
r = sd_bus_message_read_basic(m, 'b', &interactive);
if (r < 0)
return sd_bus_reply_method_errno(m, r, NULL);
return r;
/* Check whether a variable changed and if so valid */
STRV_FOREACH(i, l) {
@ -853,7 +859,7 @@ static int method_set_locale(sd_bus *bus, sd_bus_message *m, void *userdata) {
}
if (!valid)
sd_bus_reply_method_errorf(m, SD_BUS_ERROR_INVALID_ARGS, "Invalid Locale data.");
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid Locale data.");
}
/* Check whether a variable is unset */
@ -868,9 +874,9 @@ static int method_set_locale(sd_bus *bus, sd_bus_message *m, void *userdata) {
if (modified) {
r = bus_verify_polkit_async(bus, &c->polkit_registry, m,
"org.freedesktop.locale1.set-locale", interactive,
&error, method_set_locale, c);
error, method_set_locale, c);
if (r < 0)
return sd_bus_reply_method_errno(m, r, &error);
return r;
if (r == 0)
return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
@ -905,7 +911,7 @@ static int method_set_locale(sd_bus *bus, sd_bus_message *m, void *userdata) {
r = locale_write_data(c);
if (r < 0) {
log_error("Failed to set locale: %s", strerror(-r));
return sd_bus_reply_method_errnof(m, r, "Failed to set locale: %s", strerror(-r));
return sd_bus_error_set_errnof(error, r, "Failed to set locale: %s", strerror(-r));
}
locale_update_system_manager(c, bus);
@ -921,16 +927,15 @@ static int method_set_locale(sd_bus *bus, sd_bus_message *m, void *userdata) {
return sd_bus_reply_method_return(m, NULL);
}
static int method_set_vc_keyboard(sd_bus *bus, sd_bus_message *m, void *userdata) {
static int method_set_vc_keyboard(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
Context *c = userdata;
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
const char *keymap, *keymap_toggle;
int convert, interactive;
int r;
r = sd_bus_message_read(m, "ssbb", &keymap, &keymap_toggle, &convert, &interactive);
if (r < 0)
return sd_bus_reply_method_errno(m, r, NULL);
return r;
if (isempty(keymap))
keymap = NULL;
@ -943,13 +948,13 @@ static int method_set_vc_keyboard(sd_bus *bus, sd_bus_message *m, void *userdata
if ((keymap && (!filename_is_safe(keymap) || !string_is_safe(keymap))) ||
(keymap_toggle && (!filename_is_safe(keymap_toggle) || !string_is_safe(keymap_toggle))))
return sd_bus_reply_method_errnof(m, r, "Received invalid keymap data: %s", -EINVAL);
return sd_bus_error_set_errnof(error, r, "Received invalid keymap data: %s", -EINVAL);
r = bus_verify_polkit_async(bus, &c->polkit_registry, m,
"org.freedesktop.locale1.set-keyboard",
interactive, &error, method_set_vc_keyboard, c);
interactive, error, method_set_vc_keyboard, c);
if (r < 0)
return sd_bus_reply_method_errno(m, r, &error);
return r;
if (r == 0)
return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
@ -960,7 +965,7 @@ static int method_set_vc_keyboard(sd_bus *bus, sd_bus_message *m, void *userdata
r = vconsole_write_data(c);
if (r < 0) {
log_error("Failed to set virtual console keymap: %s", strerror(-r));
return sd_bus_reply_method_errnof(m, r, "Failed to set virtual console keymap: %s", strerror(-r));
return sd_bus_error_set_errnof(error, r, "Failed to set virtual console keymap: %s", strerror(-r));
}
log_info("Changed virtual console keymap to '%s'", strempty(c->vc_keymap));
@ -984,16 +989,15 @@ static int method_set_vc_keyboard(sd_bus *bus, sd_bus_message *m, void *userdata
return sd_bus_reply_method_return(m, NULL);
}
static int method_set_x11_keyboard(sd_bus *bus, sd_bus_message *m, void *userdata) {
static int method_set_x11_keyboard(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
Context *c = userdata;
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
const char *layout, *model, *variant, *options;
int convert, interactive;
int r;
r = sd_bus_message_read(m, "ssssbb", &layout, &model, &variant, &options, &convert, &interactive);
if (r < 0)
return sd_bus_reply_method_errno(m, r, NULL);
return r;
if (isempty(layout))
layout = NULL;
@ -1016,13 +1020,13 @@ static int method_set_x11_keyboard(sd_bus *bus, sd_bus_message *m, void *userdat
(model && !string_is_safe(model)) ||
(variant && !string_is_safe(variant)) ||
(options && !string_is_safe(options)))
return sd_bus_reply_method_errnof(m, r, "Received invalid keyboard data: %s", -EINVAL);
return sd_bus_error_set_errnof(error, r, "Received invalid keyboard data: %s", -EINVAL);
r = bus_verify_polkit_async(bus, &c->polkit_registry, m,
"org.freedesktop.locale1.set-keyboard",
interactive, &error, method_set_x11_keyboard, c);
interactive, error, method_set_x11_keyboard, c);
if (r < 0)
return sd_bus_reply_method_errno(m, r, &error);
return r;
if (r == 0)
return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
@ -1035,7 +1039,7 @@ static int method_set_x11_keyboard(sd_bus *bus, sd_bus_message *m, void *userdat
r = write_data_x11(c);
if (r < 0) {
log_error("Failed to set X11 keyboard layout: %s", strerror(-r));
return sd_bus_reply_method_errnof(m, r, "Failed to set X11 keyboard layout: %s", strerror(-r));
return sd_bus_error_set_errnof(error, r, "Failed to set X11 keyboard layout: %s", strerror(-r));
}
log_info("Changed X11 keyboard layout to '%s'", strempty(c->x11_layout));

File diff suppressed because it is too large Load Diff

View File

@ -35,8 +35,8 @@ static int property_get_active_session(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
_cleanup_free_ char *p = NULL;
Seat *s = userdata;
@ -58,8 +58,8 @@ static int property_get_can_multi_session(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
Seat *s = userdata;
@ -76,8 +76,8 @@ static int property_get_can_tty(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
Seat *s = userdata;
@ -94,8 +94,8 @@ static int property_get_can_graphical(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
Seat *s = userdata;
@ -112,8 +112,8 @@ static int property_get_sessions(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
Seat *s = userdata;
Session *session;
@ -153,8 +153,8 @@ static int property_get_idle_hint(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
Seat *s = userdata;
@ -171,8 +171,8 @@ static int property_get_idle_since_hint(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
Seat *s = userdata;
dual_timestamp t;
@ -192,7 +192,7 @@ static int property_get_idle_since_hint(
return sd_bus_message_append(reply, "t", u);
}
static int method_terminate(sd_bus *bus, sd_bus_message *message, void *userdata) {
static int method_terminate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
Seat *s = userdata;
int r;
@ -202,12 +202,12 @@ static int method_terminate(sd_bus *bus, sd_bus_message *message, void *userdata
r = seat_stop_sessions(s);
if (r < 0)
return sd_bus_reply_method_errno(message, r, NULL);
return r;
return sd_bus_reply_method_return(message, NULL);
}
static int method_activate_session(sd_bus *bus, sd_bus_message *message, void *userdata) {
static int method_activate_session(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
Seat *s = userdata;
const char *name;
Session *session;
@ -219,18 +219,18 @@ static int method_activate_session(sd_bus *bus, sd_bus_message *message, void *u
r = sd_bus_message_read(message, "s", &name);
if (r < 0)
return sd_bus_reply_method_errno(message, r, NULL);
return r;
session = hashmap_get(s->manager->sessions, name);
if (!session)
return sd_bus_reply_method_errorf(message, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_SESSION, "No session '%s' known", name);
if (session->seat != s)
return sd_bus_reply_method_errorf(message, BUS_ERROR_SESSION_NOT_ON_SEAT, "Session %s not on seat %s", name, s->id);
return sd_bus_error_setf(error, BUS_ERROR_SESSION_NOT_ON_SEAT, "Session %s not on seat %s", name, s->id);
r = session_activate(session);
if (r < 0)
return sd_bus_reply_method_errno(message, r, NULL);
return r;
return sd_bus_reply_method_return(message, NULL);
}

View File

@ -37,8 +37,8 @@ static int property_get_user(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
_cleanup_free_ char *p = NULL;
Session *s = userdata;
@ -60,8 +60,8 @@ static int property_get_name(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
Session *s = userdata;
@ -78,8 +78,8 @@ static int property_get_seat(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
_cleanup_free_ char *p = NULL;
Session *s = userdata;
@ -104,8 +104,8 @@ static int property_get_active(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
Session *s = userdata;
@ -122,8 +122,8 @@ static int property_get_state(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
Session *s = userdata;
@ -140,8 +140,8 @@ static int property_get_idle_hint(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
Session *s = userdata;
@ -158,8 +158,8 @@ static int property_get_idle_since_hint(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
Session *s = userdata;
dual_timestamp t;
@ -179,7 +179,7 @@ static int property_get_idle_since_hint(
return sd_bus_message_append(reply, "t", u);
}
static int method_terminate(sd_bus *bus, sd_bus_message *message, void *userdata) {
static int method_terminate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
Session *s = userdata;
int r;
@ -189,12 +189,12 @@ static int method_terminate(sd_bus *bus, sd_bus_message *message, void *userdata
r = session_stop(s);
if (r < 0)
return sd_bus_reply_method_errno(message, r, NULL);
return r;
return sd_bus_reply_method_return(message, NULL);
}
static int method_activate(sd_bus *bus, sd_bus_message *message, void *userdata) {
static int method_activate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
Session *s = userdata;
int r;
@ -204,12 +204,12 @@ static int method_activate(sd_bus *bus, sd_bus_message *message, void *userdata)
r = session_activate(s);
if (r < 0)
return sd_bus_reply_method_errno(message, r, NULL);
return r;
return sd_bus_reply_method_return(message, NULL);
}
static int method_lock(sd_bus *bus, sd_bus_message *message, void *userdata) {
static int method_lock(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
Session *s = userdata;
int r;
@ -219,12 +219,12 @@ static int method_lock(sd_bus *bus, sd_bus_message *message, void *userdata) {
r = session_send_lock(s, streq(sd_bus_message_get_member(message), "Lock"));
if (r < 0)
return sd_bus_reply_method_errno(message, r, NULL);
return r;
return sd_bus_reply_method_return(message, NULL);
}
static int method_set_idle_hint(sd_bus *bus, sd_bus_message *message, void *userdata) {
static int method_set_idle_hint(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
Session *s = userdata;
uid_t uid;
int r, b;
@ -235,21 +235,21 @@ static int method_set_idle_hint(sd_bus *bus, sd_bus_message *message, void *user
r = sd_bus_message_read(message, "b", &b);
if (r < 0)
return sd_bus_reply_method_errno(message, r, NULL);
return r;
r = sd_bus_get_owner_uid(bus, sd_bus_message_get_sender(message), &uid);
if (r < 0)
return sd_bus_reply_method_errno(message, r, NULL);
return r;
if (uid != 0 && uid != s->user->uid)
return sd_bus_reply_method_errorf(message, SD_BUS_ERROR_ACCESS_DENIED, "Only owner of session my set idle hint");
return sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "Only owner of session my set idle hint");
session_set_idle_hint(s, b);
return sd_bus_reply_method_return(message, NULL);
}
static int method_kill(sd_bus *bus, sd_bus_message *message, void *userdata) {
static int method_kill(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
Session *s = userdata;
const char *swho;
int32_t signo;
@ -262,27 +262,27 @@ static int method_kill(sd_bus *bus, sd_bus_message *message, void *userdata) {
r = sd_bus_message_read(message, "si", &swho, &signo);
if (r < 0)
return sd_bus_reply_method_errno(message, r, NULL);
return r;
if (isempty(swho))
who = KILL_ALL;
else {
who = kill_who_from_string(swho);
if (who < 0)
return sd_bus_reply_method_errorf(message, SD_BUS_ERROR_INVALID_ARGS, "Invalid kill parameter '%s'", swho);
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid kill parameter '%s'", swho);
}
if (signo <= 0 || signo >= _NSIG)
return sd_bus_reply_method_errorf(message, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo);
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo);
r = session_kill(s, who, signo);
if (r < 0)
return sd_bus_reply_method_errno(message, r, NULL);
return r;
return sd_bus_reply_method_return(message, NULL);
}
static int method_take_control(sd_bus *bus, sd_bus_message *message, void *userdata) {
static int method_take_control(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
Session *s = userdata;
int r, force;
uid_t uid;
@ -293,23 +293,23 @@ static int method_take_control(sd_bus *bus, sd_bus_message *message, void *userd
r = sd_bus_message_read(message, "b", &force);
if (r < 0)
return sd_bus_reply_method_errno(message, r, NULL);
return r;
r = sd_bus_get_owner_uid(bus, sd_bus_message_get_sender(message), &uid);
if (r < 0)
return sd_bus_reply_method_errno(message, r, NULL);
return r;
if (uid != 0 && (force || uid != s->user->uid))
return sd_bus_reply_method_errorf(message, SD_BUS_ERROR_ACCESS_DENIED, "Only owner of session may take control");
return sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "Only owner of session may take control");
r = session_set_controller(s, sd_bus_message_get_sender(message), force);
if (r < 0)
return sd_bus_reply_method_errno(message, r, NULL);
return r;
return sd_bus_reply_method_return(message, NULL);
}
static int method_release_control(sd_bus *bus, sd_bus_message *message, void *userdata) {
static int method_release_control(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
Session *s = userdata;
assert(bus);
@ -317,14 +317,14 @@ static int method_release_control(sd_bus *bus, sd_bus_message *message, void *us
assert(s);
if (!session_is_controller(s, sd_bus_message_get_sender(message)))
return sd_bus_reply_method_errorf(message, BUS_ERROR_NOT_IN_CONTROL, "You are not in control of this session");
return sd_bus_error_setf(error, BUS_ERROR_NOT_IN_CONTROL, "You are not in control of this session");
session_drop_controller(s);
return sd_bus_reply_method_return(message, NULL);
}
static int method_take_device(sd_bus *bus, sd_bus_message *message, void *userdata) {
static int method_take_device(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
Session *s = userdata;
uint32_t major, minor;
SessionDevice *sd;
@ -337,10 +337,10 @@ static int method_take_device(sd_bus *bus, sd_bus_message *message, void *userda
r = sd_bus_message_read(message, "uu", &major, &minor);
if (r < 0)
return sd_bus_reply_method_errno(message, r, NULL);
return r;
if (!session_is_controller(s, sd_bus_message_get_sender(message)))
return sd_bus_reply_method_errorf(message, BUS_ERROR_NOT_IN_CONTROL, "You are not in control of this session");
return sd_bus_error_setf(error, BUS_ERROR_NOT_IN_CONTROL, "You are not in control of this session");
dev = makedev(major, minor);
sd = hashmap_get(s->devices, &dev);
@ -350,11 +350,11 @@ static int method_take_device(sd_bus *bus, sd_bus_message *message, void *userda
* The caller should use dup() if it requires more
* than one fd (it would be functionally
* equivalent). */
return sd_bus_reply_method_errorf(message, BUS_ERROR_DEVICE_IS_TAKEN, "Device already taken");
return sd_bus_error_setf(error, BUS_ERROR_DEVICE_IS_TAKEN, "Device already taken");
r = session_device_new(s, dev, &sd);
if (r < 0)
return sd_bus_reply_method_errno(message, r, NULL);
return r;
r = sd_bus_reply_method_return(message, "hb", sd->fd, !sd->active);
if (r < 0)
@ -363,7 +363,7 @@ static int method_take_device(sd_bus *bus, sd_bus_message *message, void *userda
return r;
}
static int method_release_device(sd_bus *bus, sd_bus_message *message, void *userdata) {
static int method_release_device(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
Session *s = userdata;
uint32_t major, minor;
SessionDevice *sd;
@ -376,21 +376,21 @@ static int method_release_device(sd_bus *bus, sd_bus_message *message, void *use
r = sd_bus_message_read(message, "uu", &major, &minor);
if (r < 0)
return sd_bus_reply_method_errno(message, r, NULL);
return r;
if (!session_is_controller(s, sd_bus_message_get_sender(message)))
return sd_bus_reply_method_errorf(message, BUS_ERROR_NOT_IN_CONTROL, "You are not in control of this session");
return sd_bus_error_setf(error, BUS_ERROR_NOT_IN_CONTROL, "You are not in control of this session");
dev = makedev(major, minor);
sd = hashmap_get(s->devices, &dev);
if (!sd)
return sd_bus_reply_method_errorf(message, BUS_ERROR_DEVICE_NOT_TAKEN, "Device not taken");
return sd_bus_error_setf(error, BUS_ERROR_DEVICE_NOT_TAKEN, "Device not taken");
session_device_free(sd);
return sd_bus_reply_method_return(message, NULL);
}
static int method_pause_device_complete(sd_bus *bus, sd_bus_message *message, void *userdata) {
static int method_pause_device_complete(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
Session *s = userdata;
uint32_t major, minor;
SessionDevice *sd;
@ -403,15 +403,15 @@ static int method_pause_device_complete(sd_bus *bus, sd_bus_message *message, vo
r = sd_bus_message_read(message, "uu", &major, &minor);
if (r < 0)
return sd_bus_reply_method_errno(message, r, NULL);
return r;
if (!session_is_controller(s, sd_bus_message_get_sender(message)))
return sd_bus_reply_method_errorf(message, BUS_ERROR_NOT_IN_CONTROL, "You are not in control of this session");
return sd_bus_error_setf(error, BUS_ERROR_NOT_IN_CONTROL, "You are not in control of this session");
dev = makedev(major, minor);
sd = hashmap_get(s->devices, &dev);
if (!sd)
return sd_bus_reply_method_errorf(message, BUS_ERROR_DEVICE_NOT_TAKEN, "Device not taken");
return sd_bus_error_setf(error, BUS_ERROR_DEVICE_NOT_TAKEN, "Device not taken");
session_device_complete_pause(sd);

View File

@ -34,8 +34,8 @@ static int property_get_display(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
_cleanup_free_ char *p = NULL;
User *u = userdata;
@ -57,8 +57,8 @@ static int property_get_state(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
User *u = userdata;
@ -75,8 +75,8 @@ static int property_get_sessions(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
User *u = userdata;
Session *session;
@ -116,8 +116,8 @@ static int property_get_idle_hint(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
User *u = userdata;
@ -134,8 +134,8 @@ static int property_get_idle_since_hint(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
User *u = userdata;
dual_timestamp t;
@ -157,8 +157,8 @@ static int property_get_linger(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
User *u = userdata;
int r;
@ -172,7 +172,7 @@ static int property_get_linger(
return sd_bus_message_append(reply, "b", r > 0);
}
static int method_terminate(sd_bus *bus, sd_bus_message *message, void *userdata) {
static int method_terminate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
User *u = userdata;
int r;
@ -182,12 +182,12 @@ static int method_terminate(sd_bus *bus, sd_bus_message *message, void *userdata
r = user_stop(u);
if (r < 0)
return sd_bus_reply_method_errno(message, r, NULL);
return r;
return sd_bus_reply_method_return(message, NULL);
}
static int method_kill(sd_bus *bus, sd_bus_message *message, void *userdata) {
static int method_kill(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
User *u = userdata;
int32_t signo;
int r;
@ -198,14 +198,14 @@ static int method_kill(sd_bus *bus, sd_bus_message *message, void *userdata) {
r = sd_bus_message_read(message, "i", &signo);
if (r < 0)
return sd_bus_reply_method_errno(message, r, NULL);
return r;
if (signo <= 0 || signo >= _NSIG)
return sd_bus_reply_method_errorf(message, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo);
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo);
r = user_kill(u, signo);
if (r < 0)
return sd_bus_reply_method_errno(message, r, NULL);
return r;
return sd_bus_reply_method_return(message, NULL);
}

View File

@ -150,11 +150,11 @@ int manager_get_session_by_pid(Manager *m, pid_t pid, Session **session);
extern const sd_bus_vtable manager_vtable[];
int match_job_removed(sd_bus *bus, sd_bus_message *message, void *userdata);
int match_unit_removed(sd_bus *bus, sd_bus_message *message, void *userdata);
int match_properties_changed(sd_bus *bus, sd_bus_message *message, void *userdata);
int match_reloading(sd_bus *bus, sd_bus_message *message, void *userdata);
int match_name_owner_changed(sd_bus *bus, sd_bus_message *message, void *userdata);
int match_job_removed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error);
int match_unit_removed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error);
int match_properties_changed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error);
int match_reloading(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error);
int match_name_owner_changed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error);
int bus_manager_shutdown_or_sleep_now_or_later(Manager *m, const char *unit_name, InhibitWhat w, sd_bus_error *error);

View File

@ -32,8 +32,8 @@ static int property_get_id(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
Machine *m = userdata;
int r;
@ -55,8 +55,8 @@ static int property_get_state(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
Machine *m = userdata;
const char *state;
@ -77,7 +77,7 @@ static int property_get_state(
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_class, machine_class, MachineClass);
static int method_terminate(sd_bus *bus, sd_bus_message *message, void *userdata) {
static int method_terminate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
Machine *m = userdata;
int r;
@ -87,12 +87,12 @@ static int method_terminate(sd_bus *bus, sd_bus_message *message, void *userdata
r = machine_stop(m);
if (r < 0)
return sd_bus_reply_method_errno(message, r, NULL);
return r;
return sd_bus_reply_method_return(message, NULL);
}
static int method_kill(sd_bus *bus, sd_bus_message *message, void *userdata) {
static int method_kill(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
Machine *m = userdata;
const char *swho;
int32_t signo;
@ -105,22 +105,22 @@ static int method_kill(sd_bus *bus, sd_bus_message *message, void *userdata) {
r = sd_bus_message_read(message, "si", &swho, &signo);
if (r < 0)
return sd_bus_reply_method_errno(message, r, NULL);
return r;
if (isempty(swho))
who = KILL_ALL;
else {
who = kill_who_from_string(swho);
if (who < 0)
return sd_bus_reply_method_errorf(message, SD_BUS_ERROR_INVALID_ARGS, "Invalid kill parameter '%s'", swho);
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid kill parameter '%s'", swho);
}
if (signo <= 0 || signo >= _NSIG)
return sd_bus_reply_method_errorf(message, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo);
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo);
r = machine_kill(m, who, signo);
if (r < 0)
return sd_bus_reply_method_errno(message, r, NULL);
return r;
return sd_bus_reply_method_return(message, NULL);
}

View File

@ -58,7 +58,7 @@ static bool valid_machine_name(const char *p) {
return true;
}
static int method_get_machine(sd_bus *bus, sd_bus_message *message, void *userdata) {
static int method_get_machine(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
_cleanup_free_ char *p = NULL;
Manager *m = userdata;
Machine *machine;
@ -71,20 +71,20 @@ static int method_get_machine(sd_bus *bus, sd_bus_message *message, void *userda
r = sd_bus_message_read(message, "s", &name);
if (r < 0)
return sd_bus_reply_method_errno(message, r, NULL);
return r;
machine = hashmap_get(m->machines, name);
if (!machine)
return sd_bus_reply_method_errorf(message, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
p = machine_bus_path(machine);
if (!p)
return sd_bus_reply_method_errno(message, -ENOMEM, NULL);
return -ENOMEM;
return sd_bus_reply_method_return(message, "o", p);
}
static int method_get_machine_by_pid(sd_bus *bus, sd_bus_message *message, void *userdata) {
static int method_get_machine_by_pid(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
_cleanup_free_ char *p = NULL;
Manager *m = userdata;
Machine *machine = NULL;
@ -99,28 +99,28 @@ static int method_get_machine_by_pid(sd_bus *bus, sd_bus_message *message, void
r = sd_bus_message_read(message, "u", &pid);
if (r < 0)
return sd_bus_reply_method_errno(message, r, NULL);
return r;
if (pid == 0) {
r = sd_bus_get_owner_pid(bus, sd_bus_message_get_sender(message), &pid);
if (r < 0)
return sd_bus_reply_method_errno(message, r, NULL);
return r;
}
r = manager_get_machine_by_pid(m, pid, &machine);
if (r < 0)
return sd_bus_reply_method_errno(message, r, NULL);
return r;
if (!machine)
return sd_bus_reply_method_errorf(message, BUS_ERROR_NO_MACHINE_FOR_PID, "PID %lu does not belong to any known machine", (unsigned long) pid);
return sd_bus_error_setf(error, BUS_ERROR_NO_MACHINE_FOR_PID, "PID %lu does not belong to any known machine", (unsigned long) pid);
p = machine_bus_path(machine);
if (!p)
return sd_bus_reply_method_errno(message, -ENOMEM, NULL);
return -ENOMEM;
return sd_bus_reply_method_return(message, "o", p);
}
static int method_list_machines(sd_bus *bus, sd_bus_message *message, void *userdata) {
static int method_list_machines(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
_cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
Manager *m = userdata;
Machine *machine;
@ -133,18 +133,18 @@ static int method_list_machines(sd_bus *bus, sd_bus_message *message, void *user
r = sd_bus_message_new_method_return(message, &reply);
if (r < 0)
return sd_bus_reply_method_errno(message, r, NULL);
return sd_bus_error_set_errno(error, r);
r = sd_bus_message_open_container(reply, 'a', "(ssso)");
if (r < 0)
return sd_bus_reply_method_errno(message, r, NULL);
return sd_bus_error_set_errno(error, r);
HASHMAP_FOREACH(machine, m->machines, i) {
_cleanup_free_ char *p = NULL;
p = machine_bus_path(machine);
if (!p)
return sd_bus_reply_method_errno(message, -ENOMEM, NULL);
return -ENOMEM;
r = sd_bus_message_append(reply, "(ssso)",
machine->name,
@ -152,18 +152,17 @@ static int method_list_machines(sd_bus *bus, sd_bus_message *message, void *user
machine->service,
p);
if (r < 0)
return sd_bus_reply_method_errno(message, r, NULL);
return sd_bus_error_set_errno(error, r);
}
r = sd_bus_message_close_container(reply);
if (r < 0)
return sd_bus_reply_method_errno(message, r, NULL);
return sd_bus_error_set_errno(error, r);
return sd_bus_send(bus, reply, NULL);
}
static int method_create_machine(sd_bus *bus, sd_bus_message *message, void *userdata) {
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
static int method_create_machine(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
const char *name, *service, *class, *root_directory;
Manager *manager = userdata;
MachineClass c;
@ -180,56 +179,56 @@ static int method_create_machine(sd_bus *bus, sd_bus_message *message, void *use
r = sd_bus_message_read(message, "s", &name);
if (r < 0)
return sd_bus_reply_method_errno(message, r, NULL);
return r;
if (!valid_machine_name(name))
return sd_bus_reply_method_errorf(message, SD_BUS_ERROR_INVALID_ARGS, "Invalid machine name");
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid machine name");
r = sd_bus_message_read_array(message, 'y', &v, &n);
if (r < 0)
return sd_bus_reply_method_errno(message, r, NULL);
return r;
if (n == 0)
id = SD_ID128_NULL;
else if (n == 16)
memcpy(&id, v, n);
else
return sd_bus_reply_method_errorf(message, SD_BUS_ERROR_INVALID_ARGS, "Invalid machine ID parameter");
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid machine ID parameter");
r = sd_bus_message_read(message, "ssus", &service, &class, &leader, &root_directory);
if (r < 0)
return sd_bus_reply_method_errno(message, r, NULL);
return r;
if (isempty(class))
c = _MACHINE_CLASS_INVALID;
else {
c = machine_class_from_string(class);
if (c < 0)
return sd_bus_reply_method_errorf(message, SD_BUS_ERROR_INVALID_ARGS, "Invalid machine class parameter");
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid machine class parameter");
}
if (leader == 1)
return sd_bus_reply_method_errorf(message, SD_BUS_ERROR_INVALID_ARGS, "Invalid leader PID");
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid leader PID");
if (!isempty(root_directory) && !path_is_absolute(root_directory))
return sd_bus_reply_method_errorf(message, SD_BUS_ERROR_INVALID_ARGS, "Root directory must be empty or an absolute path");
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Root directory must be empty or an absolute path");
r = sd_bus_message_enter_container(message, 'a', "(sv)");
if (r < 0)
return sd_bus_reply_method_errno(message, r, NULL);
return r;
if (leader == 0) {
assert_cc(sizeof(uint32_t) == sizeof(pid_t));
r = sd_bus_get_owner_pid(bus, sd_bus_message_get_sender(message), (pid_t*) &leader);
if (r < 0)
return sd_bus_reply_method_errno(message, r, NULL);
return r;
}
if (hashmap_get(manager->machines, name))
return sd_bus_reply_method_errorf(message, BUS_ERROR_MACHINE_EXISTS, "Machine '%s' already exists", name);
return sd_bus_error_setf(error, BUS_ERROR_MACHINE_EXISTS, "Machine '%s' already exists", name);
r = manager_add_machine(manager, name, &m);
if (r < 0)
return sd_bus_reply_method_errno(message, r, NULL);
return r;
m->leader = leader;
m->class = c;
@ -238,7 +237,7 @@ static int method_create_machine(sd_bus *bus, sd_bus_message *message, void *use
if (!isempty(service)) {
m->service = strdup(service);
if (!m->service) {
r = sd_bus_reply_method_errno(message, -ENOMEM, NULL);
r = -ENOMEM;
goto fail;
}
}
@ -246,16 +245,14 @@ static int method_create_machine(sd_bus *bus, sd_bus_message *message, void *use
if (!isempty(root_directory)) {
m->root_directory = strdup(root_directory);
if (!m->root_directory) {
r = sd_bus_reply_method_errno(message, -ENOMEM, NULL);
r = -ENOMEM;
goto fail;
}
}
r = machine_start(m, message, &error);
if (r < 0) {
r = sd_bus_reply_method_errno(message, r, &error);
r = machine_start(m, message, error);
if (r < 0)
goto fail;
}
m->create_message = sd_bus_message_ref(message);
@ -267,7 +264,7 @@ fail:
return r;
}
static int method_terminate_machine(sd_bus *bus, sd_bus_message *message, void *userdata) {
static int method_terminate_machine(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
Manager *m = userdata;
Machine *machine;
const char *name;
@ -279,20 +276,20 @@ static int method_terminate_machine(sd_bus *bus, sd_bus_message *message, void *
r = sd_bus_message_read(message, "s", &name);
if (r < 0)
return sd_bus_reply_method_errno(message, r, NULL);
return sd_bus_error_set_errno(error, r);
machine = hashmap_get(m->machines, name);
if (!machine)
return sd_bus_reply_method_errorf(message, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
r = machine_stop(machine);
if (r < 0)
return sd_bus_reply_method_errno(message, r, NULL);
return sd_bus_error_set_errno(error, r);
return sd_bus_reply_method_return(message, NULL);
}
static int method_kill_machine(sd_bus *bus, sd_bus_message *message, void *userdata) {
static int method_kill_machine(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
Manager *m = userdata;
Machine *machine;
const char *name;
@ -307,26 +304,26 @@ static int method_kill_machine(sd_bus *bus, sd_bus_message *message, void *userd
r = sd_bus_message_read(message, "ssi", &name, &swho, &signo);
if (r < 0)
return sd_bus_reply_method_errno(message, r, NULL);
return sd_bus_error_set_errno(error, r);
if (isempty(swho))
who = KILL_ALL;
else {
who = kill_who_from_string(swho);
if (who < 0)
return sd_bus_reply_method_errorf(message, SD_BUS_ERROR_INVALID_ARGS, "Invalid kill parameter '%s'", swho);
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid kill parameter '%s'", swho);
}
if (signo <= 0 || signo >= _NSIG)
return sd_bus_reply_method_errorf(message, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo);
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo);
machine = hashmap_get(m->machines, name);
if (!machine)
return sd_bus_reply_method_errorf(message, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
r = machine_kill(machine, who, signo);
if (r < 0)
return sd_bus_reply_method_errno(message, r, NULL);
return sd_bus_error_set_errno(error, r);
return sd_bus_reply_method_return(message, NULL);
}
@ -344,7 +341,7 @@ const sd_bus_vtable manager_vtable[] = {
SD_BUS_VTABLE_END
};
int match_job_removed(sd_bus *bus, sd_bus_message *message, void *userdata) {
int match_job_removed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
const char *path, *result, *unit;
Manager *m = userdata;
Machine *machine;
@ -357,8 +354,8 @@ int match_job_removed(sd_bus *bus, sd_bus_message *message, void *userdata) {
r = sd_bus_message_read(message, "uoss", &id, &path, &unit, &result);
if (r < 0) {
log_error("Failed to parse JobRemoved message: %s", strerror(-r));
return 0;
bus_log_parse_error(r);
return r;
}
machine = hashmap_get(m->machine_units, unit);
@ -373,11 +370,11 @@ int match_job_removed(sd_bus *bus, sd_bus_message *message, void *userdata) {
if (streq(result, "done"))
machine_send_create_reply(machine, NULL);
else {
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_bus_error_free_ sd_bus_error e = SD_BUS_ERROR_NULL;
sd_bus_error_setf(&error, BUS_ERROR_JOB_FAILED, "Start job for unit %s failed with '%s'", unit, result);
sd_bus_error_setf(&e, BUS_ERROR_JOB_FAILED, "Start job for unit %s failed with '%s'", unit, result);
machine_send_create_reply(machine, &error);
machine_send_create_reply(machine, &e);
}
} else
machine_save(machine);
@ -387,11 +384,12 @@ int match_job_removed(sd_bus *bus, sd_bus_message *message, void *userdata) {
return 0;
}
int match_properties_changed(sd_bus *bus, sd_bus_message *message, void *userdata) {
int match_properties_changed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
_cleanup_free_ char *unit = NULL;
Manager *m = userdata;
Machine *machine;
const char *path;
int r;
assert(bus);
assert(message);
@ -401,9 +399,9 @@ int match_properties_changed(sd_bus *bus, sd_bus_message *message, void *userdat
if (!path)
return 0;
unit_name_from_dbus_path(path, &unit);
if (!unit)
return 0;
r = unit_name_from_dbus_path(path, &unit);
if (r < 0)
return r;
machine = hashmap_get(m->machine_units, unit);
if (machine)
@ -412,7 +410,7 @@ int match_properties_changed(sd_bus *bus, sd_bus_message *message, void *userdat
return 0;
}
int match_unit_removed(sd_bus *bus, sd_bus_message *message, void *userdata) {
int match_unit_removed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
const char *path, *unit;
Manager *m = userdata;
Machine *machine;
@ -424,8 +422,8 @@ int match_unit_removed(sd_bus *bus, sd_bus_message *message, void *userdata) {
r = sd_bus_message_read(message, "so", &unit, &path);
if (r < 0) {
log_error("Failed to parse UnitRemoved message: %s", strerror(-r));
return 0;
bus_log_parse_error(r);
return r;
}
machine = hashmap_get(m->machine_units, unit);
@ -435,7 +433,7 @@ int match_unit_removed(sd_bus *bus, sd_bus_message *message, void *userdata) {
return 0;
}
int match_reloading(sd_bus *bus, sd_bus_message *message, void *userdata) {
int match_reloading(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
Manager *m = userdata;
Machine *machine;
Iterator i;
@ -445,10 +443,9 @@ int match_reloading(sd_bus *bus, sd_bus_message *message, void *userdata) {
r = sd_bus_message_read(message, "b", &b);
if (r < 0) {
log_error("Failed to parse Reloading message: %s", strerror(-r));
return 0;
bus_log_parse_error(r);
return r;
}
if (b)
return 0;

View File

@ -62,10 +62,10 @@ extern const sd_bus_vtable manager_vtable[];
int machine_node_enumerator(sd_bus *bus, const char *path, char ***nodes, void *userdata);
int match_reloading(sd_bus *bus, sd_bus_message *message, void *userdata);
int match_unit_removed(sd_bus *bus, sd_bus_message *message, void *userdata);
int match_properties_changed(sd_bus *bus, sd_bus_message *message, void *userdata);
int match_job_removed(sd_bus *bus, sd_bus_message *message, void *userdata);
int match_reloading(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error);
int match_unit_removed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error);
int match_properties_changed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error);
int match_job_removed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error);
int manager_start_scope(Manager *manager, const char *scope, pid_t pid, const char *slice, const char *description, sd_bus_message *more_properties, sd_bus_error *error, char **job);
int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job);

View File

@ -1711,7 +1711,7 @@ typedef struct WaitData {
char *result;
} WaitData;
static int wait_filter(sd_bus *bus, sd_bus_message *m, void *data) {
static int wait_filter(sd_bus *bus, sd_bus_message *m, void *data, sd_bus_error *error) {
WaitData *d = data;
assert(bus);
@ -1764,7 +1764,7 @@ static int wait_filter(sd_bus *bus, sd_bus_message *m, void *data) {
}
#endif
log_error("Failed to parse message.");
bus_log_parse_error(r);
}
return 0;

View File

@ -46,9 +46,9 @@ typedef struct {
/* Callbacks */
typedef int (*sd_bus_message_handler_t)(sd_bus *bus, sd_bus_message *m, void *userdata);
typedef int (*sd_bus_property_get_t) (sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, sd_bus_error *error, void *userdata);
typedef int (*sd_bus_property_set_t) (sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *value, sd_bus_error *error, void *userdata);
typedef int (*sd_bus_message_handler_t)(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *ret_error);
typedef int (*sd_bus_property_get_t) (sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *ret_error);
typedef int (*sd_bus_property_set_t) (sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *value, void *userdata, sd_bus_error *ret_error);
typedef int (*sd_bus_object_find_t) (sd_bus *bus, const char *path, const char *interface, void **found, void *userdata);
typedef int (*sd_bus_node_enumerator_t) (sd_bus *bus, const char *path, char ***nodes, void *userdata);
@ -95,7 +95,7 @@ int sd_bus_get_server_id(sd_bus *bus, sd_id128_t *peer);
int sd_bus_send(sd_bus *bus, sd_bus_message *m, uint64_t *serial);
int sd_bus_send_to(sd_bus *bus, sd_bus_message *m, const char *destination, uint64_t *serial);
int sd_bus_call(sd_bus *bus, sd_bus_message *m, uint64_t usec, sd_bus_error *error, sd_bus_message **reply);
int sd_bus_call(sd_bus *bus, sd_bus_message *m, uint64_t usec, sd_bus_error *ret_error, sd_bus_message **reply);
int sd_bus_call_async(sd_bus *bus, sd_bus_message *m, sd_bus_message_handler_t callback, void *userdata, uint64_t usec, uint64_t *serial);
int sd_bus_call_async_cancel(sd_bus *bus, uint64_t serial);
@ -220,12 +220,12 @@ int sd_bus_message_rewind(sd_bus_message *m, int complete);
/* Convenience calls */
int sd_bus_call_method(sd_bus *bus, const char *destination, const char *path, const char *interface, const char *member, sd_bus_error *error, sd_bus_message **reply, const char *types, ...);
int sd_bus_get_property(sd_bus *bus, const char *destination, const char *path, const char *interface, const char *member, sd_bus_error *error, sd_bus_message **reply, const char *type);
int sd_bus_get_property_trivial(sd_bus *bus, const char *destination, const char *path, const char *interface, const char *member, sd_bus_error *error, char type, void *ptr);
int sd_bus_get_property_string(sd_bus *bus, const char *destination, const char *path, const char *interface, const char *member, sd_bus_error *error, char **ret); /* free the result! */
int sd_bus_get_property_strv(sd_bus *bus, const char *destination, const char *path, const char *interface, const char *member, sd_bus_error *error, char ***ret); /* free the result! */
int sd_bus_set_property(sd_bus *bus, const char *destination, const char *path, const char *interface, const char *member, sd_bus_error *error, const char *type, ...);
int sd_bus_call_method(sd_bus *bus, const char *destination, const char *path, const char *interface, const char *member, sd_bus_error *ret_error, sd_bus_message **reply, const char *types, ...);
int sd_bus_get_property(sd_bus *bus, const char *destination, const char *path, const char *interface, const char *member, sd_bus_error *ret_error, sd_bus_message **reply, const char *type);
int sd_bus_get_property_trivial(sd_bus *bus, const char *destination, const char *path, const char *interface, const char *member, sd_bus_error *ret_error, char type, void *ret_ptr);
int sd_bus_get_property_string(sd_bus *bus, const char *destination, const char *path, const char *interface, const char *member, sd_bus_error *ret_error, char **ret); /* free the result! */
int sd_bus_get_property_strv(sd_bus *bus, const char *destination, const char *path, const char *interface, const char *member, sd_bus_error *ret_error, char ***ret); /* free the result! */
int sd_bus_set_property(sd_bus *bus, const char *destination, const char *path, const char *interface, const char *member, sd_bus_error *ret_error, const char *ret_type, ...);
int sd_bus_reply_method_return(sd_bus_message *call, const char *types, ...);
int sd_bus_reply_method_error(sd_bus_message *call, const sd_bus_error *e);

View File

@ -458,8 +458,8 @@ static int property_get_rtc_time(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
struct tm tm;
usec_t t;
@ -470,17 +470,12 @@ static int property_get_rtc_time(
if (r == -EBUSY) {
log_warning("/dev/rtc is busy, is somebody keeping it open continously? That's not a good idea... Returning a bogus RTC timestamp.");
t = 0;
} else if (r < 0) {
sd_bus_error_set_errnof(error, -r, "Failed to read RTC: %s", strerror(-r));
return r;
} else
} else if (r < 0)
return sd_bus_error_set_errnof(error, r, "Failed to read RTC: %s", strerror(-r));
else
t = (usec_t) timegm(&tm) * USEC_PER_SEC;
r = sd_bus_message_append(reply, "t", t);
if (r < 0)
return r;
return 1;
return sd_bus_message_append(reply, "t", t);
}
static int property_get_time(
@ -489,16 +484,10 @@ static int property_get_time(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
int r;
r = sd_bus_message_append(reply, "t", now(CLOCK_REALTIME));
if (r < 0)
return r;
return 1;
return sd_bus_message_append(reply, "t", now(CLOCK_REALTIME));
}
static int property_get_ntp_sync(
@ -507,20 +496,13 @@ static int property_get_ntp_sync(
const char *interface,
const char *property,
sd_bus_message *reply,
sd_bus_error *error,
void *userdata) {
void *userdata,
sd_bus_error *error) {
int r;
r = sd_bus_message_append(reply, "b", ntp_synced());
if (r < 0)
return r;
return 1;
return sd_bus_message_append(reply, "b", ntp_synced());
}
static int method_set_timezone(sd_bus *bus, sd_bus_message *m, void *userdata) {
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
static int method_set_timezone(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
Context *c = userdata;
const char *z;
int interactive;
@ -533,23 +515,23 @@ static int method_set_timezone(sd_bus *bus, sd_bus_message *m, void *userdata) {
r = sd_bus_message_read(m, "sb", &z, &interactive);
if (r < 0)
return sd_bus_reply_method_errno(m, r, NULL);
return r;
if (!valid_timezone(z))
return sd_bus_reply_method_errorf(m, SD_BUS_ERROR_INVALID_ARGS, "Invalid time zone '%s'", z);
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid time zone '%s'", z);
if (streq_ptr(z, c->zone))
return sd_bus_reply_method_return(m, NULL);
r = bus_verify_polkit_async(bus, &c->polkit_registry, m, "org.freedesktop.timedate1.set-timezone", interactive, &error, method_set_timezone, c);
r = bus_verify_polkit_async(bus, &c->polkit_registry, m, "org.freedesktop.timedate1.set-timezone", interactive, error, method_set_timezone, c);
if (r < 0)
return sd_bus_reply_method_errno(m, r, &error);
return r;
if (r == 0)
return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
t = strdup(z);
if (!t)
return log_oom();
return -ENOMEM;
free(c->zone);
c->zone = t;
@ -558,7 +540,7 @@ static int method_set_timezone(sd_bus *bus, sd_bus_message *m, void *userdata) {
r = context_write_data_timezone(c);
if (r < 0) {
log_error("Failed to set timezone: %s", strerror(-r));
return sd_bus_reply_method_errnof(m, r, "Failed to set timezone: %s", strerror(-r));
return sd_bus_error_set_errnof(error, r, "Failed to set timezone: %s", strerror(-r));
}
/* 2. Tell the kernel our timezone */
@ -585,8 +567,7 @@ static int method_set_timezone(sd_bus *bus, sd_bus_message *m, void *userdata) {
return sd_bus_reply_method_return(m, NULL);
}
static int method_set_local_rtc(sd_bus *bus, sd_bus_message *m, void *userdata) {
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
static int method_set_local_rtc(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
int lrtc, fix_system, interactive;
Context *c = userdata;
struct timespec ts;
@ -598,14 +579,14 @@ static int method_set_local_rtc(sd_bus *bus, sd_bus_message *m, void *userdata)
r = sd_bus_message_read(m, "bbb", &lrtc, &fix_system, &interactive);
if (r < 0)
return sd_bus_reply_method_errno(m, r, NULL);
return r;
if (lrtc == c->local_rtc)
return sd_bus_reply_method_return(m, NULL);
r = bus_verify_polkit_async(bus, &c->polkit_registry, m, "org.freedesktop.timedate1.set-local-rtc", interactive, &error, method_set_local_rtc, c);
r = bus_verify_polkit_async(bus, &c->polkit_registry, m, "org.freedesktop.timedate1.set-local-rtc", interactive, error, method_set_local_rtc, c);
if (r < 0)
return sd_bus_reply_method_errno(m, r, &error);
return r;
if (r == 0)
return 1;
@ -615,7 +596,7 @@ static int method_set_local_rtc(sd_bus *bus, sd_bus_message *m, void *userdata)
r = context_write_data_local_rtc(c);
if (r < 0) {
log_error("Failed to set RTC to local/UTC: %s", strerror(-r));
return sd_bus_reply_method_errnof(m, r, "Failed to set RTC to local/UTC: %s", strerror(-r));
return sd_bus_error_set_errnof(error, r, "Failed to set RTC to local/UTC: %s", strerror(-r));
}
/* 2. Tell the kernel our timezone */
@ -669,8 +650,7 @@ static int method_set_local_rtc(sd_bus *bus, sd_bus_message *m, void *userdata)
return sd_bus_reply_method_return(m, NULL);
}
static int method_set_time(sd_bus *bus, sd_bus_message *m, void *userdata) {
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
static int method_set_time(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
int relative, interactive;
Context *c = userdata;
int64_t utc;
@ -684,10 +664,10 @@ static int method_set_time(sd_bus *bus, sd_bus_message *m, void *userdata) {
r = sd_bus_message_read(m, "xbb", &utc, &relative, &interactive);
if (r < 0)
return sd_bus_reply_method_errno(m, r, NULL);
return r;
if (!relative && utc <= 0)
return sd_bus_reply_method_errorf(m, SD_BUS_ERROR_INVALID_ARGS, "Invalid absolute time");
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid absolute time");
if (relative && utc == 0)
return sd_bus_reply_method_return(m, NULL);
@ -700,22 +680,22 @@ static int method_set_time(sd_bus *bus, sd_bus_message *m, void *userdata) {
if ((utc > 0 && x < n) ||
(utc < 0 && x > n))
return sd_bus_reply_method_errorf(m, SD_BUS_ERROR_INVALID_ARGS, "Time value overflow");
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Time value overflow");
timespec_store(&ts, x);
} else
timespec_store(&ts, (usec_t) utc);
r = bus_verify_polkit_async(bus, &c->polkit_registry, m, "org.freedesktop.timedate1.set-time", interactive, &error, method_set_time, c);
r = bus_verify_polkit_async(bus, &c->polkit_registry, m, "org.freedesktop.timedate1.set-time", interactive, error, method_set_time, c);
if (r < 0)
return sd_bus_reply_method_errno(m, r, &error);
return r;
if (r == 0)
return 1;
/* Set system clock */
if (clock_settime(CLOCK_REALTIME, &ts) < 0) {
log_error("Failed to set local time: %m");
return sd_bus_reply_method_errnof(m, errno, "Failed to set local time: %m");
return sd_bus_error_set_errnof(error, errno, "Failed to set local time: %m");
}
/* Sync down to RTC */
@ -735,34 +715,33 @@ static int method_set_time(sd_bus *bus, sd_bus_message *m, void *userdata) {
return sd_bus_reply_method_return(m, NULL);
}
static int method_set_ntp(sd_bus *bus, sd_bus_message *m, void *userdata) {
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
static int method_set_ntp(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
int ntp, interactive;
Context *c = userdata;
int r;
r = sd_bus_message_read(m, "bb", &ntp, &interactive);
if (r < 0)
return sd_bus_reply_method_errno(m, r, NULL);
return r;
if ((bool)ntp == c->use_ntp)
return sd_bus_reply_method_return(m, NULL);
r = bus_verify_polkit_async(bus, &c->polkit_registry, m, "org.freedesktop.timedate1.set-ntp", interactive, &error, method_set_ntp, c);
r = bus_verify_polkit_async(bus, &c->polkit_registry, m, "org.freedesktop.timedate1.set-ntp", interactive, error, method_set_ntp, c);
if (r < 0)
return sd_bus_reply_method_errno(m, r, &error);
return r;
if (r == 0)
return 1;
c->use_ntp = ntp;
r = context_enable_ntp(c, bus, &error);
r = context_enable_ntp(c, bus, error);
if (r < 0)
return sd_bus_reply_method_errno(m, r, &error);
return r;
r = context_start_ntp(c, bus, &error);
r = context_start_ntp(c, bus, error);
if (r < 0)
return sd_bus_reply_method_errno(m, r, &error);
return r;
log_info("Set NTP to %s", c->use_ntp ? "enabled" : "disabled");