1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
22 #include <sys/prctl.h>
28 #include "syscall-list.h"
31 #include "dbus-execute.h"
33 BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_exec_output, exec_output, ExecOutput);
35 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_exec_input, exec_input, ExecInput);
37 static int property_get_environment_files(
40 const char *interface,
42 sd_bus_message *reply,
44 sd_bus_error *error) {
46 ExecContext *c = userdata;
54 r = sd_bus_message_open_container(reply, 'a', "(sb)");
58 STRV_FOREACH(j, c->environment_files) {
61 r = sd_bus_message_append(reply, "(sb)", fn[0] == '-' ? fn + 1 : fn, fn[0] == '-');
66 return sd_bus_message_close_container(reply);
69 static int property_get_rlimit(
72 const char *interface,
74 sd_bus_message *reply,
76 sd_bus_error *error) {
85 rl = *(struct rlimit**) userdata;
87 u = (uint64_t) rl->rlim_max;
89 struct rlimit buf = {};
92 z = rlimit_from_string(property);
97 u = (uint64_t) buf.rlim_max;
100 return sd_bus_message_append(reply, "t", u);
103 static int property_get_oom_score_adjust(
106 const char *interface,
107 const char *property,
108 sd_bus_message *reply,
110 sd_bus_error *error) {
113 ExecContext *c = userdata;
120 if (c->oom_score_adjust_set)
121 n = c->oom_score_adjust;
123 _cleanup_free_ char *t = NULL;
126 if (read_one_line_file("/proc/self/oom_score_adj", &t) >= 0)
130 return sd_bus_message_append(reply, "i", n);
133 static int property_get_nice(
136 const char *interface,
137 const char *property,
138 sd_bus_message *reply,
140 sd_bus_error *error) {
143 ExecContext *c = userdata;
154 n = getpriority(PRIO_PROCESS, 0);
159 return sd_bus_message_append(reply, "i", n);
162 static int property_get_ioprio(
165 const char *interface,
166 const char *property,
167 sd_bus_message *reply,
169 sd_bus_error *error) {
172 ExecContext *c = userdata;
182 n = ioprio_get(IOPRIO_WHO_PROCESS, 0);
184 n = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 4);
187 return sd_bus_message_append(reply, "i", n);
190 static int property_get_cpu_sched_policy(
193 const char *interface,
194 const char *property,
195 sd_bus_message *reply,
197 sd_bus_error *error) {
199 ExecContext *c = userdata;
206 if (c->cpu_sched_set)
207 n = c->cpu_sched_policy;
209 n = sched_getscheduler(0);
214 return sd_bus_message_append(reply, "i", n);
217 static int property_get_cpu_sched_priority(
220 const char *interface,
221 const char *property,
222 sd_bus_message *reply,
224 sd_bus_error *error) {
226 ExecContext *c = userdata;
233 if (c->cpu_sched_set)
234 n = c->cpu_sched_priority;
236 struct sched_param p = {};
238 if (sched_getparam(0, &p) >= 0)
239 n = p.sched_priority;
244 return sd_bus_message_append(reply, "i", n);
247 static int property_get_cpu_affinity(
250 const char *interface,
251 const char *property,
252 sd_bus_message *reply,
254 sd_bus_error *error) {
256 ExecContext *c = userdata;
263 return sd_bus_message_append_array(reply, 'y', c->cpuset, CPU_ALLOC_SIZE(c->cpuset_ncpus));
265 return sd_bus_message_append_array(reply, 'y', NULL, 0);
268 static int property_get_timer_slack_nsec(
271 const char *interface,
272 const char *property,
273 sd_bus_message *reply,
275 sd_bus_error *error) {
277 ExecContext *c = userdata;
284 if (c->timer_slack_nsec != (nsec_t) -1)
285 u = (uint64_t) c->timer_slack_nsec;
287 u = (uint64_t) prctl(PR_GET_TIMERSLACK);
289 return sd_bus_message_append(reply, "t", u);
292 static int property_get_capability_bounding_set(
295 const char *interface,
296 const char *property,
297 sd_bus_message *reply,
299 sd_bus_error *error) {
301 ExecContext *c = userdata;
307 /* We store this negated internally, to match the kernel, but
308 * we expose it normalized. */
309 return sd_bus_message_append(reply, "t", ~c->capability_bounding_set_drop);
312 static int property_get_capabilities(
315 const char *interface,
316 const char *property,
317 sd_bus_message *reply,
319 sd_bus_error *error) {
321 ExecContext *c = userdata;
331 s = t = cap_to_text(c->capabilities, NULL);
338 r = sd_bus_message_append(reply, "s", s);
346 static int property_get_syscall_filter(
349 const char *interface,
350 const char *property,
351 sd_bus_message *reply,
353 sd_bus_error *error) {
355 ExecContext *c = userdata;
361 if (c->syscall_filter)
362 return sd_bus_message_append_array(reply, 'u', c->syscall_filter, (syscall_max() + 31) >> 4);
364 return sd_bus_message_append_array(reply, 'u', NULL, 0);
367 const sd_bus_vtable bus_exec_vtable[] = {
368 SD_BUS_VTABLE_START(0),
369 SD_BUS_PROPERTY("Environment", "as", NULL, offsetof(ExecContext, environment), 0),
370 SD_BUS_PROPERTY("EnvironmentFiles", "a(sb)", property_get_environment_files, 0, 0),
371 SD_BUS_PROPERTY("UMask", "u", bus_property_get_mode, offsetof(ExecContext, umask), 0),
372 SD_BUS_PROPERTY("LimitCPU", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_CPU]), 0),
373 SD_BUS_PROPERTY("LimitFSIZE", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_FSIZE]), 0),
374 SD_BUS_PROPERTY("LimitDATA", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_DATA]), 0),
375 SD_BUS_PROPERTY("LimitSTACK", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_STACK]), 0),
376 SD_BUS_PROPERTY("LimitCORE", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_CORE]), 0),
377 SD_BUS_PROPERTY("LimitRSS", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RSS]), 0),
378 SD_BUS_PROPERTY("LimitNOFILE", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NOFILE]), 0),
379 SD_BUS_PROPERTY("LimitAS", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_AS]), 0),
380 SD_BUS_PROPERTY("LimitNPROC", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NPROC]), 0),
381 SD_BUS_PROPERTY("LimitMEMLOCK", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_MEMLOCK]), 0),
382 SD_BUS_PROPERTY("LimitLOCKS", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_LOCKS]), 0),
383 SD_BUS_PROPERTY("LimitSIGPENDING", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_SIGPENDING]), 0),
384 SD_BUS_PROPERTY("LimitMSGQUEUE", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_MSGQUEUE]), 0),
385 SD_BUS_PROPERTY("LimitNICE", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NICE]), 0),
386 SD_BUS_PROPERTY("LimitRTPRIO", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RTPRIO]), 0),
387 SD_BUS_PROPERTY("LimitRTTIME", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RTTIME]), 0),
388 SD_BUS_PROPERTY("WorkingDirectory", "s", NULL, offsetof(ExecContext, working_directory), 0),
389 SD_BUS_PROPERTY("RootDirectory", "s", NULL, offsetof(ExecContext, root_directory), 0),
390 SD_BUS_PROPERTY("OOMScoreAdjust", "i", property_get_oom_score_adjust, 0, 0),
391 SD_BUS_PROPERTY("Nice", "i", property_get_nice, 0, 0),
392 SD_BUS_PROPERTY("IOScheduling", "i", property_get_ioprio, 0, 0),
393 SD_BUS_PROPERTY("CPUSchedulingPolicy", "i", property_get_cpu_sched_policy, 0, 0),
394 SD_BUS_PROPERTY("CPUSchedulingPriority", "i", property_get_cpu_sched_priority, 0, 0),
395 SD_BUS_PROPERTY("CPUAffinity", "ay", property_get_cpu_affinity, 0, 0),
396 SD_BUS_PROPERTY("TimerSlackNSec", "t", property_get_timer_slack_nsec, 0, 0),
397 SD_BUS_PROPERTY("CPUSchedulingResetOnFork", "b", bus_property_get_bool, offsetof(ExecContext, cpu_sched_reset_on_fork), 0),
398 SD_BUS_PROPERTY("NonBlocking", "b", bus_property_get_bool, offsetof(ExecContext, non_blocking), 0),
399 SD_BUS_PROPERTY("StandardInput", "s", property_get_exec_input, offsetof(ExecContext, std_input), 0),
400 SD_BUS_PROPERTY("StandardOutput", "s", bus_property_get_exec_output, offsetof(ExecContext, std_output), 0),
401 SD_BUS_PROPERTY("StandardError", "s", bus_property_get_exec_output, offsetof(ExecContext, std_error), 0),
402 SD_BUS_PROPERTY("TTYPath", "s", NULL, offsetof(ExecContext, tty_path), 0),
403 SD_BUS_PROPERTY("TTYReset", "b", bus_property_get_bool, offsetof(ExecContext, tty_reset), 0),
404 SD_BUS_PROPERTY("TTYVHangup", "b", bus_property_get_bool, offsetof(ExecContext, tty_vhangup), 0),
405 SD_BUS_PROPERTY("TTYVTDisallocate", "b", bus_property_get_bool, offsetof(ExecContext, tty_vt_disallocate), 0),
406 SD_BUS_PROPERTY("SyslogPriority", "i", bus_property_get_int, offsetof(ExecContext, syslog_priority), 0),
407 SD_BUS_PROPERTY("SyslogIdentifier", "s", NULL, offsetof(ExecContext, syslog_identifier), 0),
408 SD_BUS_PROPERTY("SyslogLevelPrefix", "b", bus_property_get_bool, offsetof(ExecContext, syslog_level_prefix), 0),
409 SD_BUS_PROPERTY("Capabilities", "s", property_get_capabilities, 0, 0),
410 SD_BUS_PROPERTY("SecureBits", "i", bus_property_get_int, offsetof(ExecContext, secure_bits), 0),
411 SD_BUS_PROPERTY("CapabilityBoundingSet", "t", property_get_capability_bounding_set, 0, 0),
412 SD_BUS_PROPERTY("User", "s", NULL, offsetof(ExecContext, user), 0),
413 SD_BUS_PROPERTY("Group", "s", NULL, offsetof(ExecContext, group), 0),
414 SD_BUS_PROPERTY("SupplementaryGroups", "as", NULL, offsetof(ExecContext, supplementary_groups), 0),
415 SD_BUS_PROPERTY("TCPWrapName", "s", NULL, offsetof(ExecContext, tcpwrap_name), 0),
416 SD_BUS_PROPERTY("PAMName", "s", NULL, offsetof(ExecContext, pam_name), 0),
417 SD_BUS_PROPERTY("ReadWriteDirectories", "as", NULL, offsetof(ExecContext, read_write_dirs), 0),
418 SD_BUS_PROPERTY("ReadOnlyDirectories", "as", NULL, offsetof(ExecContext, read_only_dirs), 0),
419 SD_BUS_PROPERTY("InaccessibleDirectories", "as", NULL, offsetof(ExecContext, inaccessible_dirs), 0),
420 SD_BUS_PROPERTY("MountFlags", "t", bus_property_get_ulong, offsetof(ExecContext, mount_flags), 0),
421 SD_BUS_PROPERTY("PrivateTmp", "b", bus_property_get_bool, offsetof(ExecContext, private_tmp), 0),
422 SD_BUS_PROPERTY("PrivateNetwork", "b", bus_property_get_bool, offsetof(ExecContext, private_network), 0),
423 SD_BUS_PROPERTY("SameProcessGroup", "b", bus_property_get_bool, offsetof(ExecContext, same_pgrp), 0),
424 SD_BUS_PROPERTY("UtmpIdentifier", "s", NULL, offsetof(ExecContext, utmp_id), 0),
425 SD_BUS_PROPERTY("IgnoreSIGPIPE", "b", bus_property_get_bool, offsetof(ExecContext, ignore_sigpipe), 0),
426 SD_BUS_PROPERTY("NoNewPrivileges", "b", bus_property_get_bool, offsetof(ExecContext, no_new_privileges), 0),
427 SD_BUS_PROPERTY("SystemCallFilter", "au", property_get_syscall_filter, 0, 0),
431 int bus_property_get_exec_command(
434 const char *interface,
435 const char *property,
436 sd_bus_message *reply,
438 sd_bus_error *ret_error) {
440 ExecCommand *c = *(ExecCommand**) userdata;
446 r = sd_bus_message_open_container(reply, 'a', "(sasbttttuii)");
450 LIST_FOREACH(command, c, c) {
454 r = sd_bus_message_open_container(reply, 'r', "sasbttttuii");
458 r = sd_bus_message_append(reply, "s", c->path);
462 r = sd_bus_message_append_strv(reply, c->argv);
466 r = sd_bus_message_append(reply, "bttttuii",
468 c->exec_status.start_timestamp.realtime,
469 c->exec_status.start_timestamp.monotonic,
470 c->exec_status.exit_timestamp.realtime,
471 c->exec_status.exit_timestamp.monotonic,
472 (uint32_t) c->exec_status.pid,
473 (int32_t) c->exec_status.code,
474 (int32_t) c->exec_status.status);
478 r = sd_bus_message_close_container(reply);
483 return sd_bus_message_close_container(reply);