View | Details | Raw Unified | Return to bug 234276
Collapse All | Expand All

(-)./src/rxvtdaemon.C (+16 lines)
Lines 40-45 Link Here
40
40
41
  if (!path)
41
  if (!path)
42
    {
42
    {
43
      const char * run = getenv ("XDG_RUNTIME_DIR");
44
      if (run)
45
	{
46
	  snprintf (name, PATH_MAX, "%s/urxvt", run);
47
	  mkdir (name, 0755);
48
49
	  // The Base Directory Specification guarantees that the runtime directory is private to both user and machine.
50
	  // So there is no need to differentiate amongst sockets by host name; making it simpler for socket units.
51
	  // Conventionally, subdirectories here do not use hidden names, either.
52
	  snprintf (name, PATH_MAX, "%s/urxvt/daemon", run);
53
	  path = name;
54
	}
55
    }
56
57
  if (!path)
58
    {
43
      struct utsname u;
59
      struct utsname u;
44
      uname (&u);
60
      uname (&u);
45
61
(-)./src/rxvtd.C (-12 / +65 lines)
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)
(-)./doc/rxvtd.1.pod (-6 / +27 lines)
Lines 36-43 Link Here
36
36
37
=item B<-q>, B<--quiet>
37
=item B<-q>, B<--quiet>
38
38
39
Normally, B<@@RXVT_NAME@@d> outputs the message C<< rxvt-unicode daemon
39
Normally, B<@@RXVT_NAME@@d> outputs the message C<< @@RXVT_NAME@@d: daemon
40
listening on <path> >> after binding to its control socket. This option
40
listening on <path> >> after binding to its control socket, or the
41
message C<< @@RXVT_NAME@@d: daemon using pre-opened listening fd <n> >>
42
if it is using an already opened socket. This option
41
will suppress this message (errors and warnings will still be logged).
43
will suppress this message (errors and warnings will still be logged).
42
44
43
=item B<-o>, B<--opendisplay>
45
=item B<-o>, B<--opendisplay>
Lines 98-109 Link Here
98
100
99
=over 4
101
=over 4
100
102
103
=item B<LISTEN_PID>, B<LISTEN_FDS>, B<LISTEN_FDNAMES>
104
105
@@RXVT_NAME@@d takes an already-open file descriptor for its listening
106
socket if these environment variables are set in accordance with the
107
systemd conventions (which are also employed by some other tools).  In
108
this case, it does not create a listening socket itself.
109
101
=item B<RXVT_SOCKET>
110
=item B<RXVT_SOCKET>
102
111
103
Both B<@@RXVT_NAME@@c> and B<@@RXVT_NAME@@d> use the environment
112
@@RXVT_NAME@@d uses the environment variable F<RXVT_SOCKET> if
104
variable F<RXVT_SOCKET> to create a listening socket and to contact
113
present, to create a listening socket.  The variable must specify the
105
the @@RXVT_NAME@@d, respectively. If the variable is missing then
114
absolute path of the local-address-family socket to create.
106
F<<< $HOME/.urxvt/urxvtd-I<< <nodename> >> >>> is used.
115
116
=item B<XDG_RUNTIME_DIR>
117
118
If the F<RXVT_SOCKET> variable is missing, @@RXVT_NAME@@d uses the
119
environment variable F<XDG_RUNTIME_DIR> to create the listening
120
socket, naming it F<<< $XDG_RUNTIME_DIR/urxvt/daemon >>>.
121
122
=item B<HOME>
123
124
If both of those environment variables are missing,
125
F<<< $HOME/.urxvt/urxvtd-I<< <nodename> >> >>> is used, falling
126
back to F<<< /tmp/.urxvt/urxvtd-I<< <nodename> >> >>> if even that environment
127
variable is missing.
107
128
108
=item B<DISPLAY>
129
=item B<DISPLAY>
109
130
(-)./doc/rxvtc.1.man.in (-5 / +15 lines)
Lines 185-195 Link Here
185
started directly.
185
started directly.
186
.IP "\fB\s-1RXVT_SOCKET\s0\fR" 4
186
.IP "\fB\s-1RXVT_SOCKET\s0\fR" 4
187
.IX Item "RXVT_SOCKET"
187
.IX Item "RXVT_SOCKET"
188
Both @@RXVT_NAME@@c and @@RXVT_NAME@@d use the environment variable
188
@@RXVT_NAME@@c uses the environment variable \&\fI\s-1RXVT_SOCKET\s0\fR, if
189
\&\fI\s-1RXVT_SOCKET\s0\fR to create a listening socket and to contact the
189
present, to contact the @@RXVT_NAME@@d.  The variable must specify the
190
@@RXVT_NAME@@d, respectively. If the variable is missing,
190
absolute path of the local-address-family socket to connect to.
191
\&\fI\f(CI$HOME\fI/.urxvt/urxvtd\-\fI<nodename>\fI\fR is used.  The variable must
191
.IP "\fB\s-1XDG_RUNTIME_DIR\s0\fR" 4
192
specify the absolute path of the socket to create.
192
.IX Item "XDG_RUNTIME_DIR"
193
If the \&\fI\s-1RXVT_SOCKET\s0\fR variable is missing, @@RXVT_NAME@@c uses the
194
environment variable \fB\s-1XDG_RUNTIME_DIR\s0\fR to contact the
195
@@RXVT_NAME@@d, connecting to the socket named
196
\&\fI\f(CI$XDG_RUNTIME_DIR\fI/urxvt/daemon\fR.
197
.IP "\fB\s-1HOME\s0\fR" 4
198
.IX Item "HOME"
199
If both of those environment variables are missing,
200
\&\fI\f(CI$HOME\fI/.urxvt/urxvtd\-\fI<nodename>\fI\fR is used, falling
201
back to \&\fI/tmp/.urxvt/urxvtd\-\fI<nodename>\fI\fR if even that environment
202
variable is missing.
193
.SH "SEE ALSO"
203
.SH "SEE ALSO"
194
.IX Header "SEE ALSO"
204
.IX Header "SEE ALSO"
195
@@RXVT_NAME@@(7), @@RXVT_NAME@@d(1)
205
@@RXVT_NAME@@(7), @@RXVT_NAME@@d(1)
(-)./doc/rxvtd.1.man.in (-6 / +26 lines)
Lines 169-176 Link Here
169
options is not yet supported.
169
options is not yet supported.
170
.IP "\fB\-q\fR, \fB\-\-quiet\fR" 4
170
.IP "\fB\-q\fR, \fB\-\-quiet\fR" 4
171
.IX Item "-q, --quiet"
171
.IX Item "-q, --quiet"
172
Normally, \fB@@RXVT_NAME@@d\fR outputs the message \f(CW\*(C`rxvt\-unicode daemon
172
Normally, \fB@@RXVT_NAME@@d\fR outputs the message \f(CW\*(C`@@RXVT_NAME@@d: daemon
173
listening on <path>\*(C'\fR after binding to its control socket. This option
173
listening on <path>\*(C'\fR after binding to its control socket, or the
174
message \f(CW\*(C`@@RXVT_NAME@@d: daemon using pre-opened listening fd <n>\*(C'\fR
175
if it is using an already opened socket. This option
174
will suppress this message (errors and warnings will still be logged).
176
will suppress this message (errors and warnings will still be logged).
175
.IP "\fB\-o\fR, \fB\-\-opendisplay\fR" 4
177
.IP "\fB\-o\fR, \fB\-\-opendisplay\fR" 4
176
.IX Item "-o, --opendisplay"
178
.IX Item "-o, --opendisplay"
Lines 223-234 Link Here
223
\&\fB@@RXVT_NAME@@d\fR is killed.
225
\&\fB@@RXVT_NAME@@d\fR is killed.
224
.SH "ENVIRONMENT"
226
.SH "ENVIRONMENT"
225
.IX Header "ENVIRONMENT"
227
.IX Header "ENVIRONMENT"
228
.IP "\fB\s-1LISTEN_PID\s0\fR,\fB\s-1LISTEN_FDS\s0\fR,\fB\s-1LISTEN_FDNAMES\s0\fR," 4
229
.IX Item "LISTEN_PID"
230
.IX Item "LISTEN_FDS"
231
.IX Item "LISTEN_FDNAMES"
232
@@RXVT_NAME@@d takes an already-open file descriptor for its listening
233
socket if these environment variables are set in accordance with the
234
systemd conventions (which are also employed by some other tools).  In
235
this case, it does not create a listening socket itself.
226
.IP "\fB\s-1RXVT_SOCKET\s0\fR" 4
236
.IP "\fB\s-1RXVT_SOCKET\s0\fR" 4
227
.IX Item "RXVT_SOCKET"
237
.IX Item "RXVT_SOCKET"
228
Both \fB@@RXVT_NAME@@c\fR and \fB@@RXVT_NAME@@d\fR use the environment
238
@@RXVT_NAME@@d uses the environment variable \&\fI\s-1RXVT_SOCKET\s0\fR, if
229
variable \fI\s-1RXVT_SOCKET\s0\fR to create a listening socket and to contact
239
present, to create a listening socket.  The variable must specify the
230
the @@RXVT_NAME@@d, respectively. If the variable is missing then
240
absolute path of the local-address-family socket to create.
231
\&\fI\f(CI$HOME\fI/.urxvt/urxvtd\-\fI<nodename>\fI\fR is used.
241
.IP "\fB\s-1XDG_RUNTIME_DIR\s0\fR" 4
242
.IX Item "XDG_RUNTIME_DIR"
243
If the \&\fI\s-1RXVT_SOCKET\s0\fR variable is missing, @@RXVT_NAME@@d uses the
244
environment variable \fB\s-1XDG_RUNTIME_DIR\s0\fR to create the listening
245
socket, naming it \&\fI\f(CI$XDG_RUNTIME_DIR\fI/urxvt/daemon\fR.
246
.IP "\fB\s-1HOME\s0\fR" 4
247
.IX Item "HOME"
248
If both of those environment variables are missing,
249
\&\fI\f(CI$HOME\fI/.urxvt/urxvtd\-\fI<nodename>\fI\fR is used, falling
250
back to \&\fI/tmp/.urxvt/urxvtd\-\fI<nodename>\fI\fR if even that environment
251
variable is missing.
232
.IP "\fB\s-1DISPLAY\s0\fR" 4
252
.IP "\fB\s-1DISPLAY\s0\fR" 4
233
.IX Item "DISPLAY"
253
.IX Item "DISPLAY"
234
Only used when the \f(CW\*(C`\-\-opendisplay\*(C'\fR option is specified. Must contain a
254
Only used when the \f(CW\*(C`\-\-opendisplay\*(C'\fR option is specified. Must contain a
(-)./doc/rxvtc.1.pod (-5 / +17 lines)
Lines 52-62 Link Here
52
52
53
=item B<RXVT_SOCKET>
53
=item B<RXVT_SOCKET>
54
54
55
Both @@RXVT_NAME@@c and @@RXVT_NAME@@d use the environment variable
55
@@RXVT_NAME@@c uses the environment variable F<RXVT_SOCKET> if
56
F<RXVT_SOCKET> to create a listening socket and to contact the
56
present, to contact the @@RXVT_NAME@@d.  The variable must specify the
57
@@RXVT_NAME@@d, respectively. If the variable is missing,
57
absolute path of the local-address-family socket to connect to.
58
F<<< $HOME/.urxvt/urxvtd-I<< <nodename> >> >>> is used.  The variable must
58
59
specify the absolute path of the socket to create.
59
=item B<XDG_RUNTIME_DIR>
60
61
If the F<RXVT_SOCKET> variable is missing, @@RXVT_NAME@@c uses the
62
environment variable F<XDG_RUNTIME_DIR> to contact the
63
@@RXVT_NAME@@d, connecting to the socket named
64
F<<< $XDG_RUNTIME_DIR/urxvt/daemon >>>.
65
66
=item B<HOME>
67
68
If both of those environment variables are missing,
69
F<<< $HOME/.urxvt/urxvtd-I<< <nodename> >> >>> is used, falling
70
back to F<<< /tmp/.urxvt/urxvtd-I<< <nodename> >> >>> if even that environment
71
variable is missing.
60
72
61
=back
73
=back
62
74

Return to bug 234276