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>
34 #include "capability.h"
37 #include "namespace.h"
38 #include "path-util.h"
39 #include "dbus-execute.h"
42 #include "seccomp-util.h"
45 BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_exec_output, exec_output, ExecOutput);
47 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_exec_input, exec_input, ExecInput);
49 static BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_protect_home, protect_home, ProtectHome);
50 static BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_protect_system, protect_system, ProtectSystem);
52 static int property_get_environment_files(
55 const char *interface,
57 sd_bus_message *reply,
59 sd_bus_error *error) {
61 ExecContext *c = userdata;
69 r = sd_bus_message_open_container(reply, 'a', "(sb)");
73 STRV_FOREACH(j, c->environment_files) {
76 r = sd_bus_message_append(reply, "(sb)", fn[0] == '-' ? fn + 1 : fn, fn[0] == '-');
81 return sd_bus_message_close_container(reply);
84 static int property_get_rlimit(
87 const char *interface,
89 sd_bus_message *reply,
91 sd_bus_error *error) {
101 rl = *(struct rlimit**) userdata;
105 struct rlimit buf = {};
108 z = rlimit_from_string(property);
115 /* rlim_t might have different sizes, let's map
116 * RLIMIT_INFINITY to (uint64_t) -1, so that it is the same on
118 u = x == RLIM_INFINITY ? (uint64_t) -1 : (uint64_t) x;
120 return sd_bus_message_append(reply, "t", u);
123 static int property_get_oom_score_adjust(
126 const char *interface,
127 const char *property,
128 sd_bus_message *reply,
130 sd_bus_error *error) {
133 ExecContext *c = userdata;
140 if (c->oom_score_adjust_set)
141 n = c->oom_score_adjust;
143 _cleanup_free_ char *t = NULL;
146 if (read_one_line_file("/proc/self/oom_score_adj", &t) >= 0)
150 return sd_bus_message_append(reply, "i", n);
153 static int property_get_nice(
156 const char *interface,
157 const char *property,
158 sd_bus_message *reply,
160 sd_bus_error *error) {
163 ExecContext *c = userdata;
174 n = getpriority(PRIO_PROCESS, 0);
179 return sd_bus_message_append(reply, "i", n);
182 static int property_get_ioprio(
185 const char *interface,
186 const char *property,
187 sd_bus_message *reply,
189 sd_bus_error *error) {
192 ExecContext *c = userdata;
202 n = ioprio_get(IOPRIO_WHO_PROCESS, 0);
204 n = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 4);
207 return sd_bus_message_append(reply, "i", n);
210 static int property_get_cpu_sched_policy(
213 const char *interface,
214 const char *property,
215 sd_bus_message *reply,
217 sd_bus_error *error) {
219 ExecContext *c = userdata;
226 if (c->cpu_sched_set)
227 n = c->cpu_sched_policy;
229 n = sched_getscheduler(0);
234 return sd_bus_message_append(reply, "i", n);
237 static int property_get_cpu_sched_priority(
240 const char *interface,
241 const char *property,
242 sd_bus_message *reply,
244 sd_bus_error *error) {
246 ExecContext *c = userdata;
253 if (c->cpu_sched_set)
254 n = c->cpu_sched_priority;
256 struct sched_param p = {};
258 if (sched_getparam(0, &p) >= 0)
259 n = p.sched_priority;
264 return sd_bus_message_append(reply, "i", n);
267 static int property_get_cpu_affinity(
270 const char *interface,
271 const char *property,
272 sd_bus_message *reply,
274 sd_bus_error *error) {
276 ExecContext *c = userdata;
283 return sd_bus_message_append_array(reply, 'y', c->cpuset, CPU_ALLOC_SIZE(c->cpuset_ncpus));
285 return sd_bus_message_append_array(reply, 'y', NULL, 0);
288 static int property_get_timer_slack_nsec(
291 const char *interface,
292 const char *property,
293 sd_bus_message *reply,
295 sd_bus_error *error) {
297 ExecContext *c = userdata;
304 if (c->timer_slack_nsec != NSEC_INFINITY)
305 u = (uint64_t) c->timer_slack_nsec;
307 u = (uint64_t) prctl(PR_GET_TIMERSLACK);
309 return sd_bus_message_append(reply, "t", u);
312 static int property_get_capability_bounding_set(
315 const char *interface,
316 const char *property,
317 sd_bus_message *reply,
319 sd_bus_error *error) {
321 ExecContext *c = userdata;
327 /* We store this negated internally, to match the kernel, but
328 * we expose it normalized. */
329 return sd_bus_message_append(reply, "t", ~c->capability_bounding_set_drop);
332 static int property_get_capabilities(
335 const char *interface,
336 const char *property,
337 sd_bus_message *reply,
339 sd_bus_error *error) {
341 ExecContext *c = userdata;
342 _cleanup_cap_free_charp_ char *t = NULL;
350 s = t = cap_to_text(c->capabilities, NULL);
357 return sd_bus_message_append(reply, "s", s);
360 static int property_get_syscall_filter(
363 const char *interface,
364 const char *property,
365 sd_bus_message *reply,
367 sd_bus_error *error) {
369 ExecContext *c = userdata;
370 _cleanup_strv_free_ char **l = NULL;
382 r = sd_bus_message_open_container(reply, 'r', "bas");
386 r = sd_bus_message_append(reply, "b", c->syscall_whitelist);
391 SET_FOREACH(id, c->syscall_filter, i) {
394 name = seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE, PTR_TO_INT(id) - 1);
398 r = strv_consume(&l, name);
406 r = sd_bus_message_append_strv(reply, l);
410 return sd_bus_message_close_container(reply);
413 static int property_get_syscall_archs(
416 const char *interface,
417 const char *property,
418 sd_bus_message *reply,
420 sd_bus_error *error) {
422 ExecContext *c = userdata;
423 _cleanup_strv_free_ char **l = NULL;
436 SET_FOREACH(id, c->syscall_archs, i) {
439 name = seccomp_arch_to_string(PTR_TO_UINT32(id) - 1);
443 r = strv_extend(&l, name);
451 r = sd_bus_message_append_strv(reply, l);
458 static int property_get_syscall_errno(
461 const char *interface,
462 const char *property,
463 sd_bus_message *reply,
465 sd_bus_error *error) {
467 ExecContext *c = userdata;
473 return sd_bus_message_append(reply, "i", (int32_t) c->syscall_errno);
476 static int property_get_selinux_context(
479 const char *interface,
480 const char *property,
481 sd_bus_message *reply,
483 sd_bus_error *error) {
485 ExecContext *c = userdata;
491 return sd_bus_message_append(reply, "(bs)", c->selinux_context_ignore, c->selinux_context);
494 static int property_get_apparmor_profile(
497 const char *interface,
498 const char *property,
499 sd_bus_message *reply,
501 sd_bus_error *error) {
503 ExecContext *c = userdata;
509 return sd_bus_message_append(reply, "(bs)", c->apparmor_profile_ignore, c->apparmor_profile);
512 static int property_get_smack_process_label(
515 const char *interface,
516 const char *property,
517 sd_bus_message *reply,
519 sd_bus_error *error) {
521 ExecContext *c = userdata;
527 return sd_bus_message_append(reply, "(bs)", c->smack_process_label_ignore, c->smack_process_label);
530 static int property_get_personality(
533 const char *interface,
534 const char *property,
535 sd_bus_message *reply,
537 sd_bus_error *error) {
539 ExecContext *c = userdata;
545 return sd_bus_message_append(reply, "s", personality_to_string(c->personality));
548 static int property_get_address_families(
551 const char *interface,
552 const char *property,
553 sd_bus_message *reply,
555 sd_bus_error *error) {
557 ExecContext *c = userdata;
558 _cleanup_strv_free_ char **l = NULL;
567 r = sd_bus_message_open_container(reply, 'r', "bas");
571 r = sd_bus_message_append(reply, "b", c->address_families_whitelist);
575 SET_FOREACH(af, c->address_families, i) {
578 name = af_to_name(PTR_TO_INT(af));
582 r = strv_extend(&l, name);
589 r = sd_bus_message_append_strv(reply, l);
593 return sd_bus_message_close_container(reply);
596 const sd_bus_vtable bus_exec_vtable[] = {
597 SD_BUS_VTABLE_START(0),
598 SD_BUS_PROPERTY("Environment", "as", NULL, offsetof(ExecContext, environment), SD_BUS_VTABLE_PROPERTY_CONST),
599 SD_BUS_PROPERTY("EnvironmentFiles", "a(sb)", property_get_environment_files, 0, SD_BUS_VTABLE_PROPERTY_CONST),
600 SD_BUS_PROPERTY("UMask", "u", bus_property_get_mode, offsetof(ExecContext, umask), SD_BUS_VTABLE_PROPERTY_CONST),
601 SD_BUS_PROPERTY("LimitCPU", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_CPU]), SD_BUS_VTABLE_PROPERTY_CONST),
602 SD_BUS_PROPERTY("LimitFSIZE", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_FSIZE]), SD_BUS_VTABLE_PROPERTY_CONST),
603 SD_BUS_PROPERTY("LimitDATA", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_DATA]), SD_BUS_VTABLE_PROPERTY_CONST),
604 SD_BUS_PROPERTY("LimitSTACK", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_STACK]), SD_BUS_VTABLE_PROPERTY_CONST),
605 SD_BUS_PROPERTY("LimitCORE", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_CORE]), SD_BUS_VTABLE_PROPERTY_CONST),
606 SD_BUS_PROPERTY("LimitRSS", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RSS]), SD_BUS_VTABLE_PROPERTY_CONST),
607 SD_BUS_PROPERTY("LimitNOFILE", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NOFILE]), SD_BUS_VTABLE_PROPERTY_CONST),
608 SD_BUS_PROPERTY("LimitAS", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_AS]), SD_BUS_VTABLE_PROPERTY_CONST),
609 SD_BUS_PROPERTY("LimitNPROC", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NPROC]), SD_BUS_VTABLE_PROPERTY_CONST),
610 SD_BUS_PROPERTY("LimitMEMLOCK", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_MEMLOCK]), SD_BUS_VTABLE_PROPERTY_CONST),
611 SD_BUS_PROPERTY("LimitLOCKS", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_LOCKS]), SD_BUS_VTABLE_PROPERTY_CONST),
612 SD_BUS_PROPERTY("LimitSIGPENDING", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_SIGPENDING]), SD_BUS_VTABLE_PROPERTY_CONST),
613 SD_BUS_PROPERTY("LimitMSGQUEUE", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_MSGQUEUE]), SD_BUS_VTABLE_PROPERTY_CONST),
614 SD_BUS_PROPERTY("LimitNICE", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NICE]), SD_BUS_VTABLE_PROPERTY_CONST),
615 SD_BUS_PROPERTY("LimitRTPRIO", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RTPRIO]), SD_BUS_VTABLE_PROPERTY_CONST),
616 SD_BUS_PROPERTY("LimitRTTIME", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RTTIME]), SD_BUS_VTABLE_PROPERTY_CONST),
617 SD_BUS_PROPERTY("WorkingDirectory", "s", NULL, offsetof(ExecContext, working_directory), SD_BUS_VTABLE_PROPERTY_CONST),
618 SD_BUS_PROPERTY("RootDirectory", "s", NULL, offsetof(ExecContext, root_directory), SD_BUS_VTABLE_PROPERTY_CONST),
619 SD_BUS_PROPERTY("OOMScoreAdjust", "i", property_get_oom_score_adjust, 0, SD_BUS_VTABLE_PROPERTY_CONST),
620 SD_BUS_PROPERTY("Nice", "i", property_get_nice, 0, SD_BUS_VTABLE_PROPERTY_CONST),
621 SD_BUS_PROPERTY("IOScheduling", "i", property_get_ioprio, 0, SD_BUS_VTABLE_PROPERTY_CONST),
622 SD_BUS_PROPERTY("CPUSchedulingPolicy", "i", property_get_cpu_sched_policy, 0, SD_BUS_VTABLE_PROPERTY_CONST),
623 SD_BUS_PROPERTY("CPUSchedulingPriority", "i", property_get_cpu_sched_priority, 0, SD_BUS_VTABLE_PROPERTY_CONST),
624 SD_BUS_PROPERTY("CPUAffinity", "ay", property_get_cpu_affinity, 0, SD_BUS_VTABLE_PROPERTY_CONST),
625 SD_BUS_PROPERTY("TimerSlackNSec", "t", property_get_timer_slack_nsec, 0, SD_BUS_VTABLE_PROPERTY_CONST),
626 SD_BUS_PROPERTY("CPUSchedulingResetOnFork", "b", bus_property_get_bool, offsetof(ExecContext, cpu_sched_reset_on_fork), SD_BUS_VTABLE_PROPERTY_CONST),
627 SD_BUS_PROPERTY("NonBlocking", "b", bus_property_get_bool, offsetof(ExecContext, non_blocking), SD_BUS_VTABLE_PROPERTY_CONST),
628 SD_BUS_PROPERTY("StandardInput", "s", property_get_exec_input, offsetof(ExecContext, std_input), SD_BUS_VTABLE_PROPERTY_CONST),
629 SD_BUS_PROPERTY("StandardOutput", "s", bus_property_get_exec_output, offsetof(ExecContext, std_output), SD_BUS_VTABLE_PROPERTY_CONST),
630 SD_BUS_PROPERTY("StandardError", "s", bus_property_get_exec_output, offsetof(ExecContext, std_error), SD_BUS_VTABLE_PROPERTY_CONST),
631 SD_BUS_PROPERTY("TTYPath", "s", NULL, offsetof(ExecContext, tty_path), SD_BUS_VTABLE_PROPERTY_CONST),
632 SD_BUS_PROPERTY("TTYReset", "b", bus_property_get_bool, offsetof(ExecContext, tty_reset), SD_BUS_VTABLE_PROPERTY_CONST),
633 SD_BUS_PROPERTY("TTYVHangup", "b", bus_property_get_bool, offsetof(ExecContext, tty_vhangup), SD_BUS_VTABLE_PROPERTY_CONST),
634 SD_BUS_PROPERTY("TTYVTDisallocate", "b", bus_property_get_bool, offsetof(ExecContext, tty_vt_disallocate), SD_BUS_VTABLE_PROPERTY_CONST),
635 SD_BUS_PROPERTY("SyslogPriority", "i", bus_property_get_int, offsetof(ExecContext, syslog_priority), SD_BUS_VTABLE_PROPERTY_CONST),
636 SD_BUS_PROPERTY("SyslogIdentifier", "s", NULL, offsetof(ExecContext, syslog_identifier), SD_BUS_VTABLE_PROPERTY_CONST),
637 SD_BUS_PROPERTY("SyslogLevelPrefix", "b", bus_property_get_bool, offsetof(ExecContext, syslog_level_prefix), SD_BUS_VTABLE_PROPERTY_CONST),
638 SD_BUS_PROPERTY("Capabilities", "s", property_get_capabilities, 0, SD_BUS_VTABLE_PROPERTY_CONST),
639 SD_BUS_PROPERTY("SecureBits", "i", bus_property_get_int, offsetof(ExecContext, secure_bits), SD_BUS_VTABLE_PROPERTY_CONST),
640 SD_BUS_PROPERTY("CapabilityBoundingSet", "t", property_get_capability_bounding_set, 0, SD_BUS_VTABLE_PROPERTY_CONST),
641 SD_BUS_PROPERTY("User", "s", NULL, offsetof(ExecContext, user), SD_BUS_VTABLE_PROPERTY_CONST),
642 SD_BUS_PROPERTY("Group", "s", NULL, offsetof(ExecContext, group), SD_BUS_VTABLE_PROPERTY_CONST),
643 SD_BUS_PROPERTY("SupplementaryGroups", "as", NULL, offsetof(ExecContext, supplementary_groups), SD_BUS_VTABLE_PROPERTY_CONST),
644 SD_BUS_PROPERTY("PAMName", "s", NULL, offsetof(ExecContext, pam_name), SD_BUS_VTABLE_PROPERTY_CONST),
645 SD_BUS_PROPERTY("ReadWriteDirectories", "as", NULL, offsetof(ExecContext, read_write_dirs), SD_BUS_VTABLE_PROPERTY_CONST),
646 SD_BUS_PROPERTY("ReadOnlyDirectories", "as", NULL, offsetof(ExecContext, read_only_dirs), SD_BUS_VTABLE_PROPERTY_CONST),
647 SD_BUS_PROPERTY("InaccessibleDirectories", "as", NULL, offsetof(ExecContext, inaccessible_dirs), SD_BUS_VTABLE_PROPERTY_CONST),
648 SD_BUS_PROPERTY("MountFlags", "t", bus_property_get_ulong, offsetof(ExecContext, mount_flags), SD_BUS_VTABLE_PROPERTY_CONST),
649 SD_BUS_PROPERTY("PrivateTmp", "b", bus_property_get_bool, offsetof(ExecContext, private_tmp), SD_BUS_VTABLE_PROPERTY_CONST),
650 SD_BUS_PROPERTY("PrivateNetwork", "b", bus_property_get_bool, offsetof(ExecContext, private_network), SD_BUS_VTABLE_PROPERTY_CONST),
651 SD_BUS_PROPERTY("PrivateDevices", "b", bus_property_get_bool, offsetof(ExecContext, private_devices), SD_BUS_VTABLE_PROPERTY_CONST),
652 SD_BUS_PROPERTY("ProtectHome", "s", bus_property_get_protect_home, offsetof(ExecContext, protect_home), SD_BUS_VTABLE_PROPERTY_CONST),
653 SD_BUS_PROPERTY("ProtectSystem", "s", bus_property_get_protect_system, offsetof(ExecContext, protect_system), SD_BUS_VTABLE_PROPERTY_CONST),
654 SD_BUS_PROPERTY("SameProcessGroup", "b", bus_property_get_bool, offsetof(ExecContext, same_pgrp), SD_BUS_VTABLE_PROPERTY_CONST),
655 SD_BUS_PROPERTY("UtmpIdentifier", "s", NULL, offsetof(ExecContext, utmp_id), SD_BUS_VTABLE_PROPERTY_CONST),
656 SD_BUS_PROPERTY("SELinuxContext", "(bs)", property_get_selinux_context, 0, SD_BUS_VTABLE_PROPERTY_CONST),
657 SD_BUS_PROPERTY("AppArmorProfile", "(bs)", property_get_apparmor_profile, 0, SD_BUS_VTABLE_PROPERTY_CONST),
658 SD_BUS_PROPERTY("SmackProcessLabel", "(bs)", property_get_smack_process_label, 0, SD_BUS_VTABLE_PROPERTY_CONST),
659 SD_BUS_PROPERTY("IgnoreSIGPIPE", "b", bus_property_get_bool, offsetof(ExecContext, ignore_sigpipe), SD_BUS_VTABLE_PROPERTY_CONST),
660 SD_BUS_PROPERTY("NoNewPrivileges", "b", bus_property_get_bool, offsetof(ExecContext, no_new_privileges), SD_BUS_VTABLE_PROPERTY_CONST),
661 SD_BUS_PROPERTY("SystemCallFilter", "(bas)", property_get_syscall_filter, 0, SD_BUS_VTABLE_PROPERTY_CONST),
662 SD_BUS_PROPERTY("SystemCallArchitectures", "as", property_get_syscall_archs, 0, SD_BUS_VTABLE_PROPERTY_CONST),
663 SD_BUS_PROPERTY("SystemCallErrorNumber", "i", property_get_syscall_errno, 0, SD_BUS_VTABLE_PROPERTY_CONST),
664 SD_BUS_PROPERTY("Personality", "s", property_get_personality, 0, SD_BUS_VTABLE_PROPERTY_CONST),
665 SD_BUS_PROPERTY("RestrictAddressFamilies", "(bas)", property_get_address_families, 0, SD_BUS_VTABLE_PROPERTY_CONST),
666 SD_BUS_PROPERTY("RuntimeDirectoryMode", "u", bus_property_get_mode, offsetof(ExecContext, runtime_directory_mode), SD_BUS_VTABLE_PROPERTY_CONST),
667 SD_BUS_PROPERTY("RuntimeDirectory", "as", NULL, offsetof(ExecContext, runtime_directory), SD_BUS_VTABLE_PROPERTY_CONST),
671 static int append_exec_command(sd_bus_message *reply, ExecCommand *c) {
680 r = sd_bus_message_open_container(reply, 'r', "sasbttttuii");
684 r = sd_bus_message_append(reply, "s", c->path);
688 r = sd_bus_message_append_strv(reply, c->argv);
692 r = sd_bus_message_append(reply, "bttttuii",
694 c->exec_status.start_timestamp.realtime,
695 c->exec_status.start_timestamp.monotonic,
696 c->exec_status.exit_timestamp.realtime,
697 c->exec_status.exit_timestamp.monotonic,
698 (uint32_t) c->exec_status.pid,
699 (int32_t) c->exec_status.code,
700 (int32_t) c->exec_status.status);
704 return sd_bus_message_close_container(reply);
707 int bus_property_get_exec_command(
710 const char *interface,
711 const char *property,
712 sd_bus_message *reply,
714 sd_bus_error *ret_error) {
716 ExecCommand *c = (ExecCommand*) userdata;
722 r = sd_bus_message_open_container(reply, 'a', "(sasbttttuii)");
726 r = append_exec_command(reply, c);
730 return sd_bus_message_close_container(reply);
733 int bus_property_get_exec_command_list(
736 const char *interface,
737 const char *property,
738 sd_bus_message *reply,
740 sd_bus_error *ret_error) {
742 ExecCommand *c = *(ExecCommand**) userdata;
748 r = sd_bus_message_open_container(reply, 'a', "(sasbttttuii)");
752 LIST_FOREACH(command, c, c) {
753 r = append_exec_command(reply, c);
758 return sd_bus_message_close_container(reply);
761 int bus_exec_context_set_transient_property(
765 sd_bus_message *message,
766 UnitSetPropertiesMode mode,
767 sd_bus_error *error) {
776 if (streq(name, "User")) {
779 r = sd_bus_message_read(message, "s", &uu);
783 if (mode != UNIT_CHECK) {
799 unit_write_drop_in_private_format(u, mode, name, "User=%s\n", uu);
804 } else if (streq(name, "Group")) {
807 r = sd_bus_message_read(message, "s", &gg);
811 if (mode != UNIT_CHECK) {
827 unit_write_drop_in_private_format(u, mode, name, "Group=%s\n", gg);
832 } else if (streq(name, "Nice")) {
835 r = sd_bus_message_read(message, "i", &n);
839 if (n < PRIO_MIN || n >= PRIO_MAX)
840 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Nice value out of range");
842 if (mode != UNIT_CHECK) {
844 unit_write_drop_in_private_format(u, mode, name, "Nice=%i\n", n);
849 } else if (streq(name, "TTYPath")) {
852 r = sd_bus_message_read(message, "s", &tty);
856 if (!path_is_absolute(tty))
857 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "TTY device not absolute path");
859 if (mode != UNIT_CHECK) {
869 unit_write_drop_in_private_format(u, mode, name, "TTYPath=%s\n", tty);
874 } else if (streq(name, "StandardInput")) {
878 r = sd_bus_message_read(message, "s", &s);
882 p = exec_input_from_string(s);
884 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid standard input name");
886 if (mode != UNIT_CHECK) {
889 unit_write_drop_in_private_format(u, mode, name, "StandardInput=%s\n", exec_input_to_string(p));
895 } else if (streq(name, "StandardOutput")) {
899 r = sd_bus_message_read(message, "s", &s);
903 p = exec_output_from_string(s);
905 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid standard output name");
907 if (mode != UNIT_CHECK) {
910 unit_write_drop_in_private_format(u, mode, name, "StandardOutput=%s\n", exec_output_to_string(p));
915 } else if (streq(name, "StandardError")) {
919 r = sd_bus_message_read(message, "s", &s);
923 p = exec_output_from_string(s);
925 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid standard error name");
927 if (mode != UNIT_CHECK) {
930 unit_write_drop_in_private_format(u, mode, name, "StandardError=%s\n", exec_output_to_string(p));
935 } else if (streq(name, "Environment")) {
937 _cleanup_strv_free_ char **l = NULL;
939 r = sd_bus_message_read_strv(message, &l);
943 if (!strv_env_is_valid(l))
944 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment block.");
946 if (mode != UNIT_CHECK) {
947 _cleanup_free_ char *joined = NULL;
950 e = strv_env_merge(2, c->environment, l);
954 strv_free(c->environment);
957 joined = strv_join_quoted(c->environment);
961 unit_write_drop_in_private_format(u, mode, name, "Environment=%s\n", joined);
966 } else if (rlimit_from_string(name) >= 0) {
970 r = sd_bus_message_read(message, "t", &rl);
974 if (rl == (uint64_t) -1)
979 if ((uint64_t) x != rl)
983 if (mode != UNIT_CHECK) {
986 z = rlimit_from_string(name);
989 c->rlimit[z] = new(struct rlimit, 1);
994 c->rlimit[z]->rlim_cur = c->rlimit[z]->rlim_max = x;
996 if (x == RLIM_INFINITY)
997 unit_write_drop_in_private_format(u, mode, name, "%s=infinity\n", name);
999 unit_write_drop_in_private_format(u, mode, name, "%s=%" PRIu64 "\n", name, rl);