supervisor: Setup services for local API use
[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 #define _GNU_SOURCE
19
20 #include <unistd.h>
21 #include <errno.h>
22
23 #include <systemd/sd-event.h>
24 #include <systemd/sd-bus.h>
25 #include <systemd/sd-daemon.h>
26
27 #include "systemd.h"
28
29 static struct sd_bus *sdbusopen(struct sd_bus **p, int (*f)(struct sd_bus **))
30 {
31         int rc;
32         struct sd_bus *r;
33
34         r = *p;
35         if (!r) {
36                 rc = f(&r);
37                 if (rc >= 0) {
38                         rc = sd_bus_attach_event(r, systemd_get_event_loop(), 0);
39                         if (rc < 0) {
40                                 sd_bus_unref(r);
41                                 r = 0;
42                         }
43                 }
44                 if (rc < 0)
45                         errno = -rc;
46                 *p = r;
47         }
48         return r;
49 }
50
51 struct sd_event *systemd_get_event_loop()
52 {
53         static struct sd_event *result = 0;
54         int rc;
55
56         if (!result) {
57                 rc = sd_event_new(&result);
58                 if (rc < 0) {
59                         errno = -rc;
60                         result = NULL;
61                 }
62         }
63         return result;
64 }
65
66 struct sd_bus *systemd_get_user_bus()
67 {
68         static struct sd_bus *result = 0;
69         return sdbusopen((void*)&result, (void*)sd_bus_open_user);
70 }
71
72 struct sd_bus *systemd_get_system_bus()
73 {
74         static struct sd_bus *result = 0;
75         return sdbusopen((void*)&result, (void*)sd_bus_open_system);
76 }
77
78 static char **fds_names()
79 {
80         static char *null;
81         static char **names;
82
83         int rc;
84
85         if (!names) {
86                 rc = sd_listen_fds_with_names(1, &names);
87                 if (rc <= 0) {
88                         errno = -rc;
89                         names = &null;
90                 }
91         }
92         return names;
93 }
94
95 int systemd_fds_init()
96 {
97         errno = 0;
98         fds_names();
99         return -!!errno;
100 }
101
102 int systemd_fds_for(const char *name)
103 {
104         int idx;
105         char **names;
106
107         names = fds_names();
108         for (idx = 0 ; names[idx] != NULL ; idx++)
109                 if (!strcmp(name, names[idx]))
110                         return idx + SD_LISTEN_FDS_START;
111
112         errno = ENOENT;
113         return -1;
114 }
115