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 "dbus-execute.h"
35 #include "capability.h"
40 #include "seccomp-util.h"
43 BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_exec_output, exec_output, ExecOutput);
45 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_exec_input, exec_input, ExecInput);
47 static int property_get_environment_files(
50 const char *interface,
52 sd_bus_message *reply,
54 sd_bus_error *error) {
56 ExecContext *c = userdata;
64 r = sd_bus_message_open_container(reply, 'a', "(sb)");
68 STRV_FOREACH(j, c->environment_files) {
71 r = sd_bus_message_append(reply, "(sb)", fn[0] == '-' ? fn + 1 : fn, fn[0] == '-');
76 return sd_bus_message_close_container(reply);
79 static int property_get_rlimit(
82 const char *interface,
84 sd_bus_message *reply,
86 sd_bus_error *error) {
96 rl = *(struct rlimit**) userdata;
100 struct rlimit buf = {};
103 z = rlimit_from_string(property);
110 /* rlim_t might have different sizes, let's map
111 * RLIMIT_INFINITY to (uint64_t) -1, so that it is the same on
113 u = x == RLIM_INFINITY ? (uint64_t) -1 : (uint64_t) x;
115 return sd_bus_message_append(reply, "t", u);
118 static int property_get_oom_score_adjust(
121 const char *interface,
122 const char *property,
123 sd_bus_message *reply,
125 sd_bus_error *error) {
128 ExecContext *c = userdata;
135 if (c->oom_score_adjust_set)
136 n = c->oom_score_adjust;
138 _cleanup_free_ char *t = NULL;
141 if (read_one_line_file("/proc/self/oom_score_adj", &t) >= 0)
145 return sd_bus_message_append(reply, "i", n);
148 static int property_get_nice(
151 const char *interface,
152 const char *property,
153 sd_bus_message *reply,
155 sd_bus_error *error) {
158 ExecContext *c = userdata;
169 n = getpriority(PRIO_PROCESS, 0);
174 return sd_bus_message_append(reply, "i", n);
177 static int property_get_ioprio(
180 const char *interface,
181 const char *property,
182 sd_bus_message *reply,
184 sd_bus_error *error) {
187 ExecContext *c = userdata;
197 n = ioprio_get(IOPRIO_WHO_PROCESS, 0);
199 n = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 4);
202 return sd_bus_message_append(reply, "i", n);
205 static int property_get_cpu_sched_policy(
208 const char *interface,
209 const char *property,
210 sd_bus_message *reply,
212 sd_bus_error *error) {
214 ExecContext *c = userdata;
221 if (c->cpu_sched_set)
222 n = c->cpu_sched_policy;
224 n = sched_getscheduler(0);
229 return sd_bus_message_append(reply, "i", n);
232 static int property_get_cpu_sched_priority(
235 const char *interface,
236 const char *property,
237 sd_bus_message *reply,
239 sd_bus_error *error) {
241 ExecContext *c = userdata;
248 if (c->cpu_sched_set)
249 n = c->cpu_sched_priority;
251 struct sched_param p = {};
253 if (sched_getparam(0, &p) >= 0)
254 n = p.sched_priority;
259 return sd_bus_message_append(reply, "i", n);
262 static int property_get_cpu_affinity(
265 const char *interface,
266 const char *property,
267 sd_bus_message *reply,
269 sd_bus_error *error) {
271 ExecContext *c = userdata;
278 return sd_bus_message_append_array(reply, 'y', c->cpuset, CPU_ALLOC_SIZE(c->cpuset_ncpus));
280 return sd_bus_message_append_array(reply, 'y', NULL, 0);
283 static int property_get_timer_slack_nsec(
286 const char *interface,
287 const char *property,
288 sd_bus_message *reply,
290 sd_bus_error *error) {
292 ExecContext *c = userdata;
299 if (c->timer_slack_nsec != (nsec_t) -1)
300 u = (uint64_t) c->timer_slack_nsec;
302 u = (uint64_t) prctl(PR_GET_TIMERSLACK);
304 return sd_bus_message_append(reply, "t", u);
307 static int property_get_capability_bounding_set(
310 const char *interface,
311 const char *property,
312 sd_bus_message *reply,
314 sd_bus_error *error) {
316 ExecContext *c = userdata;
322 /* We store this negated internally, to match the kernel, but
323 * we expose it normalized. */
324 return sd_bus_message_append(reply, "t", ~c->capability_bounding_set_drop);
327 static int property_get_capabilities(
330 const char *interface,
331 const char *property,
332 sd_bus_message *reply,
334 sd_bus_error *error) {
336 ExecContext *c = userdata;
337 _cleanup_cap_free_charp_ char *t = NULL;
345 s = t = cap_to_text(c->capabilities, NULL);
352 return sd_bus_message_append(reply, "s", s);
355 static int property_get_syscall_filter(
358 const char *interface,
359 const char *property,
360 sd_bus_message *reply,
362 sd_bus_error *error) {
364 ExecContext *c = userdata;
365 _cleanup_strv_free_ char **l = NULL;
377 r = sd_bus_message_open_container(reply, 'r', "bas");
381 r = sd_bus_message_append(reply, "b", c->syscall_whitelist);
386 SET_FOREACH(id, c->syscall_filter, i) {
389 name = seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE, PTR_TO_INT(id) - 1);
393 r = strv_consume(&l, name);
401 r = sd_bus_message_append_strv(reply, l);
405 return sd_bus_message_close_container(reply);
408 static int property_get_syscall_archs(
411 const char *interface,
412 const char *property,
413 sd_bus_message *reply,
415 sd_bus_error *error) {
417 ExecContext *c = userdata;
418 _cleanup_strv_free_ char **l = NULL;
431 SET_FOREACH(id, c->syscall_archs, i) {
434 name = seccomp_arch_to_string(PTR_TO_UINT32(id) - 1);
438 r = strv_extend(&l, name);
446 r = sd_bus_message_append_strv(reply, l);
453 static int property_get_syscall_errno(
456 const char *interface,
457 const char *property,
458 sd_bus_message *reply,
460 sd_bus_error *error) {
462 ExecContext *c = userdata;
468 return sd_bus_message_append(reply, "i", (int32_t) c->syscall_errno);
471 static int property_get_selinux_context(
474 const char *interface,
475 const char *property,
476 sd_bus_message *reply,
478 sd_bus_error *error) {
480 ExecContext *c = userdata;
486 return sd_bus_message_append(reply, "(bs)", c->selinux_context_ignore, c->selinux_context);
489 static int property_get_apparmor_profile(
492 const char *interface,
493 const char *property,
494 sd_bus_message *reply,
496 sd_bus_error *error) {
498 ExecContext *c = userdata;
504 return sd_bus_message_append(reply, "(bs)", c->apparmor_profile_ignore, c->apparmor_profile);
507 static int property_get_personality(
510 const char *interface,
511 const char *property,
512 sd_bus_message *reply,
514 sd_bus_error *error) {
516 ExecContext *c = userdata;
522 return sd_bus_message_append(reply, "s", personality_to_string(c->personality));
525 static int property_get_address_families(
528 const char *interface,
529 const char *property,
530 sd_bus_message *reply,
532 sd_bus_error *error) {
534 ExecContext *c = userdata;
535 _cleanup_strv_free_ char **l = NULL;
544 r = sd_bus_message_open_container(reply, 'r', "bas");
548 r = sd_bus_message_append(reply, "b", c->address_families_whitelist);
552 SET_FOREACH(af, c->address_families, i) {
555 name = af_to_name(PTR_TO_INT(af));
559 r = strv_extend(&l, name);
566 r = sd_bus_message_append_strv(reply, l);
570 return sd_bus_message_close_container(reply);
573 const sd_bus_vtable bus_exec_vtable[] = {
574 SD_BUS_VTABLE_START(0),
575 SD_BUS_PROPERTY("Environment", "as", NULL, offsetof(ExecContext, environment), SD_BUS_VTABLE_PROPERTY_CONST),
576 SD_BUS_PROPERTY("EnvironmentFiles", "a(sb)", property_get_environment_files, 0, SD_BUS_VTABLE_PROPERTY_CONST),
577 SD_BUS_PROPERTY("UMask", "u", bus_property_get_mode, offsetof(ExecContext, umask), SD_BUS_VTABLE_PROPERTY_CONST),
578 SD_BUS_PROPERTY("LimitCPU", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_CPU]), SD_BUS_VTABLE_PROPERTY_CONST),
579 SD_BUS_PROPERTY("LimitFSIZE", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_FSIZE]), SD_BUS_VTABLE_PROPERTY_CONST),
580 SD_BUS_PROPERTY("LimitDATA", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_DATA]), SD_BUS_VTABLE_PROPERTY_CONST),
581 SD_BUS_PROPERTY("LimitSTACK", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_STACK]), SD_BUS_VTABLE_PROPERTY_CONST),
582 SD_BUS_PROPERTY("LimitCORE", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_CORE]), SD_BUS_VTABLE_PROPERTY_CONST),
583 SD_BUS_PROPERTY("LimitRSS", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RSS]), SD_BUS_VTABLE_PROPERTY_CONST),
584 SD_BUS_PROPERTY("LimitNOFILE", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NOFILE]), SD_BUS_VTABLE_PROPERTY_CONST),
585 SD_BUS_PROPERTY("LimitAS", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_AS]), SD_BUS_VTABLE_PROPERTY_CONST),
586 SD_BUS_PROPERTY("LimitNPROC", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NPROC]), SD_BUS_VTABLE_PROPERTY_CONST),
587 SD_BUS_PROPERTY("LimitMEMLOCK", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_MEMLOCK]), SD_BUS_VTABLE_PROPERTY_CONST),
588 SD_BUS_PROPERTY("LimitLOCKS", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_LOCKS]), SD_BUS_VTABLE_PROPERTY_CONST),
589 SD_BUS_PROPERTY("LimitSIGPENDING", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_SIGPENDING]), SD_BUS_VTABLE_PROPERTY_CONST),
590 SD_BUS_PROPERTY("LimitMSGQUEUE", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_MSGQUEUE]), SD_BUS_VTABLE_PROPERTY_CONST),
591 SD_BUS_PROPERTY("LimitNICE", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NICE]), SD_BUS_VTABLE_PROPERTY_CONST),
592 SD_BUS_PROPERTY("LimitRTPRIO", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RTPRIO]), SD_BUS_VTABLE_PROPERTY_CONST),
593 SD_BUS_PROPERTY("LimitRTTIME", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RTTIME]), SD_BUS_VTABLE_PROPERTY_CONST),
594 SD_BUS_PROPERTY("WorkingDirectory", "s", NULL, offsetof(ExecContext, working_directory), SD_BUS_VTABLE_PROPERTY_CONST),
595 SD_BUS_PROPERTY("RootDirectory", "s", NULL, offsetof(ExecContext, root_directory), SD_BUS_VTABLE_PROPERTY_CONST),
596 SD_BUS_PROPERTY("OOMScoreAdjust", "i", property_get_oom_score_adjust, 0, SD_BUS_VTABLE_PROPERTY_CONST),
597 SD_BUS_PROPERTY("Nice", "i", property_get_nice, 0, SD_BUS_VTABLE_PROPERTY_CONST),
598 SD_BUS_PROPERTY("IOScheduling", "i", property_get_ioprio, 0, SD_BUS_VTABLE_PROPERTY_CONST),
599 SD_BUS_PROPERTY("CPUSchedulingPolicy", "i", property_get_cpu_sched_policy, 0, SD_BUS_VTABLE_PROPERTY_CONST),
600 SD_BUS_PROPERTY("CPUSchedulingPriority", "i", property_get_cpu_sched_priority, 0, SD_BUS_VTABLE_PROPERTY_CONST),
601 SD_BUS_PROPERTY("CPUAffinity", "ay", property_get_cpu_affinity, 0, SD_BUS_VTABLE_PROPERTY_CONST),
602 SD_BUS_PROPERTY("TimerSlackNSec", "t", property_get_timer_slack_nsec, 0, SD_BUS_VTABLE_PROPERTY_CONST),
603 SD_BUS_PROPERTY("CPUSchedulingResetOnFork", "b", bus_property_get_bool, offsetof(ExecContext, cpu_sched_reset_on_fork), SD_BUS_VTABLE_PROPERTY_CONST),
604 SD_BUS_PROPERTY("NonBlocking", "b", bus_property_get_bool, offsetof(ExecContext, non_blocking), SD_BUS_VTABLE_PROPERTY_CONST),
605 SD_BUS_PROPERTY("StandardInput", "s", property_get_exec_input, offsetof(ExecContext, std_input), SD_BUS_VTABLE_PROPERTY_CONST),
606 SD_BUS_PROPERTY("StandardOutput", "s", bus_property_get_exec_output, offsetof(ExecContext, std_output), SD_BUS_VTABLE_PROPERTY_CONST),
607 SD_BUS_PROPERTY("StandardError", "s", bus_property_get_exec_output, offsetof(ExecContext, std_error), SD_BUS_VTABLE_PROPERTY_CONST),
608 SD_BUS_PROPERTY("TTYPath", "s", NULL, offsetof(ExecContext, tty_path), SD_BUS_VTABLE_PROPERTY_CONST),
609 SD_BUS_PROPERTY("TTYReset", "b", bus_property_get_bool, offsetof(ExecContext, tty_reset), SD_BUS_VTABLE_PROPERTY_CONST),
610 SD_BUS_PROPERTY("TTYVHangup", "b", bus_property_get_bool, offsetof(ExecContext, tty_vhangup), SD_BUS_VTABLE_PROPERTY_CONST),
611 SD_BUS_PROPERTY("TTYVTDisallocate", "b", bus_property_get_bool, offsetof(ExecContext, tty_vt_disallocate), SD_BUS_VTABLE_PROPERTY_CONST),
612 SD_BUS_PROPERTY("SyslogPriority", "i", bus_property_get_int, offsetof(ExecContext, syslog_priority), SD_BUS_VTABLE_PROPERTY_CONST),
613 SD_BUS_PROPERTY("SyslogIdentifier", "s", NULL, offsetof(ExecContext, syslog_identifier), SD_BUS_VTABLE_PROPERTY_CONST),
614 SD_BUS_PROPERTY("SyslogLevelPrefix", "b", bus_property_get_bool, offsetof(ExecContext, syslog_level_prefix), SD_BUS_VTABLE_PROPERTY_CONST),
615 SD_BUS_PROPERTY("Capabilities", "s", property_get_capabilities, 0, SD_BUS_VTABLE_PROPERTY_CONST),
616 SD_BUS_PROPERTY("SecureBits", "i", bus_property_get_int, offsetof(ExecContext, secure_bits), SD_BUS_VTABLE_PROPERTY_CONST),
617 SD_BUS_PROPERTY("CapabilityBoundingSet", "t", property_get_capability_bounding_set, 0, SD_BUS_VTABLE_PROPERTY_CONST),
618 SD_BUS_PROPERTY("User", "s", NULL, offsetof(ExecContext, user), SD_BUS_VTABLE_PROPERTY_CONST),
619 SD_BUS_PROPERTY("Group", "s", NULL, offsetof(ExecContext, group), SD_BUS_VTABLE_PROPERTY_CONST),
620 SD_BUS_PROPERTY("SupplementaryGroups", "as", NULL, offsetof(ExecContext, supplementary_groups), SD_BUS_VTABLE_PROPERTY_CONST),
621 SD_BUS_PROPERTY("PAMName", "s", NULL, offsetof(ExecContext, pam_name), SD_BUS_VTABLE_PROPERTY_CONST),
622 SD_BUS_PROPERTY("ReadWriteDirectories", "as", NULL, offsetof(ExecContext, read_write_dirs), SD_BUS_VTABLE_PROPERTY_CONST),
623 SD_BUS_PROPERTY("ReadOnlyDirectories", "as", NULL, offsetof(ExecContext, read_only_dirs), SD_BUS_VTABLE_PROPERTY_CONST),
624 SD_BUS_PROPERTY("InaccessibleDirectories", "as", NULL, offsetof(ExecContext, inaccessible_dirs), SD_BUS_VTABLE_PROPERTY_CONST),
625 SD_BUS_PROPERTY("MountFlags", "t", bus_property_get_ulong, offsetof(ExecContext, mount_flags), SD_BUS_VTABLE_PROPERTY_CONST),
626 SD_BUS_PROPERTY("PrivateTmp", "b", bus_property_get_bool, offsetof(ExecContext, private_tmp), SD_BUS_VTABLE_PROPERTY_CONST),
627 SD_BUS_PROPERTY("PrivateNetwork", "b", bus_property_get_bool, offsetof(ExecContext, private_network), SD_BUS_VTABLE_PROPERTY_CONST),
628 SD_BUS_PROPERTY("PrivateDevices", "b", bus_property_get_bool, offsetof(ExecContext, private_devices), SD_BUS_VTABLE_PROPERTY_CONST),
629 SD_BUS_PROPERTY("SameProcessGroup", "b", bus_property_get_bool, offsetof(ExecContext, same_pgrp), SD_BUS_VTABLE_PROPERTY_CONST),
630 SD_BUS_PROPERTY("UtmpIdentifier", "s", NULL, offsetof(ExecContext, utmp_id), SD_BUS_VTABLE_PROPERTY_CONST),
631 SD_BUS_PROPERTY("SELinuxContext", "(bs)", property_get_selinux_context, 0, SD_BUS_VTABLE_PROPERTY_CONST),
632 SD_BUS_PROPERTY("AppArmorProfile", "(bs)", property_get_apparmor_profile, 0, SD_BUS_VTABLE_PROPERTY_CONST),
633 SD_BUS_PROPERTY("IgnoreSIGPIPE", "b", bus_property_get_bool, offsetof(ExecContext, ignore_sigpipe), SD_BUS_VTABLE_PROPERTY_CONST),
634 SD_BUS_PROPERTY("NoNewPrivileges", "b", bus_property_get_bool, offsetof(ExecContext, no_new_privileges), SD_BUS_VTABLE_PROPERTY_CONST),
635 SD_BUS_PROPERTY("SystemCallFilter", "(bas)", property_get_syscall_filter, 0, SD_BUS_VTABLE_PROPERTY_CONST),
636 SD_BUS_PROPERTY("SystemCallArchitectures", "as", property_get_syscall_archs, 0, SD_BUS_VTABLE_PROPERTY_CONST),
637 SD_BUS_PROPERTY("SystemCallErrorNumber", "i", property_get_syscall_errno, 0, SD_BUS_VTABLE_PROPERTY_CONST),
638 SD_BUS_PROPERTY("Personality", "s", property_get_personality, 0, SD_BUS_VTABLE_PROPERTY_CONST),
639 SD_BUS_PROPERTY("RestrictAddressFamilies", "(bas)", property_get_address_families, 0, SD_BUS_VTABLE_PROPERTY_CONST),
640 SD_BUS_PROPERTY("RuntimeDirectoryMode", "u", bus_property_get_mode, offsetof(ExecContext, runtime_directory_mode), SD_BUS_VTABLE_PROPERTY_CONST),
641 SD_BUS_PROPERTY("RuntimeDirectory", "as", NULL, offsetof(ExecContext, runtime_directory), SD_BUS_VTABLE_PROPERTY_CONST),
645 static int append_exec_command(sd_bus_message *reply, ExecCommand *c) {
654 r = sd_bus_message_open_container(reply, 'r', "sasbttttuii");
658 r = sd_bus_message_append(reply, "s", c->path);
662 r = sd_bus_message_append_strv(reply, c->argv);
666 r = sd_bus_message_append(reply, "bttttuii",
668 c->exec_status.start_timestamp.realtime,
669 c->exec_status.start_timestamp.monotonic,
670 c->exec_status.exit_timestamp.realtime,
671 c->exec_status.exit_timestamp.monotonic,
672 (uint32_t) c->exec_status.pid,
673 (int32_t) c->exec_status.code,
674 (int32_t) c->exec_status.status);
678 return sd_bus_message_close_container(reply);
681 int bus_property_get_exec_command(
684 const char *interface,
685 const char *property,
686 sd_bus_message *reply,
688 sd_bus_error *ret_error) {
690 ExecCommand *c = (ExecCommand*) userdata;
696 r = sd_bus_message_open_container(reply, 'a', "(sasbttttuii)");
700 r = append_exec_command(reply, c);
704 return sd_bus_message_close_container(reply);
707 int bus_property_get_exec_command_list(
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 LIST_FOREACH(command, c, c) {
727 r = append_exec_command(reply, c);
732 return sd_bus_message_close_container(reply);
735 int bus_exec_context_set_transient_property(
739 sd_bus_message *message,
740 UnitSetPropertiesMode mode,
741 sd_bus_error *error) {
750 if (streq(name, "User")) {
753 r = sd_bus_message_read(message, "s", &uu);
757 if (mode != UNIT_CHECK) {
773 unit_write_drop_in_private_format(u, mode, name, "User=%s\n", uu);
778 } else if (streq(name, "Group")) {
781 r = sd_bus_message_read(message, "s", &gg);
785 if (mode != UNIT_CHECK) {
801 unit_write_drop_in_private_format(u, mode, name, "Group=%s\n", gg);
806 } else if (streq(name, "Nice")) {
809 r = sd_bus_message_read(message, "i", &n);
813 if (n < PRIO_MIN || n >= PRIO_MAX)
814 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Nice value out of range");
816 if (mode != UNIT_CHECK) {
818 unit_write_drop_in_private_format(u, mode, name, "Nice=%i\n", n);
823 } else if (streq(name, "Environment")) {
825 _cleanup_strv_free_ char **l = NULL;
827 r = sd_bus_message_read_strv(message, &l);
831 if (!strv_env_is_valid(l))
832 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment block.");
834 if (mode != UNIT_CHECK) {
835 _cleanup_free_ char *joined = NULL;
838 e = strv_env_merge(2, c->environment, l);
842 strv_free(c->environment);
845 joined = strv_join(c->environment, " ");
849 unit_write_drop_in_private_format(u, mode, name, "Environment=%s\n", joined);
854 } else if (rlimit_from_string(name) >= 0) {
858 r = sd_bus_message_read(message, "t", &rl);
862 if (rl == (uint64_t) -1)
867 if ((uint64_t) x != rl)
871 if (mode != UNIT_CHECK) {
874 z = rlimit_from_string(name);
877 c->rlimit[z] = new(struct rlimit, 1);
882 c->rlimit[z]->rlim_cur = c->rlimit[z]->rlim_max = x;
884 if (x == RLIM_INFINITY)
885 unit_write_drop_in_private_format(u, mode, name, "%s=infinity\n", name);
887 unit_write_drop_in_private_format(u, mode, name, "%s=%" PRIu64 "\n", name, rl);