Lines 75-87
Link Here
|
75 |
|
75 |
|
76 |
void accept_cb (ev::io &w, int revents); ev::io accept_ev; |
76 |
void accept_cb (ev::io &w, int revents); ev::io accept_ev; |
77 |
|
77 |
|
78 |
unix_listener (const char *sockname); |
78 |
unix_listener (int sockfd); |
|
|
79 |
static int open (const char * sockname); |
79 |
}; |
80 |
}; |
80 |
|
81 |
|
81 |
unix_listener::unix_listener (const char *sockname) |
82 |
unix_listener::unix_listener (int sockfd) : fd(sockfd) |
82 |
{ |
83 |
{ |
83 |
accept_ev.set<unix_listener, &unix_listener::accept_cb> (this); |
84 |
accept_ev.set<unix_listener, &unix_listener::accept_cb> (this); |
|
|
85 |
accept_ev.start (fd, ev::READ); |
86 |
} |
84 |
|
87 |
|
|
|
88 |
int unix_listener::open (const char * sockname) |
89 |
{ |
85 |
sockaddr_un sa; |
90 |
sockaddr_un sa; |
86 |
|
91 |
|
87 |
if (strlen (sockname) >= sizeof(sa.sun_path)) |
92 |
if (strlen (sockname) >= sizeof(sa.sun_path)) |
Lines 90-95
Link Here
|
90 |
exit (EXIT_FAILURE); |
95 |
exit (EXIT_FAILURE); |
91 |
} |
96 |
} |
92 |
|
97 |
|
|
|
98 |
int fd; |
93 |
if ((fd = socket (AF_UNIX, SOCK_STREAM, 0)) < 0) |
99 |
if ((fd = socket (AF_UNIX, SOCK_STREAM, 0)) < 0) |
94 |
{ |
100 |
{ |
95 |
perror ("unable to create listening socket"); |
101 |
perror ("unable to create listening socket"); |
Lines 120-126
Link Here
|
120 |
exit (EXIT_FAILURE); |
126 |
exit (EXIT_FAILURE); |
121 |
} |
127 |
} |
122 |
|
128 |
|
123 |
accept_ev.start (fd, ev::READ); |
129 |
return fd; |
124 |
} |
130 |
} |
125 |
|
131 |
|
126 |
void unix_listener::accept_cb (ev::io &w, int revents) |
132 |
void unix_listener::accept_cb (ev::io &w, int revents) |
Lines 224-229
Link Here
|
224 |
return err (); |
230 |
return err (); |
225 |
} |
231 |
} |
226 |
|
232 |
|
|
|
233 |
enum { LISTEN_SOCKET_FILENO = 3 }; |
234 |
|
235 |
// This mechanism is available on operating systems other than Linux and from softwares other than systemd. |
236 |
static int get_pre_opened_listen_fd() |
237 |
{ |
238 |
const char * old; |
239 |
|
240 |
const char * listen_pid (getenv ("LISTEN_PID")); |
241 |
if (!listen_pid) |
242 |
return -1; |
243 |
old = listen_pid; |
244 |
unsigned long lp(strtoul (listen_pid, const_cast<char **>(&listen_pid), 0)); |
245 |
if (*listen_pid || old == listen_pid) |
246 |
return -1; |
247 |
|
248 |
const int pid (getpid ()); |
249 |
if (0 > pid) |
250 |
return -1; |
251 |
if (static_cast<unsigned long>(pid) != lp) |
252 |
return -1; |
253 |
|
254 |
const char * listen_fds (getenv ("LISTEN_FDS")); |
255 |
if (!listen_fds) |
256 |
return -1; |
257 |
old = listen_fds; |
258 |
unsigned long lf(strtoul (listen_fds, const_cast<char **>(&listen_fds), 0)); |
259 |
if (*listen_fds || old == listen_fds) |
260 |
return -1; |
261 |
|
262 |
if (INT_MAX < lf || lf < 1) |
263 |
return -1; |
264 |
int n = static_cast<int>(lf); |
265 |
|
266 |
unsetenv ("LISTEN_PID"); |
267 |
unsetenv ("LISTEN_FDS"); |
268 |
unsetenv ("LISTEN_FDNAMES"); |
269 |
for (int i(0U); i < n; ++i) |
270 |
fcntl (LISTEN_SOCKET_FILENO + i, F_SETFD, FD_CLOEXEC); |
271 |
|
272 |
return LISTEN_SOCKET_FILENO; |
273 |
} |
274 |
|
227 |
int |
275 |
int |
228 |
main (int argc, char *argv[]) |
276 |
main (int argc, char *argv[]) |
229 |
{ |
277 |
{ |
Lines 275-292
Link Here
|
275 |
if (const char *dpy = getenv ("DISPLAY")) |
323 |
if (const char *dpy = getenv ("DISPLAY")) |
276 |
displays.get (dpy ? dpy : ":0"); // move string logic into rxvt_display maybe? |
324 |
displays.get (dpy ? dpy : ":0"); // move string logic into rxvt_display maybe? |
277 |
|
325 |
|
278 |
char *sockname = rxvt_connection::unix_sockname (); |
326 |
int sockfd = get_pre_opened_listen_fd(); |
279 |
unix_listener l (sockname); |
327 |
if (-1 == sockfd) |
280 |
|
|
|
281 |
chdir ("/"); |
282 |
|
283 |
if (!opt_quiet) |
284 |
{ |
328 |
{ |
285 |
printf ("rxvt-unicode daemon listening on %s.\n", sockname); |
329 |
char *sockname = rxvt_connection::unix_sockname (); |
286 |
fflush (stdout); |
330 |
sockfd = unix_listener::open (sockname); |
|
|
331 |
if (!opt_quiet) |
332 |
rxvt_log ("%s: daemon listening on %s.\n", argv[0], sockname); |
333 |
free (sockname); |
334 |
} else { |
335 |
fcntl (sockfd, F_SETFL, O_NONBLOCK); // in case the socket unit is wrong |
336 |
if (!opt_quiet) |
337 |
rxvt_log ("%s: daemon using pre-opened listening fd %d.\n", argv[0], sockfd); |
287 |
} |
338 |
} |
288 |
|
339 |
|
289 |
free (sockname); |
340 |
unix_listener l (sockfd); |
|
|
341 |
|
342 |
chdir ("/"); |
290 |
|
343 |
|
291 |
pid_t pid = 0; |
344 |
pid_t pid = 0; |
292 |
if (opt_fork) |
345 |
if (opt_fork) |