Add support for L4Re Virtio Sockets
[src/app-framework-binder.git] / src / systemd.c
1 /*
2  * Copyright (C) 2015-2019 "IoT.bzh"
3  * Author José Bollo <jose.bollo@iot.bzh>
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *   http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 #if WITH_SYSTEMD
19
20 #define _GNU_SOURCE
21
22 #include <unistd.h>
23 #include <errno.h>
24
25 #include <systemd/sd-event.h>
26 #include <systemd/sd-bus.h>
27 #include <systemd/sd-daemon.h>
28
29 #include "systemd.h"
30
31 static struct sd_bus *sdbusopen(struct sd_bus **p, int (*f)(struct sd_bus **))
32 {
33         int rc;
34         struct sd_bus *r;
35
36         r = *p;
37         if (!r) {
38                 rc = f(&r);
39                 if (rc >= 0) {
40                         rc = sd_bus_attach_event(r, systemd_get_event_loop(), 0);
41                         if (rc < 0) {
42                                 sd_bus_unref(r);
43                                 r = 0;
44                         }
45                 }
46                 if (rc < 0)
47                         errno = -rc;
48                 *p = r;
49         }
50         return r;
51 }
52
53 struct sd_event *systemd_get_event_loop()
54 {
55         static struct sd_event *result = 0;
56         int rc;
57
58         if (!result) {
59                 rc = sd_event_new(&result);
60                 if (rc < 0) {
61                         errno = -rc;
62                         result = NULL;
63                 }
64         }
65         return result;
66 }
67
68 struct sd_bus *systemd_get_user_bus()
69 {
70         static struct sd_bus *result = 0;
71         return sdbusopen((void*)&result, (void*)sd_bus_open_user);
72 }
73
74 struct sd_bus *systemd_get_system_bus()
75 {
76         static struct sd_bus *result = 0;
77         return sdbusopen((void*)&result, (void*)sd_bus_open_system);
78 }
79
80 static char **fds_names()
81 {
82         static char *null;
83         static char **names;
84
85         int rc;
86
87         if (!names) {
88                 rc = sd_listen_fds_with_names(1, &names);
89                 if (rc <= 0) {
90                         errno = -rc;
91                         names = &null;
92                 }
93         }
94         return names;
95 }
96
97 int systemd_fds_init()
98 {
99         errno = 0;
100         fds_names();
101         return -!!errno;
102 }
103
104 int systemd_fds_for(const char *name)
105 {
106         int idx;
107         char **names;
108
109         names = fds_names();
110         for (idx = 0 ; names[idx] != NULL ; idx++)
111                 if (!strcmp(name, names[idx]))
112                         return idx + SD_LISTEN_FDS_START;
113
114         errno = ENOENT;
115         return -1;
116 }
117
118 #endif