-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.c
143 lines (127 loc) · 3.6 KB
/
main.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#include "controller.h"
#include "syslog.h"
#include "util.h"
#include <fcntl.h>
#include <stdbool.h>
#include <stdio.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <unistd.h>
#define STR_INT_MAX 16
static const char* default_dbus_socket_path = "/run/dbus/system_bus_socket";
#ifdef HAVE_S6
static const char* default_s6_dbuscandir = "/run/dbus_activated_services";
extern const char* s6_dbuscandir; // TODO: pass around properly
extern bool ignore_setactivenv; // TODO: pass around properly
#endif
static const char* dummy_machine_id = "00000000000000000000000000000001";
static void check_3_open() {
if (fcntl(3, F_GETFD) < 0) handle_error("readiness notification");
}
const char *usage = "usage: dbus-controller-%s [-h] dbus-broker\n\
\n\
%s controller for dbus-broker\n\
\n\
positional arguments:\n\
dbus-broker dbus-broker to execute\n\
\n\
optional arguments:\n\
-d dbus socket path (default: %s)\n\
-s open a syslog connection for dbus-broker\n\
-3 notify readiness on fd 3\n"
#ifdef HAVE_S6
"\n\
-a s6 scandir of dbus-activated services (default: %s)\n\
-e ignore requests to set the activation environment\n"
#endif
"\n\
-h show this help message and exit\n";
int main(int argc, char* argv[]) {
const char* dbus_socket_path = default_dbus_socket_path;
bool notif = false;
bool syslog = false;
#ifdef HAVE_S6
s6_dbuscandir = default_s6_dbuscandir;
#endif
int opt;
#ifdef HAVE_S6
while ((opt = getopt(argc, argv, "d:ha:es3")) != -1) {
#else
while ((opt = getopt(argc, argv, "d:hs3")) != -1) {
#endif
switch (opt) {
case 'd': dbus_socket_path = optarg; break;
case 's': syslog = true; break;
case '3': check_3_open(); notif = true; break;
#ifdef HAVE_S6
case 'a': s6_dbuscandir = optarg; break;
case 'e': ignore_setactivenv = true; break;
#endif
default:;
#ifdef HAVE_S6
const char *impl = "s6";
#else
const char *impl = "dummy";
#endif
printf(usage, impl, impl, default_dbus_socket_path
#ifdef HAVE_S6
, default_s6_dbuscandir
#endif
);
return EXIT_FAILURE;
}
}
if (argc <= optind) {
printf(usage, default_dbus_socket_path);
return EXIT_FAILURE;
}
const char* const broker_path = argv[optind];
int controller[2];
socketpair(PF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0, controller);
int logfd = syslog ? syslog_connect_socket() : -1;
pid_t cpid = fork();
if (cpid == 0) {
close(controller[0]);
if (notif) close(3);
char str_controller[STR_INT_MAX];
snprintf(str_controller, sizeof(str_controller), "%d", controller[1]);
if (logfd < 0) {
const char* const cmdline[] = {
"dbus-broker",
"--controller", str_controller,
"--machine-id", dummy_machine_id,
NULL};
execvp(broker_path, (char* const*)cmdline);
} else {
char str_log[STR_INT_MAX];
snprintf(str_log, sizeof(str_log), "%d", logfd);
const char* const cmdline_log[] = {
"dbus-broker",
"--controller", str_controller,
"--machine-id", dummy_machine_id,
"--log", str_log,
NULL};
execvp(broker_path, (char* const*)cmdline_log);
}
perror("Failed to execute dbus-broker");
_exit(EXIT_FAILURE);
/* NOTREACHED */
} else {
close(controller[1]);
if (logfd >= 0) close(logfd);
#ifdef HAVE_S6
add_s6_servicedirs(s6_dbuscandir);
#endif
controller_setup(controller[0], dbus_socket_path);
if (notif) {
write(3, "\n", 1); //dbus ready to accept connections
close(3);
}
#ifdef HAVE_S6
controller_run_signals();
#else
controller_run();
#endif
// do we need to do something here to make the broker exit "cleanly"?
}
}