xref: /netbsd-src/external/bsd/tmux/dist/server.c (revision 946379e7b37692fc43f68eb0d1c10daa0a7f3b6c)
1 /* $OpenBSD$ */
2 
3 /*
4  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15  * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <sys/types.h>
20 #include <sys/ioctl.h>
21 #include <sys/socket.h>
22 #include <sys/stat.h>
23 #include <sys/un.h>
24 #include <sys/wait.h>
25 
26 #include <errno.h>
27 #include <event.h>
28 #include <fcntl.h>
29 #include <signal.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <termios.h>
34 #include <time.h>
35 #include <unistd.h>
36 
37 #include "tmux.h"
38 
39 /*
40  * Main server functions.
41  */
42 
43 struct clients	 clients;
44 
45 int		 server_fd;
46 int		 server_shutdown;
47 struct event	 server_ev_accept;
48 
49 struct session		*marked_session;
50 struct winlink		*marked_winlink;
51 struct window		*marked_window;
52 struct window_pane	*marked_window_pane;
53 struct layout_cell	*marked_layout_cell;
54 
55 int	server_create_socket(void);
56 void	server_loop(void);
57 int	server_should_shutdown(void);
58 void	server_send_shutdown(void);
59 void	server_accept_callback(int, short, void *);
60 void	server_signal_callback(int, short, void *);
61 void	server_child_signal(void);
62 void	server_child_exited(pid_t, int);
63 void	server_child_stopped(pid_t, int);
64 
65 /* Set marked pane. */
66 void
67 server_set_marked(struct session *s, struct winlink *wl, struct window_pane *wp)
68 {
69 	marked_session = s;
70 	marked_winlink = wl;
71 	marked_window = wl->window;
72 	marked_window_pane = wp;
73 	marked_layout_cell = wp->layout_cell;
74 }
75 
76 /* Clear marked pane. */
77 void
78 server_clear_marked(void)
79 {
80 	marked_session = NULL;
81 	marked_winlink = NULL;
82 	marked_window = NULL;
83 	marked_window_pane = NULL;
84 	marked_layout_cell = NULL;
85 }
86 
87 /* Is this the marked pane? */
88 int
89 server_is_marked(struct session *s, struct winlink *wl, struct window_pane *wp)
90 {
91 	if (s == NULL || wl == NULL || wp == NULL)
92 		return (0);
93 	if (marked_session != s || marked_winlink != wl)
94 		return (0);
95 	if (marked_window_pane != wp)
96 		return (0);
97 	return (server_check_marked());
98 }
99 
100 /* Check if the marked pane is still valid. */
101 int
102 server_check_marked(void)
103 {
104 	struct winlink	*wl;
105 
106 	if (marked_window_pane == NULL)
107 		return (0);
108 	if (marked_layout_cell != marked_window_pane->layout_cell)
109 		return (0);
110 
111 	if (!session_alive(marked_session))
112 		return (0);
113 	RB_FOREACH(wl, winlinks, &marked_session->windows) {
114 		if (wl->window == marked_window && wl == marked_winlink)
115 			break;
116 	}
117 	if (wl == NULL)
118 		return (0);
119 
120 	if (!window_has_pane(marked_window, marked_window_pane))
121 		return (0);
122 	return (window_pane_visible(marked_window_pane));
123 }
124 
125 /* Create server socket. */
126 int
127 server_create_socket(void)
128 {
129 	struct sockaddr_un	sa;
130 	size_t			size;
131 	mode_t			mask;
132 	int			fd;
133 
134 	memset(&sa, 0, sizeof sa);
135 	sa.sun_family = AF_UNIX;
136 	size = strlcpy(sa.sun_path, socket_path, sizeof sa.sun_path);
137 	if (size >= sizeof sa.sun_path) {
138 		errno = ENAMETOOLONG;
139 		return (-1);
140 	}
141 	unlink(sa.sun_path);
142 
143 	if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
144 		return (-1);
145 
146 	mask = umask(S_IXUSR|S_IXGRP|S_IRWXO);
147 	if (bind(fd, (struct sockaddr *) &sa, sizeof(sa)) == -1)
148 		return (-1);
149 	umask(mask);
150 
151 	if (listen(fd, 16) == -1)
152 		return (-1);
153 	setblocking(fd, 0);
154 
155 	return (fd);
156 }
157 
158 /* Fork new server. */
159 int
160 server_start(struct event_base *base, int lockfd, char *lockfile)
161 {
162 	int	pair[2];
163 
164 	/* The first client is special and gets a socketpair; create it. */
165 	if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pair) != 0)
166 		fatal("socketpair failed");
167 	log_debug("starting server");
168 
169 	switch (fork()) {
170 	case -1:
171 		fatal("fork failed");
172 	case 0:
173 		break;
174 	default:
175 		close(pair[1]);
176 		return (pair[0]);
177 	}
178 	close(pair[0]);
179 
180 	/*
181 	 * Must daemonise before loading configuration as the PID changes so
182 	 * $TMUX would be wrong for sessions created in the config file.
183 	 */
184 	if (daemon(1, 0) != 0)
185 		fatal("daemon failed");
186 
187 	/* event_init() was called in our parent, need to reinit. */
188 	clear_signals(0);
189 	if (event_reinit(base) != 0)
190 		fatal("event_reinit failed");
191 
192 	logfile("server");
193 	log_debug("server started, pid %ld", (long) getpid());
194 
195 	RB_INIT(&windows);
196 	RB_INIT(&all_window_panes);
197 	TAILQ_INIT(&clients);
198 	RB_INIT(&sessions);
199 	TAILQ_INIT(&session_groups);
200 	mode_key_init_trees();
201 	key_bindings_init();
202 	utf8_build();
203 
204 	start_time = time(NULL);
205 	log_debug("socket path %s", socket_path);
206 #ifdef HAVE_SETPROCTITLE
207 	setproctitle("server (%s)", socket_path);
208 #endif
209 
210 	server_fd = server_create_socket();
211 	if (server_fd == -1)
212 		fatal("couldn't create socket");
213 	server_update_socket();
214 	server_client_create(pair[1]);
215 
216 	unlink(lockfile);
217 	free(lockfile);
218 	close(lockfd);
219 
220 	start_cfg();
221 
222 	status_prompt_load_history();
223 
224 	server_add_accept(0);
225 
226 	set_signals(server_signal_callback);
227 	server_loop();
228 	status_prompt_save_history();
229 	exit(0);
230 }
231 
232 /* Main server loop. */
233 void
234 server_loop(void)
235 {
236 	while (!server_should_shutdown()) {
237 		log_debug("event dispatch enter");
238 		event_loop(EVLOOP_ONCE);
239 		log_debug("event dispatch exit");
240 
241 		server_client_loop();
242 	}
243 }
244 
245 /* Check if the server should exit (no more clients or sessions). */
246 int
247 server_should_shutdown(void)
248 {
249 	struct client	*c;
250 
251 	if (!options_get_number(&global_options, "exit-unattached")) {
252 		if (!RB_EMPTY(&sessions))
253 			return (0);
254 	}
255 
256 	TAILQ_FOREACH(c, &clients, entry) {
257 		if (c->session != NULL)
258 			return (0);
259 	}
260 
261 	/*
262 	 * No attached clients therefore want to exit - flush any waiting
263 	 * clients but don't actually exit until they've gone.
264 	 */
265 	cmd_wait_for_flush();
266 	if (!TAILQ_EMPTY(&clients))
267 		return (0);
268 
269 	return (1);
270 }
271 
272 /* Shutdown the server by killing all clients and windows. */
273 void
274 server_send_shutdown(void)
275 {
276 	struct client	*c, *c1;
277 	struct session	*s, *s1;
278 
279 	cmd_wait_for_flush();
280 
281 	TAILQ_FOREACH_SAFE(c, &clients, entry, c1) {
282 		if (c->flags & (CLIENT_BAD|CLIENT_SUSPENDED))
283 			server_client_lost(c);
284 		else
285 			server_write_client(c, MSG_SHUTDOWN, NULL, 0);
286 		c->session = NULL;
287 	}
288 
289 	RB_FOREACH_SAFE(s, sessions, &sessions, s1)
290 		session_destroy(s);
291 }
292 
293 /* Update socket execute permissions based on whether sessions are attached. */
294 void
295 server_update_socket(void)
296 {
297 	struct session	*s;
298 	static int	 last = -1;
299 	int		 n, mode;
300 	struct stat      sb;
301 
302 	n = 0;
303 	RB_FOREACH(s, sessions, &sessions) {
304 		if (!(s->flags & SESSION_UNATTACHED)) {
305 			n++;
306 			break;
307 		}
308 	}
309 
310 	if (n != last) {
311 		last = n;
312 
313 		if (stat(socket_path, &sb) != 0)
314 			return;
315 		mode = sb.st_mode;
316 		if (n != 0) {
317 			if (mode & S_IRUSR)
318 				mode |= S_IXUSR;
319 			if (mode & S_IRGRP)
320 				mode |= S_IXGRP;
321 			if (mode & S_IROTH)
322 				mode |= S_IXOTH;
323 		} else
324 			mode &= ~(S_IXUSR|S_IXGRP|S_IXOTH);
325 		chmod(socket_path, mode);
326 	}
327 }
328 
329 /* Callback for server socket. */
330 void
331 server_accept_callback(int fd, short events, unused void *data)
332 {
333 	struct sockaddr_storage	sa;
334 	socklen_t		slen = sizeof sa;
335 	int			newfd;
336 
337 	server_add_accept(0);
338 	if (!(events & EV_READ))
339 		return;
340 
341 	newfd = accept(fd, (struct sockaddr *) &sa, &slen);
342 	if (newfd == -1) {
343 		if (errno == EAGAIN || errno == EINTR || errno == ECONNABORTED)
344 			return;
345 		if (errno == ENFILE || errno == EMFILE) {
346 			/* Delete and don't try again for 1 second. */
347 			server_add_accept(1);
348 			return;
349 		}
350 		fatal("accept failed");
351 	}
352 	if (server_shutdown) {
353 		close(newfd);
354 		return;
355 	}
356 	server_client_create(newfd);
357 }
358 
359 /*
360  * Add accept event. If timeout is nonzero, add as a timeout instead of a read
361  * event - used to backoff when running out of file descriptors.
362  */
363 void
364 server_add_accept(int timeout)
365 {
366 	struct timeval tv = { timeout, 0 };
367 
368 	if (event_initialized(&server_ev_accept))
369 		event_del(&server_ev_accept);
370 
371 	if (timeout == 0) {
372 		event_set(&server_ev_accept,
373 		    server_fd, EV_READ, server_accept_callback, NULL);
374 		event_add(&server_ev_accept, NULL);
375 	} else {
376 		event_set(&server_ev_accept,
377 		    server_fd, EV_TIMEOUT, server_accept_callback, NULL);
378 		event_add(&server_ev_accept, &tv);
379 	}
380 }
381 
382 /* Signal handler. */
383 void
384 server_signal_callback(int sig, unused short events, unused void *data)
385 {
386 	int	fd;
387 
388 	switch (sig) {
389 	case SIGTERM:
390 		server_shutdown = 1;
391 		server_send_shutdown();
392 		break;
393 	case SIGCHLD:
394 		server_child_signal();
395 		break;
396 	case SIGUSR1:
397 		event_del(&server_ev_accept);
398 		fd = server_create_socket();
399 		if (fd != -1) {
400 			close(server_fd);
401 			server_fd = fd;
402 			server_update_socket();
403 		}
404 		server_add_accept(0);
405 		break;
406 	}
407 }
408 
409 /* Handle SIGCHLD. */
410 void
411 server_child_signal(void)
412 {
413 	int	 status;
414 	pid_t	 pid;
415 
416 	for (;;) {
417 		switch (pid = waitpid(WAIT_ANY, &status, WNOHANG|WUNTRACED)) {
418 		case -1:
419 			if (errno == ECHILD)
420 				return;
421 			fatal("waitpid failed");
422 		case 0:
423 			return;
424 		}
425 		if (WIFSTOPPED(status))
426 			server_child_stopped(pid, status);
427 		else if (WIFEXITED(status) || WIFSIGNALED(status))
428 			server_child_exited(pid, status);
429 	}
430 }
431 
432 /* Handle exited children. */
433 void
434 server_child_exited(pid_t pid, int status)
435 {
436 	struct window		*w, *w1;
437 	struct window_pane	*wp;
438 	struct job		*job;
439 
440 	RB_FOREACH_SAFE(w, windows, &windows, w1) {
441 		TAILQ_FOREACH(wp, &w->panes, entry) {
442 			if (wp->pid == pid) {
443 				wp->status = status;
444 				server_destroy_pane(wp);
445 				break;
446 			}
447 		}
448 	}
449 
450 	LIST_FOREACH(job, &all_jobs, lentry) {
451 		if (pid == job->pid) {
452 			job_died(job, status);	/* might free job */
453 			break;
454 		}
455 	}
456 }
457 
458 /* Handle stopped children. */
459 void
460 server_child_stopped(pid_t pid, int status)
461 {
462 	struct window		*w;
463 	struct window_pane	*wp;
464 
465 	if (WSTOPSIG(status) == SIGTTIN || WSTOPSIG(status) == SIGTTOU)
466 		return;
467 
468 	RB_FOREACH(w, windows, &windows) {
469 		TAILQ_FOREACH(wp, &w->panes, entry) {
470 			if (wp->pid == pid) {
471 				if (killpg(pid, SIGCONT) != 0)
472 					kill(pid, SIGCONT);
473 			}
474 		}
475 	}
476 }
477