dbus-execute.c revision c7040b5d1c2c148f12b6a5eef3dfce1661805131
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews/***
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews This file is part of systemd.
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews Copyright 2010 Lennart Poettering
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews systemd is free software; you can redistribute it and/or modify it
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews under the terms of the GNU Lesser General Public License as published by
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews the Free Software Foundation; either version 2.1 of the License, or
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews (at your option) any later version.
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews systemd is distributed in the hope that it will be useful, but
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews WITHOUT ANY WARRANTY; without even the implied warranty of
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews Lesser General Public License for more details.
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
deaaf94332abbfdb3aff53675546acfed16e5eb6Mark Andrews You should have received a copy of the GNU Lesser General Public License
3761c433912beabe43abeed2c3513b6201c59f64Mark Andrews along with systemd; If not, see <http://www.gnu.org/licenses/>.
f7b99290c31abeb20c55fc55391510450ce60423Mark Andrews***/
f7b99290c31abeb20c55fc55391510450ce60423Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#include <sys/prctl.h>
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#include "bus-util.h"
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#include "missing.h"
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#include "ioprio.h"
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#include "strv.h"
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#include "syscall-list.h"
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#include "fileio.h"
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#include "execute.h"
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews#include "dbus-execute.h"
f7b99290c31abeb20c55fc55391510450ce60423Mark Andrews#include "capability.h"
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#include "env-util.h"
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
deaaf94332abbfdb3aff53675546acfed16e5eb6Mark AndrewsBUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_exec_output, exec_output, ExecOutput);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsstatic BUS_DEFINE_PROPERTY_GET_ENUM(property_get_exec_input, exec_input, ExecInput);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsstatic int property_get_environment_files(
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews sd_bus *bus,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews const char *path,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews const char *interface,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews const char *property,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews sd_bus_message *reply,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews void *userdata,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews sd_bus_error *error) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews ExecContext *c = userdata;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews char **j;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews int r;
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews assert(bus);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews assert(reply);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews assert(c);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews r = sd_bus_message_open_container(reply, 'a', "(sb)");
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (r < 0)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return r;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews STRV_FOREACH(j, c->environment_files) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews const char *fn = *j;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews r = sd_bus_message_append(reply, "(sb)", fn[0] == '-' ? fn + 1 : fn, fn[0] == '-');
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (r < 0)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return r;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews }
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews return sd_bus_message_close_container(reply);
f7b99290c31abeb20c55fc55391510450ce60423Mark Andrews}
f7b99290c31abeb20c55fc55391510450ce60423Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsstatic int property_get_rlimit(
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews sd_bus *bus,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews const char *path,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews const char *interface,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews const char *property,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews sd_bus_message *reply,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews void *userdata,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews sd_bus_error *error) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews struct rlimit *rl;
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews uint64_t u;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews assert(bus);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews assert(reply);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews assert(userdata);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews rl = *(struct rlimit**) userdata;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (rl)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews u = (uint64_t) rl->rlim_max;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews else {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews struct rlimit buf = {};
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews int z;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews z = rlimit_from_string(property);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews assert(z >= 0);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews getrlimit(z, &buf);
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews u = (uint64_t) buf.rlim_max;
f7b99290c31abeb20c55fc55391510450ce60423Mark Andrews }
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return sd_bus_message_append(reply, "t", u);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews}
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsstatic int property_get_oom_score_adjust(
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews sd_bus *bus,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews const char *path,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews const char *interface,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews const char *property,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews sd_bus_message *reply,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews void *userdata,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews sd_bus_error *error) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews ExecContext *c = userdata;
f7b99290c31abeb20c55fc55391510450ce60423Mark Andrews int32_t n;
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews
f7b99290c31abeb20c55fc55391510450ce60423Mark Andrews assert(bus);
f7b99290c31abeb20c55fc55391510450ce60423Mark Andrews assert(reply);
f7b99290c31abeb20c55fc55391510450ce60423Mark Andrews assert(c);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (c->oom_score_adjust_set)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews n = c->oom_score_adjust;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews else {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews _cleanup_free_ char *t = NULL;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews n = 0;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (read_one_line_file("/proc/self/oom_score_adj", &t) >= 0)
f7b99290c31abeb20c55fc55391510450ce60423Mark Andrews safe_atoi(t, &n);
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews }
f7b99290c31abeb20c55fc55391510450ce60423Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return sd_bus_message_append(reply, "i", n);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews}
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsstatic int property_get_nice(
f7b99290c31abeb20c55fc55391510450ce60423Mark Andrews sd_bus *bus,
const char *path,
const char *interface,
const char *property,
sd_bus_message *reply,
void *userdata,
sd_bus_error *error) {
ExecContext *c = userdata;
int32_t n;
assert(bus);
assert(reply);
assert(c);
if (c->nice_set)
n = c->nice;
else {
errno = 0;
n = getpriority(PRIO_PROCESS, 0);
if (errno != 0)
n = 0;
}
return sd_bus_message_append(reply, "i", n);
}
static int property_get_ioprio(
sd_bus *bus,
const char *path,
const char *interface,
const char *property,
sd_bus_message *reply,
void *userdata,
sd_bus_error *error) {
ExecContext *c = userdata;
int32_t n;
assert(bus);
assert(reply);
assert(c);
if (c->ioprio_set)
n = c->ioprio;
else {
n = ioprio_get(IOPRIO_WHO_PROCESS, 0);
if (n < 0)
n = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 4);
}
return sd_bus_message_append(reply, "i", n);
}
static int property_get_cpu_sched_policy(
sd_bus *bus,
const char *path,
const char *interface,
const char *property,
sd_bus_message *reply,
void *userdata,
sd_bus_error *error) {
ExecContext *c = userdata;
int32_t n;
assert(bus);
assert(reply);
assert(c);
if (c->cpu_sched_set)
n = c->cpu_sched_policy;
else {
n = sched_getscheduler(0);
if (n < 0)
n = SCHED_OTHER;
}
return sd_bus_message_append(reply, "i", n);
}
static int property_get_cpu_sched_priority(
sd_bus *bus,
const char *path,
const char *interface,
const char *property,
sd_bus_message *reply,
void *userdata,
sd_bus_error *error) {
ExecContext *c = userdata;
int32_t n;
assert(bus);
assert(reply);
assert(c);
if (c->cpu_sched_set)
n = c->cpu_sched_priority;
else {
struct sched_param p = {};
if (sched_getparam(0, &p) >= 0)
n = p.sched_priority;
else
n = 0;
}
return sd_bus_message_append(reply, "i", n);
}
static int property_get_cpu_affinity(
sd_bus *bus,
const char *path,
const char *interface,
const char *property,
sd_bus_message *reply,
void *userdata,
sd_bus_error *error) {
ExecContext *c = userdata;
assert(bus);
assert(reply);
assert(c);
if (c->cpuset)
return sd_bus_message_append_array(reply, 'y', c->cpuset, CPU_ALLOC_SIZE(c->cpuset_ncpus));
else
return sd_bus_message_append_array(reply, 'y', NULL, 0);
}
static int property_get_timer_slack_nsec(
sd_bus *bus,
const char *path,
const char *interface,
const char *property,
sd_bus_message *reply,
void *userdata,
sd_bus_error *error) {
ExecContext *c = userdata;
uint64_t u;
assert(bus);
assert(reply);
assert(c);
if (c->timer_slack_nsec != (nsec_t) -1)
u = (uint64_t) c->timer_slack_nsec;
else
u = (uint64_t) prctl(PR_GET_TIMERSLACK);
return sd_bus_message_append(reply, "t", u);
}
static int property_get_capability_bounding_set(
sd_bus *bus,
const char *path,
const char *interface,
const char *property,
sd_bus_message *reply,
void *userdata,
sd_bus_error *error) {
ExecContext *c = userdata;
assert(bus);
assert(reply);
assert(c);
/* We store this negated internally, to match the kernel, but
* we expose it normalized. */
return sd_bus_message_append(reply, "t", ~c->capability_bounding_set_drop);
}
static int property_get_capabilities(
sd_bus *bus,
const char *path,
const char *interface,
const char *property,
sd_bus_message *reply,
void *userdata,
sd_bus_error *error) {
ExecContext *c = userdata;
_cleanup_cap_free_charp_ char *t = NULL;
const char *s;
assert(bus);
assert(reply);
assert(c);
if (c->capabilities)
s = t = cap_to_text(c->capabilities, NULL);
else
s = "";
if (!s)
return -ENOMEM;
return sd_bus_message_append(reply, "s", s);
}
static int property_get_syscall_filter(
sd_bus *bus,
const char *path,
const char *interface,
const char *property,
sd_bus_message *reply,
void *userdata,
sd_bus_error *error) {
ExecContext *c = userdata;
assert(bus);
assert(reply);
assert(c);
if (c->syscall_filter)
return sd_bus_message_append_array(reply, 'u', c->syscall_filter, (syscall_max() + 31) >> 4);
else
return sd_bus_message_append_array(reply, 'u', NULL, 0);
}
const sd_bus_vtable bus_exec_vtable[] = {
SD_BUS_VTABLE_START(0),
SD_BUS_PROPERTY("Environment", "as", NULL, offsetof(ExecContext, environment), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("EnvironmentFiles", "a(sb)", property_get_environment_files, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("UMask", "u", bus_property_get_mode, offsetof(ExecContext, umask), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("LimitCPU", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_CPU]), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("LimitFSIZE", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_FSIZE]), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("LimitDATA", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_DATA]), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("LimitSTACK", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_STACK]), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("LimitCORE", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_CORE]), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("LimitRSS", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RSS]), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("LimitNOFILE", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NOFILE]), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("LimitAS", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_AS]), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("LimitNPROC", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NPROC]), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("LimitMEMLOCK", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_MEMLOCK]), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("LimitLOCKS", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_LOCKS]), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("LimitSIGPENDING", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_SIGPENDING]), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("LimitMSGQUEUE", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_MSGQUEUE]), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("LimitNICE", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NICE]), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("LimitRTPRIO", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RTPRIO]), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("LimitRTTIME", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RTTIME]), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("WorkingDirectory", "s", NULL, offsetof(ExecContext, working_directory), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("RootDirectory", "s", NULL, offsetof(ExecContext, root_directory), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("OOMScoreAdjust", "i", property_get_oom_score_adjust, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Nice", "i", property_get_nice, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("IOScheduling", "i", property_get_ioprio, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("CPUSchedulingPolicy", "i", property_get_cpu_sched_policy, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("CPUSchedulingPriority", "i", property_get_cpu_sched_priority, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("CPUAffinity", "ay", property_get_cpu_affinity, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("TimerSlackNSec", "t", property_get_timer_slack_nsec, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("CPUSchedulingResetOnFork", "b", bus_property_get_bool, offsetof(ExecContext, cpu_sched_reset_on_fork), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("NonBlocking", "b", bus_property_get_bool, offsetof(ExecContext, non_blocking), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("StandardInput", "s", property_get_exec_input, offsetof(ExecContext, std_input), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("StandardOutput", "s", bus_property_get_exec_output, offsetof(ExecContext, std_output), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("StandardError", "s", bus_property_get_exec_output, offsetof(ExecContext, std_error), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("TTYPath", "s", NULL, offsetof(ExecContext, tty_path), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("TTYReset", "b", bus_property_get_bool, offsetof(ExecContext, tty_reset), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("TTYVHangup", "b", bus_property_get_bool, offsetof(ExecContext, tty_vhangup), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("TTYVTDisallocate", "b", bus_property_get_bool, offsetof(ExecContext, tty_vt_disallocate), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("SyslogPriority", "i", bus_property_get_int, offsetof(ExecContext, syslog_priority), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("SyslogIdentifier", "s", NULL, offsetof(ExecContext, syslog_identifier), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("SyslogLevelPrefix", "b", bus_property_get_bool, offsetof(ExecContext, syslog_level_prefix), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Capabilities", "s", property_get_capabilities, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("SecureBits", "i", bus_property_get_int, offsetof(ExecContext, secure_bits), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("CapabilityBoundingSet", "t", property_get_capability_bounding_set, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("User", "s", NULL, offsetof(ExecContext, user), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Group", "s", NULL, offsetof(ExecContext, group), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("SupplementaryGroups", "as", NULL, offsetof(ExecContext, supplementary_groups), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("TCPWrapName", "s", NULL, offsetof(ExecContext, tcpwrap_name), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("PAMName", "s", NULL, offsetof(ExecContext, pam_name), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("ReadWriteDirectories", "as", NULL, offsetof(ExecContext, read_write_dirs), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("ReadOnlyDirectories", "as", NULL, offsetof(ExecContext, read_only_dirs), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("InaccessibleDirectories", "as", NULL, offsetof(ExecContext, inaccessible_dirs), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("MountFlags", "t", bus_property_get_ulong, offsetof(ExecContext, mount_flags), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("PrivateTmp", "b", bus_property_get_bool, offsetof(ExecContext, private_tmp), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("PrivateNetwork", "b", bus_property_get_bool, offsetof(ExecContext, private_network), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("PrivateDevices", "b", bus_property_get_bool, offsetof(ExecContext, private_devices), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("SameProcessGroup", "b", bus_property_get_bool, offsetof(ExecContext, same_pgrp), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("UtmpIdentifier", "s", NULL, offsetof(ExecContext, utmp_id), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("IgnoreSIGPIPE", "b", bus_property_get_bool, offsetof(ExecContext, ignore_sigpipe), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("NoNewPrivileges", "b", bus_property_get_bool, offsetof(ExecContext, no_new_privileges), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("SystemCallFilter", "au", property_get_syscall_filter, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_VTABLE_END
};
static int append_exec_command(sd_bus_message *reply, ExecCommand *c) {
int r;
assert(reply);
assert(c);
if (!c->path)
return 0;
r = sd_bus_message_open_container(reply, 'r', "sasbttttuii");
if (r < 0)
return r;
r = sd_bus_message_append(reply, "s", c->path);
if (r < 0)
return r;
r = sd_bus_message_append_strv(reply, c->argv);
if (r < 0)
return r;
r = sd_bus_message_append(reply, "bttttuii",
c->ignore,
c->exec_status.start_timestamp.realtime,
c->exec_status.start_timestamp.monotonic,
c->exec_status.exit_timestamp.realtime,
c->exec_status.exit_timestamp.monotonic,
(uint32_t) c->exec_status.pid,
(int32_t) c->exec_status.code,
(int32_t) c->exec_status.status);
if (r < 0)
return r;
return sd_bus_message_close_container(reply);
}
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) {
ExecCommand *c = (ExecCommand*) userdata;
int r;
assert(bus);
assert(reply);
r = sd_bus_message_open_container(reply, 'a', "(sasbttttuii)");
if (r < 0)
return r;
r = append_exec_command(reply, c);
if (r < 0)
return r;
return sd_bus_message_close_container(reply);
}
int bus_property_get_exec_command_list(
sd_bus *bus,
const char *path,
const char *interface,
const char *property,
sd_bus_message *reply,
void *userdata,
sd_bus_error *ret_error) {
ExecCommand *c = *(ExecCommand**) userdata;
int r;
assert(bus);
assert(reply);
r = sd_bus_message_open_container(reply, 'a', "(sasbttttuii)");
if (r < 0)
return r;
LIST_FOREACH(command, c, c) {
r = append_exec_command(reply, c);
if (r < 0)
return r;
}
return sd_bus_message_close_container(reply);
}
int bus_exec_context_set_transient_property(
Unit *u,
ExecContext *c,
const char *name,
sd_bus_message *message,
UnitSetPropertiesMode mode,
sd_bus_error *error) {
int r;
assert(u);
assert(c);
assert(name);
assert(message);
if (streq(name, "User")) {
const char *uu;
r = sd_bus_message_read(message, "s", &uu);
if (r < 0)
return r;
if (mode != UNIT_CHECK) {
if (isempty(uu)) {
free(c->user);
c->user = NULL;
} else {
char *t;
t = strdup(uu);
if (!t)
return -ENOMEM;
free(c->user);
c->user = t;
}
unit_write_drop_in_private_format(u, mode, name, "User=%s\n", uu);
}
return 1;
} else if (streq(name, "Group")) {
const char *gg;
r = sd_bus_message_read(message, "s", &gg);
if (r < 0)
return r;
if (mode != UNIT_CHECK) {
if (isempty(gg)) {
free(c->group);
c->group = NULL;
} else {
char *t;
t = strdup(gg);
if (!t)
return -ENOMEM;
free(c->group);
c->group = t;
}
unit_write_drop_in_private_format(u, mode, name, "Group=%s\n", gg);
}
return 1;
} else if (streq(name, "Nice")) {
int n;
r = sd_bus_message_read(message, "i", &n);
if (r < 0)
return r;
if (n < PRIO_MIN || n >= PRIO_MAX)
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Nice value out of range");
if (mode != UNIT_CHECK) {
c->nice = n;
unit_write_drop_in_private_format(u, mode, name, "Nice=%i\n", n);
}
return 1;
} else if (streq(name, "Environment")) {
_cleanup_strv_free_ char **l = NULL;
r = sd_bus_message_read_strv(message, &l);
if (r < 0)
return r;
if (!strv_env_is_valid(l))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment block.");
if (mode != UNIT_CHECK) {
_cleanup_free_ char *joined;
char **e;
e = strv_env_merge(2, c->environment, l);
if (!e)
return -ENOMEM;
strv_free(c->environment);
c->environment = e;
joined = strv_join(c->environment, " ");
if (!joined)
return -ENOMEM;
unit_write_drop_in_private_format(u, mode, name, "Environment=%s\n", joined);
}
return 1;
}
return 0;
}