tmux  3.2a
About: tmux is a terminal multiplexer that lets you switch easily between several programs in one terminal.
  Fossies Dox: tmux-3.2a.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

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