xref: /minix3/external/bsd/tmux/dist/server.c (revision b80da2a01d0bb632707b7b4e974aa32eaebbcc6f)
1 /* $Id: server.c,v 1.1.1.2 2011/08/17 18:40:05 jmmv Exp $ */
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 <syslog.h>
34 #include <termios.h>
35 #include <time.h>
36 #include <unistd.h>
37 
38 #include "tmux.h"
39 
40 /*
41  * Main server functions.
42  */
43 
44 /* Client list. */
45 struct clients	 clients;
46 struct clients	 dead_clients;
47 
48 int		 server_fd;
49 int		 server_shutdown;
50 struct event	 server_ev_accept;
51 struct event	 server_ev_second;
52 
53 struct paste_stack global_buffers;
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_clean_dead(void);
60 void		 server_accept_callback(int, short, void *);
61 void		 server_signal_callback(int, short, void *);
62 void		 server_child_signal(void);
63 void		 server_child_exited(pid_t, int);
64 void		 server_child_stopped(pid_t, int);
65 void		 server_second_callback(int, short, void *);
66 void		 server_lock_server(void);
67 void		 server_lock_sessions(void);
68 
69 /* Create server socket. */
70 int
71 server_create_socket(void)
72 {
73 	struct sockaddr_un	sa;
74 	size_t			size;
75 	mode_t			mask;
76 	int			fd;
77 
78 	memset(&sa, 0, sizeof sa);
79 	sa.sun_family = AF_UNIX;
80 	size = strlcpy(sa.sun_path, socket_path, sizeof sa.sun_path);
81 	if (size >= sizeof sa.sun_path) {
82 		errno = ENAMETOOLONG;
83 		fatal("socket failed");
84 	}
85 	unlink(sa.sun_path);
86 
87 #ifndef __minix
88 	if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
89 #else
90 	if ((fd = socket(AF_UNIX, SOCK_SEQPACKET, 0)) == -1)
91 #endif
92 		fatal("socket failed");
93 
94 	mask = umask(S_IXUSR|S_IXGRP|S_IRWXO);
95 	if (bind(fd, (struct sockaddr *) &sa, SUN_LEN(&sa)) == -1)
96 		fatal("bind failed");
97 	umask(mask);
98 
99 	if (listen(fd, 16) == -1)
100 		fatal("listen failed");
101 	setblocking(fd, 0);
102 
103 	server_update_socket();
104 
105 	return (fd);
106 }
107 
108 /* Fork new server. */
109 int
110 server_start(void)
111 {
112 	struct window_pane	*wp;
113 	int	 		 pair[2];
114 	char			*cause;
115 	struct timeval		 tv;
116 	u_int			 i;
117 
118 	/* The first client is special and gets a socketpair; create it. */
119 #ifndef __minix
120 	if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pair) != 0)
121 #else
122 	if (socketpair(AF_UNIX, SOCK_SEQPACKET, PF_UNSPEC, pair) != 0)
123 #endif
124 		fatal("socketpair failed");
125 
126 	switch (fork()) {
127 	case -1:
128 		fatal("fork failed");
129 	case 0:
130 		break;
131 	default:
132 		close(pair[1]);
133 		return (pair[0]);
134 	}
135 	close(pair[0]);
136 
137 	/*
138 	 * Must daemonise before loading configuration as the PID changes so
139 	 * $TMUX would be wrong for sessions created in the config file.
140 	 */
141 	if (daemon(1, 0) != 0)
142 		fatal("daemon failed");
143 
144 	/* event_init() was called in our parent, need to reinit. */
145 	if (event_reinit(ev_base) != 0)
146 		fatal("event_reinit failed");
147 	clear_signals(0);
148 
149 	logfile("server");
150 	log_debug("server started, pid %ld", (long) getpid());
151 
152 	ARRAY_INIT(&windows);
153 	RB_INIT(&all_window_panes);
154 	ARRAY_INIT(&clients);
155 	ARRAY_INIT(&dead_clients);
156 	RB_INIT(&sessions);
157 	RB_INIT(&dead_sessions);
158 	TAILQ_INIT(&session_groups);
159 	ARRAY_INIT(&global_buffers);
160 	mode_key_init_trees();
161 	key_bindings_init();
162 	utf8_build();
163 
164 	start_time = time(NULL);
165 	log_debug("socket path %s", socket_path);
166 #ifdef HAVE_SETPROCTITLE
167 	setproctitle("server (%s)", socket_path);
168 #endif
169 
170 	server_fd = server_create_socket();
171 	server_client_create(pair[1]);
172 
173 	if (access(SYSTEM_CFG, R_OK) == 0)
174 		load_cfg(SYSTEM_CFG, NULL, &cfg_causes);
175 	else if (errno != ENOENT) {
176 		cfg_add_cause(
177 		    &cfg_causes, "%s: %s", strerror(errno), SYSTEM_CFG);
178 	}
179 	if (cfg_file != NULL)
180 		load_cfg(cfg_file, NULL, &cfg_causes);
181 
182 	/*
183 	 * If there is a session already, put the current window and pane into
184 	 * more mode.
185 	 */
186 	if (!RB_EMPTY(&sessions) && !ARRAY_EMPTY(&cfg_causes)) {
187 		wp = RB_MIN(sessions, &sessions)->curw->window->active;
188 		window_pane_set_mode(wp, &window_copy_mode);
189 		window_copy_init_for_output(wp);
190 		for (i = 0; i < ARRAY_LENGTH(&cfg_causes); i++) {
191 			cause = ARRAY_ITEM(&cfg_causes, i);
192 			window_copy_add(wp, "%s", cause);
193 			xfree(cause);
194 		}
195 		ARRAY_FREE(&cfg_causes);
196 	}
197 	cfg_finished = 1;
198 
199 	event_set(&server_ev_accept,
200 	    server_fd, EV_READ|EV_PERSIST, server_accept_callback, NULL);
201 	event_add(&server_ev_accept, NULL);
202 
203 	memset(&tv, 0, sizeof tv);
204 	tv.tv_sec = 1;
205 	evtimer_set(&server_ev_second, server_second_callback, NULL);
206 	evtimer_add(&server_ev_second, &tv);
207 
208 	set_signals(server_signal_callback);
209 	server_loop();
210 	exit(0);
211 }
212 
213 /* Main server loop. */
214 void
215 server_loop(void)
216 {
217 	while (!server_should_shutdown()) {
218 		event_loop(EVLOOP_ONCE);
219 
220 		server_window_loop();
221 		server_client_loop();
222 
223 		key_bindings_clean();
224 		server_clean_dead();
225 	}
226 }
227 
228 /* Check if the server should be shutting down (no more clients or sessions). */
229 int
230 server_should_shutdown(void)
231 {
232 	u_int	i;
233 
234 	if (!options_get_number(&global_options, "exit-unattached")) {
235 		if (!RB_EMPTY(&sessions))
236 			return (0);
237 	}
238 	for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
239 		if (ARRAY_ITEM(&clients, i) != NULL)
240 			return (0);
241 	}
242 	return (1);
243 }
244 
245 /* Shutdown the server by killing all clients and windows. */
246 void
247 server_send_shutdown(void)
248 {
249 	struct client	*c;
250 	struct session	*s, *next_s;
251 	u_int		 i;
252 
253 	for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
254 		c = ARRAY_ITEM(&clients, i);
255 		if (c != NULL) {
256 			if (c->flags & (CLIENT_BAD|CLIENT_SUSPENDED))
257 				server_client_lost(c);
258 			else
259 				server_write_client(c, MSG_SHUTDOWN, NULL, 0);
260 			c->session = NULL;
261 		}
262 	}
263 
264 	s = RB_MIN(sessions, &sessions);
265 	while (s != NULL) {
266 		next_s = RB_NEXT(sessions, &sessions, s);
267 		session_destroy(s);
268 		s = next_s;
269 	}
270 }
271 
272 /* Free dead, unreferenced clients and sessions. */
273 void
274 server_clean_dead(void)
275 {
276 	struct session	*s, *next_s;
277 	struct client	*c;
278 	u_int		 i;
279 
280 	s = RB_MIN(sessions, &dead_sessions);
281 	while (s != NULL) {
282 		next_s = RB_NEXT(sessions, &dead_sessions, s);
283 		if (s->references == 0) {
284 			RB_REMOVE(sessions, &dead_sessions, s);
285 			xfree(s->name);
286 			xfree(s);
287 		}
288 		s = next_s;
289 	}
290 
291 	for (i = 0; i < ARRAY_LENGTH(&dead_clients); i++) {
292 		c = ARRAY_ITEM(&dead_clients, i);
293 		if (c == NULL || c->references != 0)
294 			continue;
295 		ARRAY_SET(&dead_clients, i, NULL);
296 		xfree(c);
297 	}
298 }
299 
300 /* Update socket execute permissions based on whether sessions are attached. */
301 void
302 server_update_socket(void)
303 {
304 	struct session	*s;
305 	static int	 last = -1;
306 	int		 n, mode;
307 	struct stat      sb;
308 
309 	n = 0;
310 	RB_FOREACH(s, sessions, &sessions) {
311 		if (!(s->flags & SESSION_UNATTACHED)) {
312 			n++;
313 			break;
314 		}
315 	}
316 
317 	if (n != last) {
318 		last = n;
319 
320 		if (stat(socket_path, &sb) != 0)
321 			return;
322 		mode = sb.st_mode;
323 		if (n != 0) {
324 			if (mode & S_IRUSR)
325 				mode |= S_IXUSR;
326 			if (mode & S_IRGRP)
327 				mode |= S_IXGRP;
328 			if (mode & S_IROTH)
329 				mode |= S_IXOTH;
330 		} else
331 			mode &= ~(S_IXUSR|S_IXGRP|S_IXOTH);
332 		chmod(socket_path, mode);
333 	}
334 }
335 
336 /* Callback for server socket. */
337 /* ARGSUSED */
338 void
339 server_accept_callback(int fd, short events, unused void *data)
340 {
341 	struct sockaddr_storage	sa;
342 	socklen_t		slen = sizeof sa;
343 	int			newfd;
344 
345 	if (!(events & EV_READ))
346 		return;
347 
348 	newfd = accept(fd, (struct sockaddr *) &sa, &slen);
349 	if (newfd == -1) {
350 		if (errno == EAGAIN || errno == EINTR || errno == ECONNABORTED)
351 			return;
352 		fatal("accept failed");
353 	}
354 	if (server_shutdown) {
355 		close(newfd);
356 		return;
357 	}
358 	server_client_create(newfd);
359 }
360 
361 /* Signal handler. */
362 /* ARGSUSED */
363 void
364 server_signal_callback(int sig, unused short events, unused void *data)
365 {
366 	switch (sig) {
367 	case SIGTERM:
368 		server_shutdown = 1;
369 		server_send_shutdown();
370 		break;
371 	case SIGCHLD:
372 		server_child_signal();
373 		break;
374 	case SIGUSR1:
375 		event_del(&server_ev_accept);
376 		close(server_fd);
377 		server_fd = server_create_socket();
378 		event_set(&server_ev_accept, server_fd,
379 		    EV_READ|EV_PERSIST, server_accept_callback, NULL);
380 		event_add(&server_ev_accept, NULL);
381 		break;
382 	}
383 }
384 
385 /* Handle SIGCHLD. */
386 void
387 server_child_signal(void)
388 {
389 	int	 status;
390 	pid_t	 pid;
391 
392 	for (;;) {
393 		switch (pid = waitpid(WAIT_ANY, &status, WNOHANG|WUNTRACED)) {
394 		case -1:
395 			if (errno == ECHILD)
396 				return;
397 			fatal("waitpid failed");
398 		case 0:
399 			return;
400 		}
401 		if (WIFSTOPPED(status))
402 			server_child_stopped(pid, status);
403 		else if (WIFEXITED(status) || WIFSIGNALED(status))
404 			server_child_exited(pid, status);
405 	}
406 }
407 
408 /* Handle exited children. */
409 void
410 server_child_exited(pid_t pid, int status)
411 {
412 	struct window		*w;
413 	struct window_pane	*wp;
414 	struct job		*job;
415 	u_int		 	 i;
416 
417 	for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
418 		if ((w = ARRAY_ITEM(&windows, i)) == NULL)
419 			continue;
420 		TAILQ_FOREACH(wp, &w->panes, entry) {
421 			if (wp->pid == pid) {
422 				server_destroy_pane(wp);
423 				break;
424 			}
425 		}
426 	}
427 
428 	LIST_FOREACH(job, &all_jobs, lentry) {
429 		if (pid == job->pid) {
430 			job_died(job, status);	/* might free job */
431 			break;
432 		}
433 	}
434 }
435 
436 /* Handle stopped children. */
437 void
438 server_child_stopped(pid_t pid, int status)
439 {
440 	struct window		*w;
441 	struct window_pane	*wp;
442 	u_int			 i;
443 
444 	if (WSTOPSIG(status) == SIGTTIN || WSTOPSIG(status) == SIGTTOU)
445 		return;
446 
447 	for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
448 		if ((w = ARRAY_ITEM(&windows, i)) == NULL)
449 			continue;
450 		TAILQ_FOREACH(wp, &w->panes, entry) {
451 			if (wp->pid == pid) {
452 				if (killpg(pid, SIGCONT) != 0)
453 					kill(pid, SIGCONT);
454 			}
455 		}
456 	}
457 }
458 
459 /* Handle once-per-second timer events. */
460 /* ARGSUSED */
461 void
462 server_second_callback(unused int fd, unused short events, unused void *arg)
463 {
464 	struct window		*w;
465 	struct window_pane	*wp;
466 	struct timeval		 tv;
467 	u_int		 	 i;
468 
469 	if (options_get_number(&global_s_options, "lock-server"))
470 		server_lock_server();
471 	else
472 		server_lock_sessions();
473 
474 	for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
475 		w = ARRAY_ITEM(&windows, i);
476 		if (w == NULL)
477 			continue;
478 
479 		TAILQ_FOREACH(wp, &w->panes, entry) {
480 			if (wp->mode != NULL && wp->mode->timer != NULL)
481 				wp->mode->timer(wp);
482 		}
483 	}
484 
485 	server_client_status_timer();
486 
487 	evtimer_del(&server_ev_second);
488 	memset(&tv, 0, sizeof tv);
489 	tv.tv_sec = 1;
490 	evtimer_add(&server_ev_second, &tv);
491 }
492 
493 /* Lock the server if ALL sessions have hit the time limit. */
494 void
495 server_lock_server(void)
496 {
497 	struct session  *s;
498 	int		 timeout;
499 	time_t           t;
500 
501 	t = time(NULL);
502 	RB_FOREACH(s, sessions, &sessions) {
503 		if (s->flags & SESSION_UNATTACHED)
504 			continue;
505 		timeout = options_get_number(&s->options, "lock-after-time");
506 		if (timeout <= 0 || t <= s->activity_time.tv_sec + timeout)
507 			return;	/* not timed out */
508 	}
509 
510 	server_lock();
511 	recalculate_sizes();
512 }
513 
514 /* Lock any sessions which have timed out. */
515 void
516 server_lock_sessions(void)
517 {
518 	struct session  *s;
519 	int		 timeout;
520 	time_t		 t;
521 
522 	t = time(NULL);
523 	RB_FOREACH(s, sessions, &sessions) {
524 		if (s->flags & SESSION_UNATTACHED)
525 			continue;
526 		timeout = options_get_number(&s->options, "lock-after-time");
527 		if (timeout > 0 && t > s->activity_time.tv_sec + timeout) {
528 			server_lock_session(s);
529 			recalculate_sizes();
530 		}
531 	}
532 }
533