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"
31 DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_execute_append_kill_mode
, kill_mode
, KillMode
);
33 DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_execute_append_input
, exec_input
, ExecInput
);
34 DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_execute_append_output
, exec_output
, ExecOutput
);
36 int bus_execute_append_env_files(Manager
*m
, DBusMessageIter
*i
, const char *property
, void *data
) {
37 char **env_files
= data
, **j
;
38 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(Manager
*m
, DBusMessageIter
*i
, const char *property
, void *data
) {
70 ExecContext
*c
= data
;
78 if (c
->oom_score_adjust_set
)
79 n
= c
->oom_score_adjust
;
84 if (read_one_line_file("/proc/self/oom_score_adj", &t
) >= 0) {
87 } else if (read_one_line_file("/proc/self/oom_adj", &t
) >= 0) {
91 if (n
== OOM_ADJUST_MAX
)
92 n
= OOM_SCORE_ADJ_MAX
;
94 n
= (n
* OOM_SCORE_ADJ_MAX
) / -OOM_DISABLE
;
98 if (!dbus_message_iter_append_basic(i
, DBUS_TYPE_INT32
, &n
))
104 int bus_execute_append_nice(Manager
*m
, DBusMessageIter
*i
, const char *property
, void *data
) {
105 ExecContext
*c
= data
;
116 n
= getpriority(PRIO_PROCESS
, 0);
118 if (!dbus_message_iter_append_basic(i
, DBUS_TYPE_INT32
, &n
))
124 int bus_execute_append_ioprio(Manager
*m
, DBusMessageIter
*i
, const char *property
, void *data
) {
125 ExecContext
*c
= data
;
136 n
= ioprio_get(IOPRIO_WHO_PROCESS
, 0);
138 if (!dbus_message_iter_append_basic(i
, DBUS_TYPE_INT32
, &n
))
144 int bus_execute_append_cpu_sched_policy(Manager
*m
, DBusMessageIter
*i
, const char *property
, void *data
) {
145 ExecContext
*c
= data
;
153 if (c
->cpu_sched_set
)
154 n
= c
->cpu_sched_policy
;
156 n
= sched_getscheduler(0);
158 if (!dbus_message_iter_append_basic(i
, DBUS_TYPE_INT32
, &n
))
164 int bus_execute_append_cpu_sched_priority(Manager
*m
, DBusMessageIter
*i
, const char *property
, void *data
) {
165 ExecContext
*c
= data
;
173 if (c
->cpu_sched_set
)
174 n
= c
->cpu_sched_priority
;
176 struct sched_param p
;
180 if (sched_getparam(0, &p
) >= 0)
181 n
= p
.sched_priority
;
184 if (!dbus_message_iter_append_basic(i
, DBUS_TYPE_INT32
, &n
))
190 int bus_execute_append_affinity(Manager
*m
, DBusMessageIter
*i
, const char *property
, void *data
) {
191 ExecContext
*c
= data
;
200 if (!dbus_message_iter_open_container(i
, DBUS_TYPE_ARRAY
, "y", &sub
))
204 b
= dbus_message_iter_append_fixed_array(&sub
, DBUS_TYPE_BYTE
, &c
->cpuset
, CPU_ALLOC_SIZE(c
->cpuset_ncpus
));
206 b
= dbus_message_iter_append_fixed_array(&sub
, DBUS_TYPE_BYTE
, &c
->cpuset
, 0);
211 if (!dbus_message_iter_close_container(i
, &sub
))
217 int bus_execute_append_timer_slack_nsec(Manager
*m
, DBusMessageIter
*i
, const char *property
, void *data
) {
218 ExecContext
*c
= data
;
226 if (c
->timer_slack_nsec_set
)
227 u
= (uint64_t) c
->timer_slack_nsec
;
229 u
= (uint64_t) prctl(PR_GET_TIMERSLACK
);
231 if (!dbus_message_iter_append_basic(i
, DBUS_TYPE_UINT64
, &u
))
237 int bus_execute_append_capability_bs(Manager
*m
, DBusMessageIter
*i
, const char *property
, void *data
) {
238 ExecContext
*c
= data
;
239 uint64_t normal
, inverted
;
246 /* We store this negated internally, to match the kernel, bu
247 * we expose it normalized. */
249 normal
= *(uint64_t*) data
;
252 return bus_property_append_uint64(m
, i
, property
, &inverted
);
255 int bus_execute_append_capabilities(Manager
*m
, DBusMessageIter
*i
, const char *property
, void *data
) {
256 ExecContext
*c
= data
;
267 s
= t
= cap_to_text(c
->capabilities
, NULL
);
274 b
= dbus_message_iter_append_basic(i
, DBUS_TYPE_STRING
, &s
);
285 int bus_execute_append_rlimits(Manager
*m
, DBusMessageIter
*i
, const char *property
, void *data
) {
286 ExecContext
*c
= data
;
295 assert_se((r
= rlimit_from_string(property
)) >= 0);
298 u
= (uint64_t) c
->rlimit
[r
]->rlim_max
;
305 u
= (uint64_t) rl
.rlim_max
;
308 if (!dbus_message_iter_append_basic(i
, DBUS_TYPE_UINT64
, &u
))
314 int bus_execute_append_command(Manager
*m
, DBusMessageIter
*i
, const char *property
, void *data
) {
315 ExecCommand
*c
= data
;
316 DBusMessageIter sub
, sub2
, sub3
;
322 if (!dbus_message_iter_open_container(i
, DBUS_TYPE_ARRAY
, "(sasbttuii)", &sub
))
325 LIST_FOREACH(command
, c
, c
) {
328 int32_t code
, status
;
333 if (!dbus_message_iter_open_container(&sub
, DBUS_TYPE_STRUCT
, NULL
, &sub2
) ||
334 !dbus_message_iter_append_basic(&sub2
, DBUS_TYPE_STRING
, &c
->path
) ||
335 !dbus_message_iter_open_container(&sub2
, DBUS_TYPE_ARRAY
, "s", &sub3
))
338 STRV_FOREACH(l
, c
->argv
)
339 if (!dbus_message_iter_append_basic(&sub3
, DBUS_TYPE_STRING
, l
))
342 pid
= (uint32_t) c
->exec_status
.pid
;
343 code
= (int32_t) c
->exec_status
.code
;
344 status
= (int32_t) c
->exec_status
.status
;
346 if (!dbus_message_iter_close_container(&sub2
, &sub3
) ||
347 !dbus_message_iter_append_basic(&sub2
, DBUS_TYPE_BOOLEAN
, &c
->ignore
) ||
348 !dbus_message_iter_append_basic(&sub2
, DBUS_TYPE_UINT64
, &c
->exec_status
.start_timestamp
.realtime
) ||
349 !dbus_message_iter_append_basic(&sub2
, DBUS_TYPE_UINT64
, &c
->exec_status
.exit_timestamp
.realtime
) ||
350 !dbus_message_iter_append_basic(&sub2
, DBUS_TYPE_UINT32
, &pid
) ||
351 !dbus_message_iter_append_basic(&sub2
, DBUS_TYPE_INT32
, &code
) ||
352 !dbus_message_iter_append_basic(&sub2
, DBUS_TYPE_INT32
, &status
))
355 if (!dbus_message_iter_close_container(&sub
, &sub2
))
359 if (!dbus_message_iter_close_container(i
, &sub
))