Coverage Report

Created: 2024-07-27 06:19

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