From ab26eabfedbc645ec78cced73ba1bb89adacf0c1 Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 11 Feb 2021 09:39:29 +0000 Subject: [PATCH] Add a couple of helper functions, and flush imsgs on exit. --- usr.bin/tmux/client.c | 17 ++--------------- usr.bin/tmux/file.c | 22 +++++++++++++++++++++- usr.bin/tmux/proc.c | 38 +++++++++++++++++++++++++++++++++++++- usr.bin/tmux/server.c | 31 +++++++++---------------------- usr.bin/tmux/tmux.h | 4 +++- 5 files changed, 72 insertions(+), 40 deletions(-) diff --git a/usr.bin/tmux/client.c b/usr.bin/tmux/client.c index 9ef017eed77..d9bd79fdef7 100644 --- a/usr.bin/tmux/client.c +++ b/usr.bin/tmux/client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: client.c,v 1.152 2021/02/11 08:28:45 nicm Exp $ */ +/* $OpenBSD: client.c,v 1.153 2021/02/11 09:39:29 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -223,20 +223,7 @@ client_exit_message(void) static void client_exit(void) { - struct client_file *cf; - size_t left; - int waiting = 0; - - RB_FOREACH (cf, client_files, &client_files) { - if (cf->event == NULL) - continue; - left = EVBUFFER_LENGTH(cf->event->output); - if (left != 0) { - waiting++; - log_debug("file %u %zu bytes left", cf->stream, left); - } - } - if (waiting == 0) + if (!file_write_left(&client_files)) proc_exit(client_proc); } diff --git a/usr.bin/tmux/file.c b/usr.bin/tmux/file.c index 0520b972de4..8c3d7aaface 100644 --- a/usr.bin/tmux/file.c +++ b/usr.bin/tmux/file.c @@ -1,4 +1,4 @@ -/* $OpenBSD: file.c,v 1.8 2021/02/11 08:28:45 nicm Exp $ */ +/* $OpenBSD: file.c,v 1.9 2021/02/11 09:39:29 nicm Exp $ */ /* * Copyright (c) 2019 Nicholas Marriott @@ -477,6 +477,26 @@ file_push(struct client_file *cf) free(msg); } +/* Check if any files have data left to write. */ +int +file_write_left(struct client_files *files) +{ + struct client_file *cf; + size_t left; + int waiting = 0; + + RB_FOREACH (cf, client_files, files) { + if (cf->event == NULL) + continue; + left = EVBUFFER_LENGTH(cf->event->output); + if (left != 0) { + waiting++; + log_debug("file %u %zu bytes left", cf->stream, left); + } + } + return (waiting != 0); +} + /* Client file write error callback. */ static void file_write_error_callback(__unused struct bufferevent *bev, __unused short what, diff --git a/usr.bin/tmux/proc.c b/usr.bin/tmux/proc.c index af8343f77e7..fd4ca6f97ee 100644 --- a/usr.bin/tmux/proc.c +++ b/usr.bin/tmux/proc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: proc.c,v 1.19 2020/10/26 19:00:37 nicm Exp $ */ +/* $OpenBSD: proc.c,v 1.20 2021/02/11 09:39:29 nicm Exp $ */ /* * Copyright (c) 2015 Nicholas Marriott @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -45,6 +46,8 @@ struct tmuxproc { struct event ev_sigusr1; struct event ev_sigusr2; struct event ev_sigwinch; + + TAILQ_HEAD(, tmuxpeer) peers; }; struct tmuxpeer { @@ -58,6 +61,8 @@ struct tmuxpeer { void (*dispatchcb)(struct imsg *, void *); void *arg; + + TAILQ_ENTRY(tmuxpeer) entry; }; static int peer_check_version(struct tmuxpeer *, struct imsg *); @@ -190,6 +195,7 @@ proc_start(const char *name) tp = xcalloc(1, sizeof *tp); tp->name = xstrdup(name); + TAILQ_INIT(&tp->peers); return (tp); } @@ -207,6 +213,10 @@ proc_loop(struct tmuxproc *tp, int (*loopcb)(void)) void proc_exit(struct tmuxproc *tp) { + struct tmuxpeer *peer; + + TAILQ_FOREACH(peer, &tp->peers, entry) + imsg_flush(&peer->ibuf); tp->exit = 1; } @@ -297,6 +307,7 @@ proc_add_peer(struct tmuxproc *tp, int fd, event_set(&peer->event, fd, EV_READ, proc_event_cb, peer); log_debug("add peer %p: %d (%p)", peer, fd, arg); + TAILQ_INSERT_TAIL(&tp->peers, peer, entry); proc_update_event(peer); return (peer); @@ -305,6 +316,7 @@ proc_add_peer(struct tmuxproc *tp, int fd, void proc_remove_peer(struct tmuxpeer *peer) { + TAILQ_REMOVE(&peer->parent->peers, peer, entry); log_debug("remove peer %p", peer); event_del(&peer->event); @@ -325,3 +337,27 @@ proc_toggle_log(struct tmuxproc *tp) { log_toggle(tp->name); } + +pid_t +proc_fork_and_daemon(int *fd) +{ + pid_t pid; + int pair[2]; + + if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pair) != 0) + fatal("socketpair failed"); + switch (pid = fork()) { + case -1: + fatal("fork failed"); + case 0: + close(pair[0]); + *fd = pair[1]; + if (daemon(1, 0) != 0) + fatal("daemon failed"); + return (0); + default: + close(pair[1]); + *fd = pair[0]; + return (pid); + } +} diff --git a/usr.bin/tmux/server.c b/usr.bin/tmux/server.c index 2890d8357f2..ccbdddcdfc8 100644 --- a/usr.bin/tmux/server.c +++ b/usr.bin/tmux/server.c @@ -1,4 +1,4 @@ -/* $OpenBSD: server.c,v 1.195 2020/09/16 18:37:55 nicm Exp $ */ +/* $OpenBSD: server.c,v 1.196 2021/02/11 09:39:29 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -156,35 +156,22 @@ int server_start(struct tmuxproc *client, int flags, struct event_base *base, int lockfd, char *lockfile) { - int pair[2]; - sigset_t set, oldset; - struct client *c = NULL; - char *cause = NULL; + int fd; + sigset_t set, oldset; + struct client *c = NULL; + char *cause = NULL; sigfillset(&set); sigprocmask(SIG_BLOCK, &set, &oldset); if (~flags & CLIENT_NOFORK) { - if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pair) != 0) - fatal("socketpair failed"); - - switch (fork()) { - case -1: - fatal("fork failed"); - case 0: - break; - default: + if (proc_fork_and_daemon(&fd) != 0) { sigprocmask(SIG_SETMASK, &oldset, NULL); - close(pair[1]); - return (pair[0]); + return (fd); } - close(pair[0]); - if (daemon(1, 0) != 0) - fatal("daemon failed"); } - - server_client_flags = flags; proc_clear_signals(client, 0); + server_client_flags = flags; if (event_reinit(base) != 0) fatalx("event_reinit failed"); @@ -213,7 +200,7 @@ server_start(struct tmuxproc *client, int flags, struct event_base *base, if (server_fd != -1) server_update_socket(); if (~flags & CLIENT_NOFORK) - c = server_client_create(pair[1]); + c = server_client_create(fd); else options_set_number(global_options, "exit-empty", 0); diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h index 243ac4b9580..a28efbb9aca 100644 --- a/usr.bin/tmux/tmux.h +++ b/usr.bin/tmux/tmux.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tmux.h,v 1.1089 2021/02/11 08:28:45 nicm Exp $ */ +/* $OpenBSD: tmux.h,v 1.1090 2021/02/11 09:39:29 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -1899,6 +1899,7 @@ struct tmuxpeer *proc_add_peer(struct tmuxproc *, int, void proc_remove_peer(struct tmuxpeer *); void proc_kill_peer(struct tmuxpeer *); void proc_toggle_log(struct tmuxproc *); +pid_t proc_fork_and_daemon(int *); /* cfg.c */ extern int cfg_finished; @@ -2389,6 +2390,7 @@ void file_write(struct client *, const char *, int, const void *, size_t, client_file_cb, void *); void file_read(struct client *, const char *, client_file_cb, void *); void file_push(struct client_file *); +int file_write_left(struct client_files *); void file_write_open(struct client_files *, struct tmuxpeer *, struct imsg *, int, int, client_file_cb, void *); void file_write_data(struct client_files *, struct imsg *); -- 2.20.1