chiark / gitweb /
systemctl: sort 'list-units' output
[elogind.git] / src / dbus-execute.c
1 /*-*- Mode: C; c-basic-offset: 8 -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2010 Lennart Poettering
7
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.
12
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.
17
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/>.
20 ***/
21
22 #include <errno.h>
23 #include <dbus/dbus.h>
24 #include <sys/prctl.h>
25
26 #include "dbus-execute.h"
27 #include "missing.h"
28 #include "ioprio.h"
29 #include "strv.h"
30
31 DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_execute_append_kill_mode, kill_mode, KillMode);
32
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);
35
36 int bus_execute_append_oom_adjust(Manager *m, DBusMessageIter *i, const char *property, void *data) {
37         ExecContext *c = data;
38         int32_t n;
39
40         assert(m);
41         assert(i);
42         assert(property);
43         assert(c);
44
45         if (c->oom_adjust_set)
46                 n = c->oom_adjust;
47         else {
48                 char *t;
49
50                 n = 0;
51                 if (read_one_line_file("/proc/self/oom_adj", &t) >= 0) {
52                         safe_atoi(t, &n);
53                         free(t);
54                 }
55         }
56
57         if (!dbus_message_iter_append_basic(i, DBUS_TYPE_INT32, &n))
58                 return -ENOMEM;
59
60         return 0;
61 }
62
63 int bus_execute_append_nice(Manager *m, DBusMessageIter *i, const char *property, void *data) {
64         ExecContext *c = data;
65         int32_t n;
66
67         assert(m);
68         assert(i);
69         assert(property);
70         assert(c);
71
72         if (c->nice_set)
73                 n = c->nice;
74         else
75                 n = getpriority(PRIO_PROCESS, 0);
76
77         if (!dbus_message_iter_append_basic(i, DBUS_TYPE_INT32, &n))
78                 return -ENOMEM;
79
80         return 0;
81 }
82
83 int bus_execute_append_ioprio(Manager *m, DBusMessageIter *i, const char *property, void *data) {
84         ExecContext *c = data;
85         int32_t n;
86
87         assert(m);
88         assert(i);
89         assert(property);
90         assert(c);
91
92         if (c->ioprio_set)
93                 n = c->ioprio;
94         else
95                 n = ioprio_get(IOPRIO_WHO_PROCESS, 0);
96
97         if (!dbus_message_iter_append_basic(i, DBUS_TYPE_INT32, &n))
98                 return -ENOMEM;
99
100         return 0;
101 }
102
103 int bus_execute_append_cpu_sched_policy(Manager *m, DBusMessageIter *i, const char *property, void *data) {
104         ExecContext *c = data;
105         int32_t n;
106
107         assert(m);
108         assert(i);
109         assert(property);
110         assert(c);
111
112         if (c->cpu_sched_set)
113                 n = c->cpu_sched_policy;
114         else
115                 n = sched_getscheduler(0);
116
117         if (!dbus_message_iter_append_basic(i, DBUS_TYPE_INT32, &n))
118                 return -ENOMEM;
119
120         return 0;
121 }
122
123 int bus_execute_append_cpu_sched_priority(Manager *m, DBusMessageIter *i, const char *property, void *data) {
124         ExecContext *c = data;
125         int32_t n;
126
127         assert(m);
128         assert(i);
129         assert(property);
130         assert(c);
131
132         if (c->cpu_sched_set)
133                 n = c->cpu_sched_priority;
134         else {
135                 struct sched_param p;
136                 n = 0;
137
138                 zero(p);
139                 if (sched_getparam(0, &p) >= 0)
140                         n = p.sched_priority;
141         }
142
143         if (!dbus_message_iter_append_basic(i, DBUS_TYPE_INT32, &n))
144                 return -ENOMEM;
145
146         return 0;
147 }
148
149 int bus_execute_append_affinity(Manager *m, DBusMessageIter *i, const char *property, void *data) {
150         ExecContext *c = data;
151         dbus_bool_t b;
152         DBusMessageIter sub;
153
154         assert(m);
155         assert(i);
156         assert(property);
157         assert(c);
158
159         if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "y", &sub))
160                 return -ENOMEM;
161
162         if (c->cpuset)
163                 b = dbus_message_iter_append_fixed_array(&sub, DBUS_TYPE_BYTE, &c->cpuset, CPU_ALLOC_SIZE(c->cpuset_ncpus));
164         else
165                 b = dbus_message_iter_append_fixed_array(&sub, DBUS_TYPE_BYTE, &c->cpuset, 0);
166
167         if (!b)
168                 return -ENOMEM;
169
170         if (!dbus_message_iter_close_container(i, &sub))
171                 return -ENOMEM;
172
173         return 0;
174 }
175
176 int bus_execute_append_timer_slack_nsec(Manager *m, DBusMessageIter *i, const char *property, void *data) {
177         ExecContext *c = data;
178         uint64_t u;
179
180         assert(m);
181         assert(i);
182         assert(property);
183         assert(c);
184
185         if (c->timer_slack_nsec_set)
186                 u = (uint64_t) c->timer_slack_nsec;
187         else
188                 u = (uint64_t) prctl(PR_GET_TIMERSLACK);
189
190         if (!dbus_message_iter_append_basic(i, DBUS_TYPE_UINT64, &u))
191                 return -ENOMEM;
192
193         return 0;
194 }
195
196 int bus_execute_append_capabilities(Manager *m, DBusMessageIter *i, const char *property, void *data) {
197         ExecContext *c = data;
198         char *t = NULL;
199         const char *s;
200         dbus_bool_t b;
201
202         assert(m);
203         assert(i);
204         assert(property);
205         assert(c);
206
207         if (c->capabilities)
208                 s = t = cap_to_text(c->capabilities, NULL);
209         else
210                 s = "";
211
212         if (!s)
213                 return -ENOMEM;
214
215         b = dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &s);
216
217         if (t)
218                 cap_free(t);
219
220         if (!b)
221                 return -ENOMEM;
222
223         return 0;
224 }
225
226 int bus_execute_append_rlimits(Manager *m, DBusMessageIter *i, const char *property, void *data) {
227         ExecContext *c = data;
228         int r;
229         uint64_t u;
230
231         assert(m);
232         assert(i);
233         assert(property);
234         assert(c);
235
236         assert_se((r = rlimit_from_string(property)) >= 0);
237
238         if (c->rlimit[r])
239                 u = (uint64_t) c->rlimit[r]->rlim_max;
240         else {
241                 struct rlimit rl;
242
243                 zero(rl);
244                 getrlimit(r, &rl);
245
246                 u = (uint64_t) rl.rlim_max;
247         }
248
249         if (!dbus_message_iter_append_basic(i, DBUS_TYPE_UINT64, &u))
250                 return -ENOMEM;
251
252         return 0;
253 }
254
255 int bus_execute_append_command(Manager *m, DBusMessageIter *i, const char *property, void *data) {
256         ExecCommand *c = data;
257         DBusMessageIter sub, sub2, sub3;
258
259         assert(m);
260         assert(i);
261         assert(property);
262
263         if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "(sasbttuii)", &sub))
264                 return -ENOMEM;
265
266         LIST_FOREACH(command, c, c) {
267                 char **l;
268                 uint32_t pid;
269                 int32_t code, status;
270
271                 if (!c->path)
272                         continue;
273
274                 if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) ||
275                     !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &c->path) ||
276                     !dbus_message_iter_open_container(&sub2, DBUS_TYPE_ARRAY, "s", &sub3))
277                         return -ENOMEM;
278
279                 STRV_FOREACH(l, c->argv)
280                         if (!dbus_message_iter_append_basic(&sub3, DBUS_TYPE_STRING, l))
281                                 return -ENOMEM;
282
283                 pid = (uint32_t) c->exec_status.pid;
284                 code = (int32_t) c->exec_status.code;
285                 status = (int32_t) c->exec_status.status;
286
287                 if (!dbus_message_iter_close_container(&sub2, &sub3) ||
288                     !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_BOOLEAN, &c->ignore) ||
289                     !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT64, &c->exec_status.start_timestamp.realtime) ||
290                     !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT64, &c->exec_status.exit_timestamp.realtime) ||
291                     !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT32, &pid) ||
292                     !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_INT32, &code) ||
293                     !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_INT32, &status))
294                         return -ENOMEM;
295
296                 if (!dbus_message_iter_close_container(&sub, &sub2))
297                         return -ENOMEM;
298         }
299
300         if (!dbus_message_iter_close_container(i, &sub))
301                 return -ENOMEM;
302
303         return 0;
304 }