]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/console/consoled-manager.c
treewide: more log_*_errno() conversions, multiline calls
[thirdparty/systemd.git] / src / console / consoled-manager.c
CommitLineData
ce7b9f50
DH
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2014 David Herrmann <dh.herrmann@gmail.com>
7
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.
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 Lesser General Public License for more details.
17
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/>.
20***/
21
22#include <errno.h>
23#include <libudev.h>
24#include <stdlib.h>
25#include <string.h>
26#include "consoled.h"
27#include "grdev.h"
28#include "idev.h"
29#include "log.h"
30#include "sd-bus.h"
31#include "sd-daemon.h"
32#include "sd-event.h"
33#include "sd-login.h"
34#include "sysview.h"
35#include "unifont.h"
36#include "util.h"
37
38int manager_new(Manager **out) {
39 _cleanup_(manager_freep) Manager *m = NULL;
40 int r;
41
42 assert(out);
43
44 m = new0(Manager, 1);
45 if (!m)
46 return -ENOMEM;
47
48 r = sd_event_default(&m->event);
49 if (r < 0)
50 return r;
51
52 r = sd_event_set_watchdog(m->event, true);
53 if (r < 0)
54 return r;
55
56 r = sigprocmask_many(SIG_BLOCK, SIGTERM, SIGQUIT, SIGINT, SIGWINCH, SIGCHLD, -1);
57 if (r < 0)
58 return r;
59
60 r = sd_event_add_signal(m->event, NULL, SIGTERM, NULL, NULL);
61 if (r < 0)
62 return r;
63
64 r = sd_event_add_signal(m->event, NULL, SIGQUIT, NULL, NULL);
65 if (r < 0)
66 return r;
67
68 r = sd_event_add_signal(m->event, NULL, SIGINT, NULL, NULL);
69 if (r < 0)
70 return r;
71
72 r = sd_bus_open_system(&m->sysbus);
73 if (r < 0)
74 return r;
75
76 r = sd_bus_attach_event(m->sysbus, m->event, SD_EVENT_PRIORITY_NORMAL);
77 if (r < 0)
78 return r;
79
80 r = unifont_new(&m->uf);
81 if (r < 0)
82 return r;
83
84 r = sysview_context_new(&m->sysview,
85 SYSVIEW_CONTEXT_SCAN_LOGIND |
86 SYSVIEW_CONTEXT_SCAN_EVDEV |
87 SYSVIEW_CONTEXT_SCAN_DRM,
88 m->event,
89 m->sysbus,
90 NULL);
91 if (r < 0)
92 return r;
93
94 r = grdev_context_new(&m->grdev, m->event, m->sysbus);
95 if (r < 0)
96 return r;
97
98 r = idev_context_new(&m->idev, m->event, m->sysbus);
99 if (r < 0)
100 return r;
101
102 *out = m;
103 m = NULL;
104 return 0;
105}
106
107Manager *manager_free(Manager *m) {
108 if (!m)
109 return NULL;
110
111 assert(!m->workspace_list);
112
113 m->idev = idev_context_unref(m->idev);
114 m->grdev = grdev_context_unref(m->grdev);
115 m->sysview = sysview_context_free(m->sysview);
116 m->uf = unifont_unref(m->uf);
117 m->sysbus = sd_bus_unref(m->sysbus);
118 m->event = sd_event_unref(m->event);
119 free(m);
120
121 return NULL;
122}
123
124static int manager_sysview_session_filter(Manager *m, sysview_event *event) {
125 const char *sid = event->session_filter.id;
126 _cleanup_free_ char *desktop = NULL;
127 int r;
128
129 assert(sid);
130
131 r = sd_session_get_desktop(sid, &desktop);
132 if (r < 0)
133 return 0;
134
09077149 135 return streq(desktop, "systemd-console");
ce7b9f50
DH
136}
137
138static int manager_sysview_session_add(Manager *m, sysview_event *event) {
139 sysview_session *session = event->session_add.session;
140 Session *s;
141 int r;
142
143 r = sysview_session_take_control(session);
144 if (r < 0) {
c33b3297
MS
145 log_error_errno(r, "Cannot request session control on '%s': %m",
146 sysview_session_get_name(session));
ce7b9f50
DH
147 return r;
148 }
149
150 r = session_new(&s, m, session);
151 if (r < 0) {
c33b3297
MS
152 log_error_errno(r, "Cannot create session on '%s': %m",
153 sysview_session_get_name(session));
ce7b9f50
DH
154 sysview_session_release_control(session);
155 return r;
156 }
157
158 sysview_session_set_userdata(session, s);
159
160 return 0;
161}
162
163static int manager_sysview_session_remove(Manager *m, sysview_event *event) {
164 sysview_session *session = event->session_remove.session;
165 Session *s;
166
167 s = sysview_session_get_userdata(session);
168 if (!s)
169 return 0;
170
171 session_free(s);
172
173 return 0;
174}
175
176static int manager_sysview_session_attach(Manager *m, sysview_event *event) {
177 sysview_session *session = event->session_attach.session;
178 sysview_device *device = event->session_attach.device;
179 Session *s;
180
181 s = sysview_session_get_userdata(session);
182 if (!s)
183 return 0;
184
185 session_add_device(s, device);
186
187 return 0;
188}
189
190static int manager_sysview_session_detach(Manager *m, sysview_event *event) {
191 sysview_session *session = event->session_detach.session;
192 sysview_device *device = event->session_detach.device;
193 Session *s;
194
195 s = sysview_session_get_userdata(session);
196 if (!s)
197 return 0;
198
199 session_remove_device(s, device);
200
201 return 0;
202}
203
204static int manager_sysview_session_refresh(Manager *m, sysview_event *event) {
205 sysview_session *session = event->session_refresh.session;
206 sysview_device *device = event->session_refresh.device;
207 struct udev_device *ud = event->session_refresh.ud;
208 Session *s;
209
210 s = sysview_session_get_userdata(session);
211 if (!s)
212 return 0;
213
214 session_refresh_device(s, device, ud);
215
216 return 0;
217}
218
219static int manager_sysview_session_control(Manager *m, sysview_event *event) {
220 sysview_session *session = event->session_control.session;
221 int error = event->session_control.error;
222 Session *s;
223
224 s = sysview_session_get_userdata(session);
225 if (!s)
226 return 0;
227
228 if (error < 0) {
c33b3297
MS
229 log_error_errno(error, "Cannot take session control on '%s': %m",
230 sysview_session_get_name(session));
ce7b9f50
DH
231 session_free(s);
232 sysview_session_set_userdata(session, NULL);
233 return -error;
234 }
235
236 return 0;
237}
238
239static int manager_sysview_fn(sysview_context *sysview, void *userdata, sysview_event *event) {
240 Manager *m = userdata;
241 int r;
242
243 assert(m);
244
245 switch (event->type) {
246 case SYSVIEW_EVENT_SESSION_FILTER:
247 r = manager_sysview_session_filter(m, event);
248 break;
249 case SYSVIEW_EVENT_SESSION_ADD:
250 r = manager_sysview_session_add(m, event);
251 break;
252 case SYSVIEW_EVENT_SESSION_REMOVE:
253 r = manager_sysview_session_remove(m, event);
254 break;
255 case SYSVIEW_EVENT_SESSION_ATTACH:
256 r = manager_sysview_session_attach(m, event);
257 break;
258 case SYSVIEW_EVENT_SESSION_DETACH:
259 r = manager_sysview_session_detach(m, event);
260 break;
261 case SYSVIEW_EVENT_SESSION_REFRESH:
262 r = manager_sysview_session_refresh(m, event);
263 break;
264 case SYSVIEW_EVENT_SESSION_CONTROL:
265 r = manager_sysview_session_control(m, event);
266 break;
267 default:
268 r = 0;
269 break;
270 }
271
272 return r;
273}
274
275int manager_run(Manager *m) {
276 int r;
277
278 assert(m);
279
280 r = sysview_context_start(m->sysview, manager_sysview_fn, m);
281 if (r < 0)
282 return r;
283
284 r = sd_event_loop(m->event);
285
286 sysview_context_stop(m->sysview);
287 return r;
288}