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 General Public License as published by
10 the Free Software Foundation; either version 2 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 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
23 #include <dbus/dbus.h>
24 #include <sys/prctl.h>
26 #include "dbus-execute.h"
30 #include "dbus-common.h"
32 DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_execute_append_kill_mode
, kill_mode
, KillMode
);
34 DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_execute_append_input
, exec_input
, ExecInput
);
35 DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_execute_append_output
, exec_output
, ExecOutput
);
37 int bus_execute_append_env_files(DBusMessageIter
*i
, const char *property
, void *data
) {
38 char **env_files
= data
, **j
;
39 DBusMessageIter sub
, sub2
;
44 if (!dbus_message_iter_open_container(i
, DBUS_TYPE_ARRAY
, "(sb)", &sub
))
47 STRV_FOREACH(j
, env_files
) {
48 dbus_bool_t b
= false;
56 if (!dbus_message_iter_open_container(&sub
, DBUS_TYPE_STRUCT
, NULL
, &sub2
) ||
57 !dbus_message_iter_append_basic(&sub2
, DBUS_TYPE_STRING
, &fn
) ||
58 !dbus_message_iter_append_basic(&sub2
, DBUS_TYPE_BOOLEAN
, &b
) ||
59 !dbus_message_iter_close_container(&sub
, &sub2
))
63 if (!dbus_message_iter_close_container(i
, &sub
))
69 int bus_execute_append_oom_score_adjust(DBusMessageIter
*i
, const char *property
, void *data
) {
70 ExecContext
*c
= data
;
77 if (c
->oom_score_adjust_set
)
78 n
= c
->oom_score_adjust
;
83 if (read_one_line_file("/proc/self/oom_score_adj", &t
) >= 0) {
86 } else if (read_one_line_file("/proc/self/oom_adj", &t
) >= 0) {
90 if (n
== OOM_ADJUST_MAX
)
91 n
= OOM_SCORE_ADJ_MAX
;
93 n
= (n
* OOM_SCORE_ADJ_MAX
) / -OOM_DISABLE
;
97 if (!dbus_message_iter_append_basic(i
, DBUS_TYPE_INT32
, &n
))
103 int bus_execute_append_nice(DBusMessageIter
*i
, const char *property
, void *data
) {
104 ExecContext
*c
= data
;
114 n
= getpriority(PRIO_PROCESS
, 0);
116 if (!dbus_message_iter_append_basic(i
, DBUS_TYPE_INT32
, &n
))
122 int bus_execute_append_ioprio(DBusMessageIter
*i
, const char *property
, void *data
) {
123 ExecContext
*c
= data
;
133 n
= ioprio_get(IOPRIO_WHO_PROCESS
, 0);
135 if (!dbus_message_iter_append_basic(i
, DBUS_TYPE_INT32
, &n
))
141 int bus_execute_append_cpu_sched_policy(DBusMessageIter
*i
, const char *property
, void *data
) {
142 ExecContext
*c
= data
;
149 if (c
->cpu_sched_set
)
150 n
= c
->cpu_sched_policy
;
152 n
= sched_getscheduler(0);
154 if (!dbus_message_iter_append_basic(i
, DBUS_TYPE_INT32
, &n
))
160 int bus_execute_append_cpu_sched_priority(DBusMessageIter
*i
, const char *property
, void *data
) {
161 ExecContext
*c
= data
;
168 if (c
->cpu_sched_set
)
169 n
= c
->cpu_sched_priority
;
171 struct sched_param p
;
175 if (sched_getparam(0, &p
) >= 0)
176 n
= p
.sched_priority
;
179 if (!dbus_message_iter_append_basic(i
, DBUS_TYPE_INT32
, &n
))
185 int bus_execute_append_affinity(DBusMessageIter
*i
, const char *property
, void *data
) {
186 ExecContext
*c
= data
;
194 if (!dbus_message_iter_open_container(i
, DBUS_TYPE_ARRAY
, "y", &sub
))
198 b
= dbus_message_iter_append_fixed_array(&sub
, DBUS_TYPE_BYTE
, &c
->cpuset
, CPU_ALLOC_SIZE(c
->cpuset_ncpus
));
200 b
= dbus_message_iter_append_fixed_array(&sub
, DBUS_TYPE_BYTE
, &c
->cpuset
, 0);
205 if (!dbus_message_iter_close_container(i
, &sub
))
211 int bus_execute_append_timer_slack_nsec(DBusMessageIter
*i
, const char *property
, void *data
) {
212 ExecContext
*c
= data
;
219 if (c
->timer_slack_nsec_set
)
220 u
= (uint64_t) c
->timer_slack_nsec
;
222 u
= (uint64_t) prctl(PR_GET_TIMERSLACK
);
224 if (!dbus_message_iter_append_basic(i
, DBUS_TYPE_UINT64
, &u
))
230 int bus_execute_append_capability_bs(DBusMessageIter
*i
, const char *property
, void *data
) {
231 ExecContext
*c
= data
;
232 uint64_t normal
, inverted
;
238 /* We store this negated internally, to match the kernel, bu
239 * we expose it normalized. */
241 normal
= *(uint64_t*) data
;
244 return bus_property_append_uint64(i
, property
, &inverted
);
247 int bus_execute_append_capabilities(DBusMessageIter
*i
, const char *property
, void *data
) {
248 ExecContext
*c
= data
;
258 s
= t
= cap_to_text(c
->capabilities
, NULL
);
265 b
= dbus_message_iter_append_basic(i
, DBUS_TYPE_STRING
, &s
);
276 int bus_execute_append_rlimits(DBusMessageIter
*i
, const char *property
, void *data
) {
277 ExecContext
*c
= data
;
285 assert_se((r
= rlimit_from_string(property
)) >= 0);
288 u
= (uint64_t) c
->rlimit
[r
]->rlim_max
;
295 u
= (uint64_t) rl
.rlim_max
;
298 if (!dbus_message_iter_append_basic(i
, DBUS_TYPE_UINT64
, &u
))
304 int bus_execute_append_command(DBusMessageIter
*i
, const char *property
, void *data
) {
305 ExecCommand
*c
= data
;
306 DBusMessageIter sub
, sub2
, sub3
;
311 if (!dbus_message_iter_open_container(i
, DBUS_TYPE_ARRAY
, "(sasbttuii)", &sub
))
314 LIST_FOREACH(command
, c
, c
) {
317 int32_t code
, status
;
322 if (!dbus_message_iter_open_container(&sub
, DBUS_TYPE_STRUCT
, NULL
, &sub2
) ||
323 !dbus_message_iter_append_basic(&sub2
, DBUS_TYPE_STRING
, &c
->path
) ||
324 !dbus_message_iter_open_container(&sub2
, DBUS_TYPE_ARRAY
, "s", &sub3
))
327 STRV_FOREACH(l
, c
->argv
)
328 if (!dbus_message_iter_append_basic(&sub3
, DBUS_TYPE_STRING
, l
))
331 pid
= (uint32_t) c
->exec_status
.pid
;
332 code
= (int32_t) c
->exec_status
.code
;
333 status
= (int32_t) c
->exec_status
.status
;
335 if (!dbus_message_iter_close_container(&sub2
, &sub3
) ||
336 !dbus_message_iter_append_basic(&sub2
, DBUS_TYPE_BOOLEAN
, &c
->ignore
) ||
337 !dbus_message_iter_append_basic(&sub2
, DBUS_TYPE_UINT64
, &c
->exec_status
.start_timestamp
.realtime
) ||
338 !dbus_message_iter_append_basic(&sub2
, DBUS_TYPE_UINT64
, &c
->exec_status
.start_timestamp
.monotonic
) ||
339 !dbus_message_iter_append_basic(&sub2
, DBUS_TYPE_UINT64
, &c
->exec_status
.exit_timestamp
.realtime
) ||
340 !dbus_message_iter_append_basic(&sub2
, DBUS_TYPE_UINT64
, &c
->exec_status
.exit_timestamp
.monotonic
) ||
341 !dbus_message_iter_append_basic(&sub2
, DBUS_TYPE_UINT32
, &pid
) ||
342 !dbus_message_iter_append_basic(&sub2
, DBUS_TYPE_INT32
, &code
) ||
343 !dbus_message_iter_append_basic(&sub2
, DBUS_TYPE_INT32
, &status
))
346 if (!dbus_message_iter_close_container(&sub
, &sub2
))
350 if (!dbus_message_iter_close_container(i
, &sub
))