Home | History | Annotate | Line # | Download | only in dist
      1 /* $OpenBSD$ */
      2 
      3 /*
      4  * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott (at) gmail.com>
      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 <fcntl.h>
     28 #include <signal.h>
     29 #include <stdio.h>
     30 #include <stdlib.h>
     31 #include <string.h>
     32 #include <termios.h>
     33 #include <time.h>
     34 #include <unistd.h>
     35 
     36 #include "tmux.h"
     37 
     38 /*
     39  * Main server functions.
     40  */
     41 
     42 struct clients		 clients;
     43 
     44 struct tmuxproc		*server_proc;
     45 static int		 server_fd = -1;
     46 static uint64_t		 server_client_flags;
     47 static int		 server_exit;
     48 static struct event	 server_ev_accept;
     49 static struct event	 server_ev_tidy;
     50 
     51 struct cmd_find_state	 marked_pane;
     52 
     53 static u_int		 message_next;
     54 struct message_list	 message_log;
     55 
     56 time_t			 current_time;
     57 
     58 static int	server_loop(void);
     59 static void	server_send_exit(void);
     60 static void	server_accept(int, short, void *);
     61 static void	server_signal(int);
     62 static void	server_child_signal(void);
     63 static void	server_child_exited(pid_t, int);
     64 static void	server_child_stopped(pid_t, int);
     65 
     66 /* Set marked pane. */
     67 void
     68 server_set_marked(struct session *s, struct winlink *wl, struct window_pane *wp)
     69 {
     70 	cmd_find_clear_state(&marked_pane, 0);
     71 	marked_pane.s = s;
     72 	marked_pane.wl = wl;
     73 	if (wl != NULL)
     74 		marked_pane.w = wl->window;
     75 	marked_pane.wp = wp;
     76 }
     77 
     78 /* Clear marked pane. */
     79 void
     80 server_clear_marked(void)
     81 {
     82 	cmd_find_clear_state(&marked_pane, 0);
     83 }
     84 
     85 /* Is this the marked pane? */
     86 int
     87 server_is_marked(struct session *s, struct winlink *wl, struct window_pane *wp)
     88 {
     89 	if (s == NULL || wl == NULL || wp == NULL)
     90 		return (0);
     91 	if (marked_pane.s != s || marked_pane.wl != wl)
     92 		return (0);
     93 	if (marked_pane.wp != wp)
     94 		return (0);
     95 	return (server_check_marked());
     96 }
     97 
     98 /* Check if the marked pane is still valid. */
     99 int
    100 server_check_marked(void)
    101 {
    102 	return (cmd_find_valid_state(&marked_pane));
    103 }
    104 
    105 /* Create server socket. */
    106 int
    107 server_create_socket(uint64_t flags, char **cause)
    108 {
    109 	struct sockaddr_un	sa;
    110 	size_t			size;
    111 	mode_t			mask;
    112 	int			fd, saved_errno;
    113 
    114 	memset(&sa, 0, sizeof sa);
    115 	sa.sun_family = AF_UNIX;
    116 	size = strlcpy(sa.sun_path, socket_path, sizeof sa.sun_path);
    117 	if (size >= sizeof sa.sun_path) {
    118 		errno = ENAMETOOLONG;
    119 		goto fail;
    120 	}
    121 	unlink(sa.sun_path);
    122 
    123 	if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
    124 		goto fail;
    125 
    126 	if (flags & CLIENT_DEFAULTSOCKET)
    127 		mask = umask(S_IXUSR|S_IXGRP|S_IRWXO);
    128 	else
    129 		mask = umask(S_IXUSR|S_IRWXG|S_IRWXO);
    130 	if (bind(fd, (struct sockaddr *)&sa, sizeof sa) == -1) {
    131 		saved_errno = errno;
    132 		close(fd);
    133 		errno = saved_errno;
    134 		goto fail;
    135 	}
    136 	umask(mask);
    137 
    138 	if (listen(fd, 128) == -1) {
    139 		saved_errno = errno;
    140 		close(fd);
    141 		errno = saved_errno;
    142 		goto fail;
    143 	}
    144 	setblocking(fd, 0);
    145 
    146 	return (fd);
    147 
    148 fail:
    149 	if (cause != NULL) {
    150 		xasprintf(cause, "error creating %s (%s)", socket_path,
    151 		    strerror(errno));
    152 	}
    153 	return (-1);
    154 }
    155 
    156 /* Tidy up every hour. */
    157 static void
    158 server_tidy_event(__unused int fd, __unused short events, __unused void *data)
    159 {
    160     struct timeval	tv = { .tv_sec = 3600 };
    161     uint64_t		t = get_timer();
    162 
    163     format_tidy_jobs();
    164 
    165 #ifdef HAVE_MALLOC_TRIM
    166     malloc_trim(0);
    167 #endif
    168 
    169     log_debug("%s: took %ju milliseconds", __func__, (uintmax_t)get_timer() - t);
    170     evtimer_add(&server_ev_tidy, &tv);
    171 }
    172 
    173 /* Fork new server. */
    174 int
    175 server_start(struct tmuxproc *client, uint64_t flags, struct event_base *base,
    176     int lockfd, char *lockfile)
    177 {
    178 	int		 fd;
    179 	sigset_t	 set, oldset;
    180 	struct client	*c = NULL;
    181 	char		*cause = NULL;
    182 	struct timeval	 tv = { .tv_sec = 3600 };
    183 
    184 	sigfillset(&set);
    185 	sigprocmask(SIG_BLOCK, &set, &oldset);
    186 
    187 	if (~flags & CLIENT_NOFORK) {
    188 		if (proc_fork_and_daemon(&fd) != 0) {
    189 			sigprocmask(SIG_SETMASK, &oldset, NULL);
    190 			return (fd);
    191 		}
    192 	}
    193 	proc_clear_signals(client, 0);
    194 	server_client_flags = flags;
    195 
    196 	if (event_reinit(base) != 0)
    197 		fatalx("event_reinit failed");
    198 	server_proc = proc_start("server");
    199 
    200 	proc_set_signals(server_proc, server_signal);
    201 	sigprocmask(SIG_SETMASK, &oldset, NULL);
    202 
    203 	if (log_get_level() > 1)
    204 		tty_create_log();
    205 	if (pledge("stdio rpath wpath cpath fattr unix getpw recvfd proc exec "
    206 	    "tty ps", NULL) != 0)
    207 		fatal("pledge failed");
    208 
    209 	input_key_build();
    210 	utf8_update_width_cache();
    211 	RB_INIT(&windows);
    212 	RB_INIT(&all_window_panes);
    213 	TAILQ_INIT(&clients);
    214 	RB_INIT(&sessions);
    215 	key_bindings_init();
    216 	TAILQ_INIT(&message_log);
    217 	gettimeofday(&start_time, NULL);
    218 
    219 #ifdef HAVE_SYSTEMD
    220 	server_fd = systemd_create_socket(flags, &cause);
    221 #else
    222 	server_fd = server_create_socket(flags, &cause);
    223 #endif
    224 	if (server_fd != -1)
    225 		server_update_socket();
    226 	if (~flags & CLIENT_NOFORK)
    227 		c = server_client_create(fd);
    228 	else
    229 		options_set_number(global_options, "exit-empty", 0);
    230 
    231 	if (lockfd >= 0) {
    232 		unlink(lockfile);
    233 		free(lockfile);
    234 		close(lockfd);
    235 	}
    236 
    237 	if (cause != NULL) {
    238 		if (c != NULL) {
    239 			c->exit_message = cause;
    240 			c->flags |= CLIENT_EXIT;
    241 		} else {
    242 			fprintf(stderr, "%s\n", cause);
    243 			exit(1);
    244 		}
    245 	}
    246 
    247 	evtimer_set(&server_ev_tidy, server_tidy_event, NULL);
    248 	evtimer_add(&server_ev_tidy, &tv);
    249 
    250 	server_acl_init();
    251 
    252 	server_add_accept(0);
    253 	proc_loop(server_proc, server_loop);
    254 
    255 	job_kill_all();
    256 	status_prompt_save_history();
    257 
    258 	exit(0);
    259 }
    260 
    261 /* Server loop callback. */
    262 static int
    263 server_loop(void)
    264 {
    265 	struct client	*c;
    266 	u_int		 items;
    267 
    268 	current_time = time(NULL);
    269 
    270 	do {
    271 		items = cmdq_next(NULL);
    272 		TAILQ_FOREACH(c, &clients, entry) {
    273 			if (c->flags & CLIENT_IDENTIFIED)
    274 				items += cmdq_next(c);
    275 		}
    276 	} while (items != 0);
    277 
    278 	server_client_loop();
    279 
    280 	if (!options_get_number(global_options, "exit-empty") && !server_exit)
    281 		return (0);
    282 
    283 	if (!options_get_number(global_options, "exit-unattached")) {
    284 		if (!RB_EMPTY(&sessions))
    285 			return (0);
    286 	}
    287 
    288 	TAILQ_FOREACH(c, &clients, entry) {
    289 		if (c->session != NULL)
    290 			return (0);
    291 	}
    292 
    293 	/*
    294 	 * No attached clients therefore want to exit - flush any waiting
    295 	 * clients but don't actually exit until they've gone.
    296 	 */
    297 	cmd_wait_for_flush();
    298 	if (!TAILQ_EMPTY(&clients))
    299 		return (0);
    300 
    301 	if (job_still_running())
    302 		return (0);
    303 
    304 	return (1);
    305 }
    306 
    307 /* Exit the server by killing all clients and windows. */
    308 static void
    309 server_send_exit(void)
    310 {
    311 	struct client	*c, *c1;
    312 	struct session	*s, *s1;
    313 
    314 	cmd_wait_for_flush();
    315 
    316 	TAILQ_FOREACH_SAFE(c, &clients, entry, c1) {
    317 		if (c->flags & CLIENT_SUSPENDED)
    318 			server_client_lost(c);
    319 		else {
    320 			c->flags |= CLIENT_EXIT;
    321 			c->exit_type = CLIENT_EXIT_SHUTDOWN;
    322 		}
    323 		c->session = NULL;
    324 	}
    325 
    326 	RB_FOREACH_SAFE(s, sessions, &sessions, s1)
    327 		session_destroy(s, 1, __func__);
    328 }
    329 
    330 /* Update socket execute permissions based on whether sessions are attached. */
    331 void
    332 server_update_socket(void)
    333 {
    334 	struct session	*s;
    335 	static int	 last = -1;
    336 	int		 n, mode;
    337 	struct stat      sb;
    338 
    339 	n = 0;
    340 	RB_FOREACH(s, sessions, &sessions) {
    341 		if (s->attached != 0) {
    342 			n++;
    343 			break;
    344 		}
    345 	}
    346 
    347 	if (n != last) {
    348 		last = n;
    349 
    350 		if (stat(socket_path, &sb) != 0)
    351 			return;
    352 		mode = sb.st_mode & ACCESSPERMS;
    353 		if (n != 0) {
    354 			if (mode & S_IRUSR)
    355 				mode |= S_IXUSR;
    356 			if (mode & S_IRGRP)
    357 				mode |= S_IXGRP;
    358 			if (mode & S_IROTH)
    359 				mode |= S_IXOTH;
    360 		} else
    361 			mode &= ~(S_IXUSR|S_IXGRP|S_IXOTH);
    362 		chmod(socket_path, mode);
    363 	}
    364 }
    365 
    366 /* Callback for server socket. */
    367 static void
    368 server_accept(int fd, short events, __unused void *data)
    369 {
    370 	struct sockaddr_storage	 sa;
    371 	socklen_t		 slen = sizeof sa;
    372 	int			 newfd;
    373 	struct client		*c;
    374 
    375 	server_add_accept(0);
    376 	if (!(events & EV_READ))
    377 		return;
    378 
    379 	newfd = accept(fd, (struct sockaddr *) &sa, &slen);
    380 	if (newfd == -1) {
    381 		if (errno == EAGAIN || errno == EINTR || errno == ECONNABORTED)
    382 			return;
    383 		if (errno == ENFILE || errno == EMFILE) {
    384 			/* Delete and don't try again for 1 second. */
    385 			server_add_accept(1);
    386 			return;
    387 		}
    388 		fatal("accept failed");
    389 	}
    390 
    391 	if (server_exit) {
    392 		close(newfd);
    393 		return;
    394 	}
    395 	c = server_client_create(newfd);
    396 	if (!server_acl_join(c)) {
    397 		c->exit_message = xstrdup("access not allowed");
    398 		c->flags |= CLIENT_EXIT;
    399 	}
    400 }
    401 
    402 /*
    403  * Add accept event. If timeout is nonzero, add as a timeout instead of a read
    404  * event - used to backoff when running out of file descriptors.
    405  */
    406 void
    407 server_add_accept(int timeout)
    408 {
    409 	struct timeval tv = { timeout, 0 };
    410 
    411 	if (server_fd == -1)
    412 		return;
    413 
    414 	if (event_initialized(&server_ev_accept))
    415 		event_del(&server_ev_accept);
    416 
    417 	if (timeout == 0) {
    418 		event_set(&server_ev_accept, server_fd, EV_READ, server_accept,
    419 		    NULL);
    420 		event_add(&server_ev_accept, NULL);
    421 	} else {
    422 		event_set(&server_ev_accept, server_fd, EV_TIMEOUT,
    423 		    server_accept, NULL);
    424 		event_add(&server_ev_accept, &tv);
    425 	}
    426 }
    427 
    428 /* Signal handler. */
    429 static void
    430 server_signal(int sig)
    431 {
    432 	int	fd;
    433 
    434 	log_debug("%s: %s", __func__, strsignal(sig));
    435 	switch (sig) {
    436 	case SIGINT:
    437 	case SIGTERM:
    438 		server_exit = 1;
    439 		server_send_exit();
    440 		break;
    441 	case SIGCHLD:
    442 		server_child_signal();
    443 		break;
    444 	case SIGUSR1:
    445 		event_del(&server_ev_accept);
    446 		fd = server_create_socket(server_client_flags, NULL);
    447 		if (fd != -1) {
    448 			close(server_fd);
    449 			server_fd = fd;
    450 			server_update_socket();
    451 		}
    452 		server_add_accept(0);
    453 		break;
    454 	case SIGUSR2:
    455 		proc_toggle_log(server_proc);
    456 		break;
    457 	}
    458 }
    459 
    460 /* Handle SIGCHLD. */
    461 static void
    462 server_child_signal(void)
    463 {
    464 	int	 status;
    465 	pid_t	 pid;
    466 
    467 	for (;;) {
    468 		switch (pid = waitpid(WAIT_ANY, &status, WNOHANG|WUNTRACED)) {
    469 		case -1:
    470 			if (errno == ECHILD)
    471 				return;
    472 			fatal("waitpid failed");
    473 		case 0:
    474 			return;
    475 		}
    476 		if (WIFSTOPPED(status))
    477 			server_child_stopped(pid, status);
    478 		else if (WIFEXITED(status) || WIFSIGNALED(status))
    479 			server_child_exited(pid, status);
    480 	}
    481 }
    482 
    483 /* Handle exited children. */
    484 static void
    485 server_child_exited(pid_t pid, int status)
    486 {
    487 	struct window		*w, *w1;
    488 	struct window_pane	*wp;
    489 
    490 	RB_FOREACH_SAFE(w, windows, &windows, w1) {
    491 		TAILQ_FOREACH(wp, &w->panes, entry) {
    492 			if (wp->pid == pid) {
    493 				wp->status = status;
    494 				wp->flags |= PANE_STATUSREADY;
    495 
    496 				log_debug("%%%u exited", wp->id);
    497 				wp->flags |= PANE_EXITED;
    498 
    499 				if (window_pane_destroy_ready(wp))
    500 					server_destroy_pane(wp, 1);
    501 				break;
    502 			}
    503 		}
    504 	}
    505 	job_check_died(pid, status);
    506 }
    507 
    508 /* Handle stopped children. */
    509 static void
    510 server_child_stopped(pid_t pid, int status)
    511 {
    512 	struct window		*w;
    513 	struct window_pane	*wp;
    514 
    515 	if (WSTOPSIG(status) == SIGTTIN || WSTOPSIG(status) == SIGTTOU)
    516 		return;
    517 
    518 	RB_FOREACH(w, windows, &windows) {
    519 		TAILQ_FOREACH(wp, &w->panes, entry) {
    520 			if (wp->pid == pid) {
    521 				if (killpg(pid, SIGCONT) != 0)
    522 					kill(pid, SIGCONT);
    523 			}
    524 		}
    525 	}
    526 	job_check_died(pid, status);
    527 }
    528 
    529 /* Add to message log. */
    530 void
    531 server_add_message(const char *fmt, ...)
    532 {
    533 	struct message_entry	*msg, *msg1;
    534 	char			*s;
    535 	va_list			 ap;
    536 	u_int			 limit;
    537 
    538 	va_start(ap, fmt);
    539 	xvasprintf(&s, fmt, ap);
    540 	va_end(ap);
    541 
    542 	log_debug("message: %s", s);
    543 
    544 	msg = xcalloc(1, sizeof *msg);
    545 	gettimeofday(&msg->msg_time, NULL);
    546 	msg->msg_num = message_next++;
    547 	msg->msg = s;
    548 	TAILQ_INSERT_TAIL(&message_log, msg, entry);
    549 
    550 	limit = options_get_number(global_options, "message-limit");
    551 	TAILQ_FOREACH_SAFE(msg, &message_log, entry, msg1) {
    552 		if (msg->msg_num + limit >= message_next)
    553 			break;
    554 		free(msg->msg);
    555 		TAILQ_REMOVE(&message_log, msg, entry);
    556 		free(msg);
    557 	}
    558 }
    559