From dd92b6e83dbd4b5f24ad062c7944ca32add8d0e5 Mon Sep 17 00:00:00 2001 From: nicm Date: Sun, 30 Aug 2015 22:19:07 +0000 Subject: [PATCH 01/17] Event base does not need to be global. --- client.c | 10 +++++----- server.c | 4 ++-- tmux.c | 5 +---- tmux.h | 5 ++--- 4 files changed, 10 insertions(+), 14 deletions(-) diff --git a/client.c b/client.c index 63432926..271568da 100644 --- a/client.c +++ b/client.c @@ -52,7 +52,7 @@ const char *client_exitsession; int client_attached; int client_get_lock(char *); -int client_connect(char *, int); +int client_connect(struct event_base *, char *, int); void client_send_identify(int); int client_write_one(enum msgtype, int, const void *, size_t); int client_write_server(enum msgtype, const void *, size_t); @@ -96,7 +96,7 @@ client_get_lock(char *lockfile) /* Connect client to server. */ int -client_connect(char *path, int start_server) +client_connect(struct event_base *base, char *path, int start_server) { struct sockaddr_un sa; size_t size; @@ -149,7 +149,7 @@ retry: close(lockfd); return (-1); } - fd = server_start(lockfd, lockfile); + fd = server_start(base, lockfd, lockfile); } if (locked) { free(lockfile); @@ -203,7 +203,7 @@ client_exit_message(void) /* Client main loop. */ int -client_main(int argc, char **argv, int flags) +client_main(struct event_base *base, int argc, char **argv, int flags) { struct cmd *cmd; struct cmd_list *cmdlist; @@ -252,7 +252,7 @@ client_main(int argc, char **argv, int flags) set_signals(client_signal); /* Initialize the client socket and start the server. */ - fd = client_connect(socket_path, cmdflags & CMD_STARTSERVER); + fd = client_connect(base, socket_path, cmdflags & CMD_STARTSERVER); if (fd == -1) { if (errno == ECONNREFUSED) { fprintf(stderr, "no server running on %s\n", diff --git a/server.c b/server.c index 9cddecd3..8308367d 100644 --- a/server.c +++ b/server.c @@ -158,7 +158,7 @@ server_create_socket(void) /* Fork new server. */ int -server_start(int lockfd, char *lockfile) +server_start(struct event_base *base, int lockfd, char *lockfile) { int pair[2]; char *cause; @@ -188,7 +188,7 @@ server_start(int lockfd, char *lockfile) /* event_init() was called in our parent, need to reinit. */ clear_signals(0); - if (event_reinit(ev_base) != 0) + if (event_reinit(base) != 0) fatal("event_reinit failed"); logfile("server"); diff --git a/tmux.c b/tmux.c index e66d24c0..b984b903 100644 --- a/tmux.c +++ b/tmux.c @@ -41,8 +41,6 @@ struct options global_s_options; /* session options */ struct options global_w_options; /* window options */ struct environ global_environ; -struct event_base *ev_base; - char *cfg_file; char *shell_cmd; int debug_level; @@ -386,6 +384,5 @@ main(int argc, char **argv) setproctitle("%s (%s)", __progname, socket_path); /* Pass control to the client. */ - ev_base = event_init(); - exit(client_main(argc, argv, flags)); + exit(client_main(event_init(), argc, argv, flags)); } diff --git a/tmux.h b/tmux.h index 10b161de..3b67470f 100644 --- a/tmux.h +++ b/tmux.h @@ -1407,7 +1407,6 @@ extern struct options global_options; extern struct options global_s_options; extern struct options global_w_options; extern struct environ global_environ; -extern struct event_base *ev_base; extern char *cfg_file; extern char *shell_cmd; extern int debug_level; @@ -1792,7 +1791,7 @@ int cmd_string_parse(const char *, struct cmd_list **, const char *, void cmd_wait_for_flush(void); /* client.c */ -int client_main(int, char **, int); +int client_main(struct event_base *, int, char **, int); /* key-bindings.c */ RB_PROTOTYPE(key_bindings, key_binding, entry, key_bindings_cmp); @@ -1829,7 +1828,7 @@ void server_clear_marked(void); int server_is_marked(struct session *, struct winlink *, struct window_pane *); int server_check_marked(void); -int server_start(int, char *); +int server_start(struct event_base *, int, char *); void server_update_socket(void); void server_add_accept(int); From c6e9160c676db48e12e3c38229870d1c020cf1d2 Mon Sep 17 00:00:00 2001 From: nicm Date: Sun, 30 Aug 2015 22:40:25 +0000 Subject: [PATCH 02/17] Login shell can be a client flag, and move the exec code into client.c. --- client.c | 67 ++++++++++++++++++++++++++++++++++++++++++-------------- tmux.c | 36 +++++------------------------- tmux.h | 4 +--- 3 files changed, 57 insertions(+), 50 deletions(-) diff --git a/client.c b/client.c index 271568da..55c5aa56 100644 --- a/client.c +++ b/client.c @@ -33,6 +33,7 @@ #include "tmux.h" +int client_flags; struct imsgbuf client_ibuf; struct event client_event; struct event client_stdin; @@ -51,9 +52,10 @@ enum msgtype client_exittype; const char *client_exitsession; int client_attached; +__dead void client_exec(const char *); int client_get_lock(char *); int client_connect(struct event_base *, char *, int); -void client_send_identify(int); +void client_send_identify(void); int client_write_one(enum msgtype, int, const void *, size_t); int client_write_server(enum msgtype, const void *, size_t); void client_update_event(void); @@ -62,7 +64,7 @@ void client_stdin_callback(int, short, void *); void client_write(int, const char *, size_t); void client_callback(int, short, void *); int client_dispatch_attached(void); -int client_dispatch_wait(void *); +int client_dispatch_wait(void); const char *client_exit_message(void); /* @@ -215,6 +217,9 @@ client_main(struct event_base *base, int argc, char **argv, int flags) struct termios tio, saved_tio; size_t size; + /* Save the flags. */ + client_flags = flags; + /* Set up the initial command. */ cmdflags = 0; if (shell_cmd != NULL) { @@ -266,13 +271,13 @@ client_main(struct event_base *base, int argc, char **argv, int flags) /* Create imsg. */ imsg_init(&client_ibuf, fd); - event_set(&client_event, fd, EV_READ, client_callback, shell_cmd); + event_set(&client_event, fd, EV_READ, client_callback, NULL); /* Create stdin handler. */ setblocking(STDIN_FILENO, 0); event_set(&client_stdin, STDIN_FILENO, EV_READ|EV_PERSIST, client_stdin_callback, NULL); - if (flags & CLIENT_CONTROLCONTROL) { + if (client_flags & CLIENT_CONTROLCONTROL) { if (tcgetattr(STDIN_FILENO, &saved_tio) != 0) { fprintf(stderr, "tcgetattr failed: %s\n", strerror(errno)); @@ -291,7 +296,7 @@ client_main(struct event_base *base, int argc, char **argv, int flags) } /* Send identify messages. */ - client_send_identify(flags); + client_send_identify(); /* Send first command. */ if (msg == MSG_COMMAND) { @@ -326,13 +331,13 @@ client_main(struct event_base *base, int argc, char **argv, int flags) /* Print the exit message, if any, and exit. */ if (client_attached) { - if (client_exitreason != CLIENT_EXIT_NONE && !login_shell) + if (client_exitreason != CLIENT_EXIT_NONE) printf("[%s]\n", client_exit_message()); ppid = getppid(); if (client_exittype == MSG_DETACHKILL && ppid > 1) kill(ppid, SIGHUP); - } else if (flags & CLIENT_CONTROLCONTROL) { + } else if (client_flags & CLIENT_CONTROLCONTROL) { if (client_exitreason != CLIENT_EXIT_NONE) printf("%%exit %s\n", client_exit_message()); else @@ -346,12 +351,12 @@ client_main(struct event_base *base, int argc, char **argv, int flags) /* Send identify messages to server. */ void -client_send_identify(int flags) +client_send_identify(void) { const char *s; char **ss; size_t sslen; - int fd; + int fd, flags = client_flags; pid_t pid; client_write_one(MSG_IDENTIFY_FLAGS, -1, &flags, sizeof flags); @@ -421,14 +426,13 @@ client_update_event(void) events = EV_READ; if (client_ibuf.w.queued > 0) events |= EV_WRITE; - event_set( - &client_event, client_ibuf.fd, events, client_callback, shell_cmd); + event_set(&client_event, client_ibuf.fd, events, client_callback, NULL); event_add(&client_event, NULL); } /* Callback to handle signals in the client. */ void -client_signal(int sig, unused short events, unused void *data) +client_signal(int sig, unused short events, unused void *arg) { struct sigaction sigact; int status; @@ -470,7 +474,7 @@ client_signal(int sig, unused short events, unused void *data) /* Callback for client imsg read events. */ void -client_callback(unused int fd, short events, void *data) +client_callback(unused int fd, short events, unused void *arg) { ssize_t n; int retval; @@ -481,7 +485,7 @@ client_callback(unused int fd, short events, void *data) if (client_attached) retval = client_dispatch_attached(); else - retval = client_dispatch_wait(data); + retval = client_dispatch_wait(); if (retval != 0) { event_loopexit(NULL); return; @@ -504,7 +508,7 @@ lost_server: /* Callback for client stdin read events. */ void -client_stdin_callback(unused int fd, unused short events, unused void *data1) +client_stdin_callback(unused int fd, unused short events, unused void *arg) { struct msg_stdin_data data; @@ -536,9 +540,38 @@ client_write(int fd, const char *data, size_t size) } } +/* Run command in shell; used for -c. */ +__dead void +client_exec(const char *shell) +{ + const char *name, *ptr; + char *argv0; + + log_debug("shell %s, command %s", shell, shell_cmd); + + ptr = strrchr(shell, '/'); + if (ptr != NULL && *(ptr + 1) != '\0') + name = ptr + 1; + else + name = shell; + if (client_flags & CLIENT_LOGIN) + xasprintf(&argv0, "-%s", name); + else + xasprintf(&argv0, "%s", name); + setenv("SHELL", shell, 1); + + setblocking(STDIN_FILENO, 1); + setblocking(STDOUT_FILENO, 1); + setblocking(STDERR_FILENO, 1); + closefrom(STDERR_FILENO + 1); + + execl(shell, argv0, "-c", shell_cmd, (char *) NULL); + fatal("execl failed"); +} + /* Dispatch imsgs when in wait state (before MSG_READY). */ int -client_dispatch_wait(void *data0) +client_dispatch_wait(void) { struct imsg imsg; char *data; @@ -614,7 +647,7 @@ client_dispatch_wait(void *data0) fatalx("bad MSG_SHELL string"); clear_signals(0); - shell_exec(data, data0); + client_exec(data); /* NOTREACHED */ case MSG_DETACH: case MSG_DETACHKILL: diff --git a/tmux.c b/tmux.c index b984b903..1ef23915 100644 --- a/tmux.c +++ b/tmux.c @@ -46,7 +46,6 @@ char *shell_cmd; int debug_level; time_t start_time; char socket_path[PATH_MAX]; -int login_shell; char *environ_path; __dead void usage(void); @@ -170,32 +169,6 @@ setblocking(int fd, int state) } } -__dead void -shell_exec(const char *shell, const char *shellcmd) -{ - const char *shellname, *ptr; - char *argv0; - - ptr = strrchr(shell, '/'); - if (ptr != NULL && *(ptr + 1) != '\0') - shellname = ptr + 1; - else - shellname = shell; - if (login_shell) - xasprintf(&argv0, "-%s", shellname); - else - xasprintf(&argv0, "%s", shellname); - setenv("SHELL", shell, 1); - - setblocking(STDIN_FILENO, 1); - setblocking(STDOUT_FILENO, 1); - setblocking(STDERR_FILENO, 1); - closefrom(STDERR_FILENO + 1); - - execl(shell, argv0, "-c", shellcmd, (char *) NULL); - fatal("execl failed"); -} - const char * find_home(void) { @@ -229,9 +202,12 @@ main(int argc, char **argv) setlocale(LC_TIME, ""); - flags = 0; + if (**argv == '-') + flags = CLIENT_LOGIN; + else + flags = 0; + label = path = NULL; - login_shell = (**argv == '-'); while ((opt = getopt(argc, argv, "2c:Cdf:lL:qS:uUv")) != -1) { switch (opt) { case '2': @@ -252,7 +228,7 @@ main(int argc, char **argv) cfg_file = xstrdup(optarg); break; case 'l': - login_shell = 1; + flags |= CLIENT_LOGIN; break; case 'L': free(label); diff --git a/tmux.h b/tmux.h index 3b67470f..528c3e71 100644 --- a/tmux.h +++ b/tmux.h @@ -1203,7 +1203,7 @@ struct client { struct screen status; #define CLIENT_TERMINAL 0x1 -/* 0x2 unused */ +#define CLIENT_LOGIN 0x2 #define CLIENT_EXIT 0x4 #define CLIENT_REDRAW 0x8 #define CLIENT_STATUS 0x10 @@ -1412,14 +1412,12 @@ extern char *shell_cmd; extern int debug_level; extern time_t start_time; extern char socket_path[PATH_MAX]; -extern int login_shell; extern char *environ_path; void logfile(const char *); const char *getshell(void); int checkshell(const char *); int areshell(const char *); void setblocking(int, int); -__dead void shell_exec(const char *, const char *); const char *find_home(void); /* cfg.c */ From 6a539c00dfe52f588376d997a75e6c7540db5e14 Mon Sep 17 00:00:00 2001 From: nicm Date: Sun, 30 Aug 2015 22:56:36 +0000 Subject: [PATCH 03/17] Path from $TMUX does not need to be global anymore. --- tmux.c | 26 +++++++++++++------------- tmux.h | 1 - 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/tmux.c b/tmux.c index 1ef23915..6eb2a301 100644 --- a/tmux.c +++ b/tmux.c @@ -46,7 +46,6 @@ char *shell_cmd; int debug_level; time_t start_time; char socket_path[PATH_MAX]; -char *environ_path; __dead void usage(void); char *makesocketpath(const char *); @@ -191,10 +190,8 @@ int main(int argc, char **argv) { char *s, *path, *label, **var, tmp[PATH_MAX]; - char in[256]; const char *home; - long long pid; - int opt, flags, keys, session; + int opt, flags, keys; #ifdef DEBUG malloc_options = (char *) "AFGJPX"; @@ -321,11 +318,6 @@ main(int argc, char **argv) } } - /* Get path from environment. */ - s = getenv("TMUX"); - if (s != NULL && sscanf(s, "%255[^,],%lld,%d", in, &pid, &session) == 3) - environ_path = xstrdup(in); - /* * Figure out the socket path. If specified on the command-line with -S * or -L, use it, otherwise try $TMUX or assume -L default. @@ -333,8 +325,15 @@ main(int argc, char **argv) if (path == NULL) { /* If no -L, use the environment. */ if (label == NULL) { - if (environ_path != NULL) - path = xstrdup(environ_path); + s = getenv("TMUX"); + if (s != NULL) { + path = xstrdup(s); + path[strcspn (path, ",")] = '\0'; + if (*path == '\0') { + free(path); + label = xstrdup("default"); + } + } else label = xstrdup("default"); } @@ -343,14 +342,15 @@ main(int argc, char **argv) if (label != NULL) { if ((path = makesocketpath(label)) == NULL) { fprintf(stderr, "can't create socket: %s\n", - strerror(errno)); + strerror(errno)); exit(1); } } } free(label); - if (strlcpy(socket_path, path, sizeof socket_path) >= sizeof socket_path) { + if (strlcpy(socket_path, path, sizeof socket_path) >= + sizeof socket_path) { fprintf(stderr, "socket path too long: %s\n", path); exit(1); } diff --git a/tmux.h b/tmux.h index 528c3e71..1bde93cd 100644 --- a/tmux.h +++ b/tmux.h @@ -1412,7 +1412,6 @@ extern char *shell_cmd; extern int debug_level; extern time_t start_time; extern char socket_path[PATH_MAX]; -extern char *environ_path; void logfile(const char *); const char *getshell(void); int checkshell(const char *); From 2a836bc306c5635329bec2dd35ba9537a552ff9a Mon Sep 17 00:00:00 2001 From: nicm Date: Tue, 1 Sep 2015 09:48:34 +0000 Subject: [PATCH 04/17] All the cmd_*_entry declarations do not need to be in tmux.h. --- cmd.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ tmux.h | 86 --------------------------------------------------------- 2 files changed, 87 insertions(+), 86 deletions(-) diff --git a/cmd.c b/cmd.c index e8ce932d..0c20d656 100644 --- a/cmd.c +++ b/cmd.c @@ -28,6 +28,93 @@ #include "tmux.h" +extern const struct cmd_entry cmd_attach_session_entry; +extern const struct cmd_entry cmd_bind_key_entry; +extern const struct cmd_entry cmd_break_pane_entry; +extern const struct cmd_entry cmd_capture_pane_entry; +extern const struct cmd_entry cmd_choose_buffer_entry; +extern const struct cmd_entry cmd_choose_client_entry; +extern const struct cmd_entry cmd_choose_session_entry; +extern const struct cmd_entry cmd_choose_tree_entry; +extern const struct cmd_entry cmd_choose_window_entry; +extern const struct cmd_entry cmd_clear_history_entry; +extern const struct cmd_entry cmd_clock_mode_entry; +extern const struct cmd_entry cmd_command_prompt_entry; +extern const struct cmd_entry cmd_confirm_before_entry; +extern const struct cmd_entry cmd_copy_mode_entry; +extern const struct cmd_entry cmd_delete_buffer_entry; +extern const struct cmd_entry cmd_detach_client_entry; +extern const struct cmd_entry cmd_display_message_entry; +extern const struct cmd_entry cmd_display_panes_entry; +extern const struct cmd_entry cmd_down_pane_entry; +extern const struct cmd_entry cmd_find_window_entry; +extern const struct cmd_entry cmd_has_session_entry; +extern const struct cmd_entry cmd_if_shell_entry; +extern const struct cmd_entry cmd_join_pane_entry; +extern const struct cmd_entry cmd_kill_pane_entry; +extern const struct cmd_entry cmd_kill_server_entry; +extern const struct cmd_entry cmd_kill_session_entry; +extern const struct cmd_entry cmd_kill_window_entry; +extern const struct cmd_entry cmd_last_pane_entry; +extern const struct cmd_entry cmd_last_window_entry; +extern const struct cmd_entry cmd_link_window_entry; +extern const struct cmd_entry cmd_list_buffers_entry; +extern const struct cmd_entry cmd_list_clients_entry; +extern const struct cmd_entry cmd_list_commands_entry; +extern const struct cmd_entry cmd_list_keys_entry; +extern const struct cmd_entry cmd_list_panes_entry; +extern const struct cmd_entry cmd_list_sessions_entry; +extern const struct cmd_entry cmd_list_windows_entry; +extern const struct cmd_entry cmd_load_buffer_entry; +extern const struct cmd_entry cmd_lock_client_entry; +extern const struct cmd_entry cmd_lock_server_entry; +extern const struct cmd_entry cmd_lock_session_entry; +extern const struct cmd_entry cmd_move_pane_entry; +extern const struct cmd_entry cmd_move_window_entry; +extern const struct cmd_entry cmd_new_session_entry; +extern const struct cmd_entry cmd_new_window_entry; +extern const struct cmd_entry cmd_next_layout_entry; +extern const struct cmd_entry cmd_next_window_entry; +extern const struct cmd_entry cmd_paste_buffer_entry; +extern const struct cmd_entry cmd_pipe_pane_entry; +extern const struct cmd_entry cmd_previous_layout_entry; +extern const struct cmd_entry cmd_previous_window_entry; +extern const struct cmd_entry cmd_refresh_client_entry; +extern const struct cmd_entry cmd_rename_session_entry; +extern const struct cmd_entry cmd_rename_window_entry; +extern const struct cmd_entry cmd_resize_pane_entry; +extern const struct cmd_entry cmd_respawn_pane_entry; +extern const struct cmd_entry cmd_respawn_window_entry; +extern const struct cmd_entry cmd_rotate_window_entry; +extern const struct cmd_entry cmd_run_shell_entry; +extern const struct cmd_entry cmd_save_buffer_entry; +extern const struct cmd_entry cmd_select_layout_entry; +extern const struct cmd_entry cmd_select_pane_entry; +extern const struct cmd_entry cmd_select_window_entry; +extern const struct cmd_entry cmd_send_keys_entry; +extern const struct cmd_entry cmd_send_prefix_entry; +extern const struct cmd_entry cmd_server_info_entry; +extern const struct cmd_entry cmd_set_buffer_entry; +extern const struct cmd_entry cmd_set_environment_entry; +extern const struct cmd_entry cmd_set_option_entry; +extern const struct cmd_entry cmd_set_window_option_entry; +extern const struct cmd_entry cmd_show_buffer_entry; +extern const struct cmd_entry cmd_show_environment_entry; +extern const struct cmd_entry cmd_show_messages_entry; +extern const struct cmd_entry cmd_show_options_entry; +extern const struct cmd_entry cmd_show_window_options_entry; +extern const struct cmd_entry cmd_source_file_entry; +extern const struct cmd_entry cmd_split_window_entry; +extern const struct cmd_entry cmd_start_server_entry; +extern const struct cmd_entry cmd_suspend_client_entry; +extern const struct cmd_entry cmd_swap_pane_entry; +extern const struct cmd_entry cmd_swap_window_entry; +extern const struct cmd_entry cmd_switch_client_entry; +extern const struct cmd_entry cmd_unbind_key_entry; +extern const struct cmd_entry cmd_unlink_window_entry; +extern const struct cmd_entry cmd_up_pane_entry; +extern const struct cmd_entry cmd_wait_for_entry; + const struct cmd_entry *cmd_table[] = { &cmd_attach_session_entry, &cmd_bind_key_entry, diff --git a/tmux.h b/tmux.h index 1bde93cd..4e880028 100644 --- a/tmux.h +++ b/tmux.h @@ -1671,92 +1671,6 @@ struct window_pane *cmd_mouse_pane(struct mouse_event *, struct session **, struct winlink **); char *cmd_template_replace(const char *, const char *, int); extern const struct cmd_entry *cmd_table[]; -extern const struct cmd_entry cmd_attach_session_entry; -extern const struct cmd_entry cmd_bind_key_entry; -extern const struct cmd_entry cmd_break_pane_entry; -extern const struct cmd_entry cmd_capture_pane_entry; -extern const struct cmd_entry cmd_choose_buffer_entry; -extern const struct cmd_entry cmd_choose_client_entry; -extern const struct cmd_entry cmd_choose_session_entry; -extern const struct cmd_entry cmd_choose_tree_entry; -extern const struct cmd_entry cmd_choose_window_entry; -extern const struct cmd_entry cmd_clear_history_entry; -extern const struct cmd_entry cmd_clock_mode_entry; -extern const struct cmd_entry cmd_command_prompt_entry; -extern const struct cmd_entry cmd_confirm_before_entry; -extern const struct cmd_entry cmd_copy_mode_entry; -extern const struct cmd_entry cmd_delete_buffer_entry; -extern const struct cmd_entry cmd_detach_client_entry; -extern const struct cmd_entry cmd_display_message_entry; -extern const struct cmd_entry cmd_display_panes_entry; -extern const struct cmd_entry cmd_down_pane_entry; -extern const struct cmd_entry cmd_find_window_entry; -extern const struct cmd_entry cmd_has_session_entry; -extern const struct cmd_entry cmd_if_shell_entry; -extern const struct cmd_entry cmd_join_pane_entry; -extern const struct cmd_entry cmd_kill_pane_entry; -extern const struct cmd_entry cmd_kill_server_entry; -extern const struct cmd_entry cmd_kill_session_entry; -extern const struct cmd_entry cmd_kill_window_entry; -extern const struct cmd_entry cmd_last_pane_entry; -extern const struct cmd_entry cmd_last_window_entry; -extern const struct cmd_entry cmd_link_window_entry; -extern const struct cmd_entry cmd_list_buffers_entry; -extern const struct cmd_entry cmd_list_clients_entry; -extern const struct cmd_entry cmd_list_commands_entry; -extern const struct cmd_entry cmd_list_keys_entry; -extern const struct cmd_entry cmd_list_panes_entry; -extern const struct cmd_entry cmd_list_sessions_entry; -extern const struct cmd_entry cmd_list_windows_entry; -extern const struct cmd_entry cmd_load_buffer_entry; -extern const struct cmd_entry cmd_lock_client_entry; -extern const struct cmd_entry cmd_lock_server_entry; -extern const struct cmd_entry cmd_lock_session_entry; -extern const struct cmd_entry cmd_move_pane_entry; -extern const struct cmd_entry cmd_move_window_entry; -extern const struct cmd_entry cmd_new_session_entry; -extern const struct cmd_entry cmd_new_window_entry; -extern const struct cmd_entry cmd_next_layout_entry; -extern const struct cmd_entry cmd_next_window_entry; -extern const struct cmd_entry cmd_paste_buffer_entry; -extern const struct cmd_entry cmd_pipe_pane_entry; -extern const struct cmd_entry cmd_previous_layout_entry; -extern const struct cmd_entry cmd_previous_window_entry; -extern const struct cmd_entry cmd_refresh_client_entry; -extern const struct cmd_entry cmd_rename_session_entry; -extern const struct cmd_entry cmd_rename_window_entry; -extern const struct cmd_entry cmd_resize_pane_entry; -extern const struct cmd_entry cmd_respawn_pane_entry; -extern const struct cmd_entry cmd_respawn_window_entry; -extern const struct cmd_entry cmd_rotate_window_entry; -extern const struct cmd_entry cmd_run_shell_entry; -extern const struct cmd_entry cmd_save_buffer_entry; -extern const struct cmd_entry cmd_select_layout_entry; -extern const struct cmd_entry cmd_select_pane_entry; -extern const struct cmd_entry cmd_select_window_entry; -extern const struct cmd_entry cmd_send_keys_entry; -extern const struct cmd_entry cmd_send_prefix_entry; -extern const struct cmd_entry cmd_server_info_entry; -extern const struct cmd_entry cmd_set_buffer_entry; -extern const struct cmd_entry cmd_set_environment_entry; -extern const struct cmd_entry cmd_set_option_entry; -extern const struct cmd_entry cmd_set_window_option_entry; -extern const struct cmd_entry cmd_show_buffer_entry; -extern const struct cmd_entry cmd_show_environment_entry; -extern const struct cmd_entry cmd_show_messages_entry; -extern const struct cmd_entry cmd_show_options_entry; -extern const struct cmd_entry cmd_show_window_options_entry; -extern const struct cmd_entry cmd_source_file_entry; -extern const struct cmd_entry cmd_split_window_entry; -extern const struct cmd_entry cmd_start_server_entry; -extern const struct cmd_entry cmd_suspend_client_entry; -extern const struct cmd_entry cmd_swap_pane_entry; -extern const struct cmd_entry cmd_swap_window_entry; -extern const struct cmd_entry cmd_switch_client_entry; -extern const struct cmd_entry cmd_unbind_key_entry; -extern const struct cmd_entry cmd_unlink_window_entry; -extern const struct cmd_entry cmd_up_pane_entry; -extern const struct cmd_entry cmd_wait_for_entry; /* cmd-attach-session.c */ enum cmd_retval cmd_attach_session(struct cmd_q *, const char *, int, int, From 83157c02d6935d3ea4dcf6e39d6a531849a775d6 Mon Sep 17 00:00:00 2001 From: nicm Date: Tue, 1 Sep 2015 10:01:56 +0000 Subject: [PATCH 05/17] Move initial conf load into cfg.c. --- cfg.c | 43 +++++++++++++++++++++++++++++++++++++------ server.c | 21 ++------------------- tmux.h | 3 +-- 3 files changed, 40 insertions(+), 27 deletions(-) diff --git a/cfg.c b/cfg.c index 37474094..e15d048d 100644 --- a/cfg.c +++ b/cfg.c @@ -23,16 +23,47 @@ #include #include #include +#include #include #include "tmux.h" -struct cmd_q *cfg_cmd_q; -int cfg_finished; -int cfg_references; -char **cfg_causes; -u_int cfg_ncauses; -struct client *cfg_client; +struct cmd_q *cfg_cmd_q; +int cfg_finished; +int cfg_references; +char **cfg_causes; +u_int cfg_ncauses; +struct client *cfg_client; + +void cfg_default_done(struct cmd_q *); + +void +start_cfg(void) +{ + char *cause = NULL; + + cfg_cmd_q = cmdq_new(NULL); + cfg_cmd_q->emptyfn = cfg_default_done; + + cfg_finished = 0; + cfg_references = 1; + + cfg_client = TAILQ_FIRST(&clients); + if (cfg_client != NULL) + cfg_client->references++; + + if (access(TMUX_CONF, R_OK) == 0) { + if (load_cfg(TMUX_CONF, cfg_cmd_q, &cause) == -1) + cfg_add_cause("%s: %s", TMUX_CONF, cause); + } else if (errno != ENOENT) + cfg_add_cause("%s: %s", TMUX_CONF, strerror(errno)); + + if (cfg_file != NULL && load_cfg(cfg_file, cfg_cmd_q, &cause) == -1) + cfg_add_cause("%s: %s", cfg_file, cause); + free(cause); + + cmdq_continue(cfg_cmd_q); +} int load_cfg(const char *path, struct cmd_q *cmdq, char **cause) diff --git a/server.c b/server.c index 8308367d..045daead 100644 --- a/server.c +++ b/server.c @@ -160,8 +160,7 @@ server_create_socket(void) int server_start(struct event_base *base, int lockfd, char *lockfile) { - int pair[2]; - char *cause; + int pair[2]; /* The first client is special and gets a socketpair; create it. */ if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pair) != 0) @@ -217,24 +216,8 @@ server_start(struct event_base *base, int lockfd, char *lockfile) free(lockfile); close(lockfd); - cfg_cmd_q = cmdq_new(NULL); - cfg_cmd_q->emptyfn = cfg_default_done; - cfg_finished = 0; - cfg_references = 1; - cfg_client = TAILQ_FIRST(&clients); - if (cfg_client != NULL) - cfg_client->references++; + start_cfg(); - if (access(TMUX_CONF, R_OK) == 0) { - if (load_cfg(TMUX_CONF, cfg_cmd_q, &cause) == -1) - cfg_add_cause("%s: %s", TMUX_CONF, cause); - } else if (errno != ENOENT) - cfg_add_cause("%s: %s", TMUX_CONF, strerror(errno)); - if (cfg_file != NULL) { - if (load_cfg(cfg_file, cfg_cmd_q, &cause) == -1) - cfg_add_cause("%s: %s", cfg_file, cause); - } - cmdq_continue(cfg_cmd_q); status_prompt_load_history(); server_add_accept(0); diff --git a/tmux.h b/tmux.h index 4e880028..ced3cccf 100644 --- a/tmux.h +++ b/tmux.h @@ -1420,12 +1420,11 @@ void setblocking(int, int); const char *find_home(void); /* cfg.c */ -extern struct cmd_q *cfg_cmd_q; extern int cfg_finished; extern int cfg_references; extern struct client *cfg_client; +void start_cfg(void); int load_cfg(const char *, struct cmd_q *, char **); -void cfg_default_done(struct cmd_q *); void cfg_add_cause(const char *, ...); void cfg_print_causes(struct cmd_q *); void cfg_show_causes(struct session *); From 952ba846111fb91d9882846a4061955262f34212 Mon Sep 17 00:00:00 2001 From: nicm Date: Tue, 1 Sep 2015 10:10:59 +0000 Subject: [PATCH 06/17] Work out config file when needed not at startup. --- cfg.c | 18 +++++++++++++++++- tmux.c | 28 ++++++++-------------------- tmux.h | 2 +- 3 files changed, 26 insertions(+), 22 deletions(-) diff --git a/cfg.c b/cfg.c index e15d048d..ecb38fc0 100644 --- a/cfg.c +++ b/cfg.c @@ -28,6 +28,7 @@ #include "tmux.h" +char *cfg_file; struct cmd_q *cfg_cmd_q; int cfg_finished; int cfg_references; @@ -37,10 +38,18 @@ struct client *cfg_client; void cfg_default_done(struct cmd_q *); +void +set_cfg_file(const char *path) +{ + free(cfg_file); + cfg_file = xstrdup(path); +} + void start_cfg(void) { - char *cause = NULL; + char *cause = NULL; + const char *home; cfg_cmd_q = cmdq_new(NULL); cfg_cmd_q->emptyfn = cfg_default_done; @@ -58,6 +67,13 @@ start_cfg(void) } else if (errno != ENOENT) cfg_add_cause("%s: %s", TMUX_CONF, strerror(errno)); + if (cfg_file == NULL && (home = find_home()) != NULL) { + xasprintf(&cfg_file, "%s/.tmux.conf", home); + if (access(cfg_file, R_OK) != 0 && errno == ENOENT) { + free(cfg_file); + cfg_file = NULL; + } + } if (cfg_file != NULL && load_cfg(cfg_file, cfg_cmd_q, &cause) == -1) cfg_add_cause("%s: %s", cfg_file, cause); free(cause); diff --git a/tmux.c b/tmux.c index 6eb2a301..69097bf9 100644 --- a/tmux.c +++ b/tmux.c @@ -41,7 +41,6 @@ struct options global_s_options; /* session options */ struct options global_w_options; /* window options */ struct environ global_environ; -char *cfg_file; char *shell_cmd; int debug_level; time_t start_time; @@ -171,8 +170,11 @@ setblocking(int fd, int state) const char * find_home(void) { - struct passwd *pw; - const char *home; + struct passwd *pw; + static const char *home; + + if (home != NULL) + return (home); home = getenv("HOME"); if (home == NULL || *home == '\0') { @@ -189,9 +191,8 @@ find_home(void) int main(int argc, char **argv) { - char *s, *path, *label, **var, tmp[PATH_MAX]; - const char *home; - int opt, flags, keys; + char *s, *path, *label, **var, tmp[PATH_MAX]; + int opt, flags, keys; #ifdef DEBUG malloc_options = (char *) "AFGJPX"; @@ -221,8 +222,7 @@ main(int argc, char **argv) flags |= CLIENT_CONTROL; break; case 'f': - free(cfg_file); - cfg_file = xstrdup(optarg); + set_cfg_file(optarg); break; case 'l': flags |= CLIENT_LOGIN; @@ -306,18 +306,6 @@ main(int argc, char **argv) options_set_number(&global_w_options, "mode-keys", keys); } - /* Locate the configuration file. */ - if (cfg_file == NULL) { - home = find_home(); - if (home != NULL) { - xasprintf(&cfg_file, "%s/.tmux.conf", home); - if (access(cfg_file, R_OK) != 0 && errno == ENOENT) { - free(cfg_file); - cfg_file = NULL; - } - } - } - /* * Figure out the socket path. If specified on the command-line with -S * or -L, use it, otherwise try $TMUX or assume -L default. diff --git a/tmux.h b/tmux.h index ced3cccf..c2309f8a 100644 --- a/tmux.h +++ b/tmux.h @@ -1407,7 +1407,6 @@ extern struct options global_options; extern struct options global_s_options; extern struct options global_w_options; extern struct environ global_environ; -extern char *cfg_file; extern char *shell_cmd; extern int debug_level; extern time_t start_time; @@ -1425,6 +1424,7 @@ extern int cfg_references; extern struct client *cfg_client; void start_cfg(void); int load_cfg(const char *, struct cmd_q *, char **); +void set_cfg_file(const char *); void cfg_add_cause(const char *, ...); void cfg_print_causes(struct cmd_q *); void cfg_show_causes(struct session *); From 69a2d46ee55b5fc62862dde7cf74bc02556e7559 Mon Sep 17 00:00:00 2001 From: nicm Date: Tue, 1 Sep 2015 11:13:39 +0000 Subject: [PATCH 07/17] Remove dead_clients which is no longer used. --- tmux.h | 1 - 1 file changed, 1 deletion(-) diff --git a/tmux.h b/tmux.h index c2309f8a..a71d6c2a 100644 --- a/tmux.h +++ b/tmux.h @@ -1728,7 +1728,6 @@ void alerts_queue(struct window *, int); /* server.c */ extern struct clients clients; -extern struct clients dead_clients; extern struct session *marked_session; extern struct winlink *marked_winlink; extern struct window_pane *marked_window_pane; From fa3d4fab85e4c1f807808640f75f50a41bbb2c5b Mon Sep 17 00:00:00 2001 From: nicm Date: Tue, 1 Sep 2015 18:50:16 +0000 Subject: [PATCH 08/17] Fix a spelling error, sesson -> session. --- session.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/session.c b/session.c index 56986497..a929cada 100644 --- a/session.c +++ b/session.c @@ -187,7 +187,7 @@ session_free(unused int fd, unused short events, void *arg) { struct session *s = arg; - log_debug("sesson %s freed (%d references)", s->name, s->references); + log_debug("session %s freed (%d references)", s->name, s->references); if (s->references == 0) { free(s->name); From 364a885b0c8b3bc58396775603c7927e1fb19cee Mon Sep 17 00:00:00 2001 From: nicm Date: Tue, 1 Sep 2015 19:14:43 +0000 Subject: [PATCH 09/17] Pass logging through vis(3). --- log.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/log.c b/log.c index fa26eb4c..ecb9698a 100644 --- a/log.c +++ b/log.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "tmux.h" @@ -66,19 +67,24 @@ log_close(void) void log_vwrite(const char *msg, va_list ap) { - char *fmt; + char *fmt, *out; struct timeval tv; if (log_file == NULL) return; - gettimeofday(&tv, NULL); - if (asprintf(&fmt, "%lld.%06d %s\n", (long long)tv.tv_sec, - (int)tv.tv_usec, msg) == -1) + if (vasprintf(&fmt, msg, ap) == -1) exit(1); - if (vfprintf(log_file, fmt, ap) == -1) + if (stravis(&out, fmt, VIS_OCTAL|VIS_CSTYLE|VIS_TAB|VIS_NL) == -1) + exit(1); + + gettimeofday(&tv, NULL); + if (fprintf(log_file, "%lld.%06d %s\n", (long long)tv.tv_sec, + (int)tv.tv_usec, out) == -1) exit(1); fflush(log_file); + + free(out); free(fmt); } From 66a2720c56328c186784345664ba283a4ca0748c Mon Sep 17 00:00:00 2001 From: nicm Date: Tue, 1 Sep 2015 19:16:00 +0000 Subject: [PATCH 10/17] Log the whole new input buffer once rather than each byte. --- input.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/input.c b/input.c index cfe6b4af..25cfe971 100644 --- a/input.c +++ b/input.c @@ -862,10 +862,12 @@ input_parse(struct window_pane *wp) notify_input(wp, evb); off = 0; + log_debug("%s: %s, %zu bytes: %.*s", __func__, ictx->state->name, len, + (int)len, buf); + /* Parse the input. */ while (off < len) { ictx->ch = buf[off++]; - log_debug("%s: '%c' %s", __func__, ictx->ch, ictx->state->name); /* Find the transition. */ itr = ictx->state->transitions; @@ -1070,7 +1072,7 @@ input_c0_dispatch(struct input_ctx *ictx) struct window_pane *wp = ictx->wp; struct screen *s = sctx->s; - log_debug("%s: '%c", __func__, ictx->ch); + log_debug("%s: '%c'", __func__, ictx->ch); switch (ictx->ch) { case '\000': /* NUL */ From 93b946ee5076495ff815ad1a1d874341cbc70499 Mon Sep 17 00:00:00 2001 From: nicm Date: Tue, 1 Sep 2015 19:50:09 +0000 Subject: [PATCH 11/17] Tweak some error messages/comments. --- input.c | 2 +- server-client.c | 2 +- tty-term.c | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/input.c b/input.c index 25cfe971..1b0c1752 100644 --- a/input.c +++ b/input.c @@ -878,7 +878,7 @@ input_parse(struct window_pane *wp) } if (itr->first == -1 || itr->last == -1) { /* No transition? Eh? */ - fatalx("No transition from state!"); + fatalx("no transition from state"); } /* diff --git a/server-client.c b/server-client.c index 08058ab4..70f5adcb 100644 --- a/server-client.c +++ b/server-client.c @@ -1060,7 +1060,7 @@ server_client_msg_dispatch(struct client *c) s = c->session; if (gettimeofday(&c->activity_time, NULL) != 0) - fatal("gettimeofday"); + fatal("gettimeofday failed"); if (s != NULL) session_update_activity(s, &c->activity_time); diff --git a/tty-term.c b/tty-term.c index 14339de1..f4fd91a8 100644 --- a/tty-term.c +++ b/tty-term.c @@ -560,7 +560,6 @@ tty_term_string(struct tty_term *term, enum tty_code_code code) return (term->codes[code].value.string); } -/* No vtparm. Fucking curses. */ const char * tty_term_string1(struct tty_term *term, enum tty_code_code code, int a) { From a45164f2e023f436d0c9b0f50580a71f2b4b8f87 Mon Sep 17 00:00:00 2001 From: nicm Date: Wed, 2 Sep 2015 17:12:07 +0000 Subject: [PATCH 12/17] Fix indentation of grid_string_cells_fg. --- grid.c | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/grid.c b/grid.c index c339cdc5..93fed05e 100644 --- a/grid.c +++ b/grid.c @@ -395,29 +395,29 @@ grid_string_cells_fg(const struct grid_cell *gc, int *values) values[n++] = gc->fg; } else { switch (gc->fg) { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - values[n++] = gc->fg + 30; - break; - case 8: - values[n++] = 39; - break; - case 90: - case 91: - case 92: - case 93: - case 94: - case 95: - case 96: - case 97: - values[n++] = gc->fg; - break; + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + values[n++] = gc->fg + 30; + break; + case 8: + values[n++] = 39; + break; + case 90: + case 91: + case 92: + case 93: + case 94: + case 95: + case 96: + case 97: + values[n++] = gc->fg; + break; } } return (n); From 8121127606e8c354daa4802177763d2b1f8df81d Mon Sep 17 00:00:00 2001 From: nicm Date: Wed, 2 Sep 2015 17:37:54 +0000 Subject: [PATCH 13/17] We no longer need the terminal service class, so don't bother asking for it. --- tmux.h | 3 --- tty-keys.c | 69 ------------------------------------------------------ tty.c | 9 ------- 3 files changed, 81 deletions(-) diff --git a/tmux.h b/tmux.h index a71d6c2a..9e028194 100644 --- a/tmux.h +++ b/tmux.h @@ -1082,9 +1082,7 @@ LIST_HEAD(tty_terms, tty_term); struct tty { struct client *client; - char *path; - u_int class; u_int sx; u_int sy; @@ -1564,7 +1562,6 @@ void tty_putn(struct tty *, const void *, size_t, u_int); int tty_init(struct tty *, struct client *, int, char *); int tty_resize(struct tty *); int tty_set_size(struct tty *, u_int, u_int); -void tty_set_class(struct tty *, u_int); void tty_start_tty(struct tty *); void tty_stop_tty(struct tty *); void tty_set_title(struct tty *, const char *); diff --git a/tty-keys.c b/tty-keys.c index 75e06526..c1de2ab7 100644 --- a/tty-keys.c +++ b/tty-keys.c @@ -41,7 +41,6 @@ struct tty_key *tty_keys_find1( struct tty_key *tty_keys_find(struct tty *, const char *, size_t, size_t *); void tty_keys_callback(int, short, void *); int tty_keys_mouse(struct tty *, const char *, size_t, size_t *); -int tty_keys_device(struct tty *, const char *, size_t, size_t *); /* Default raw keys. */ struct tty_default_key_raw { @@ -482,17 +481,6 @@ tty_keys_next(struct tty *tty) return (0); log_debug("keys are %zu (%.*s)", len, (int) len, buf); - /* Is this device attributes response? */ - switch (tty_keys_device(tty, buf, len, &size)) { - case 0: /* yes */ - key = KEYC_NONE; - goto complete_key; - case -1: /* no, or not valid */ - break; - case 1: /* partial */ - goto partial_key; - } - /* Is this a mouse key press? */ switch (tty_keys_mouse(tty, buf, len, &size)) { case 0: /* yes */ @@ -794,60 +782,3 @@ tty_keys_mouse(struct tty *tty, const char *buf, size_t len, size_t *size) return (0); } - -/* - * Handle device attributes input. Returns 0 for success, -1 for failure, 1 for - * partial. - */ -int -tty_keys_device(struct tty *tty, const char *buf, size_t len, size_t *size) -{ - u_int i, class; - char tmp[64], *endptr; - - /* - * Primary device attributes are \033[?a;b and secondary are - * \033[>a;b;c. - */ - - *size = 0; - - /* First three bytes are always \033[?. */ - if (buf[0] != '\033') - return (-1); - if (len == 1) - return (1); - if (buf[1] != '[') - return (-1); - if (len == 2) - return (1); - if (buf[2] != '>' && buf[2] != '?') - return (-1); - if (len == 3) - return (1); - - /* Copy the rest up to a 'c'. */ - for (i = 0; i < (sizeof tmp) - 1 && buf[3 + i] != 'c'; i++) { - if (3 + i == len) - return (1); - tmp[i] = buf[3 + i]; - } - if (i == (sizeof tmp) - 1) - return (-1); - tmp[i] = '\0'; - *size = 4 + i; - - /* Only primary is of interest. */ - if (buf[2] != '?') - return (0); - - /* Convert service class. */ - class = strtoul(tmp, &endptr, 10); - if (*endptr != ';') - class = 0; - - log_debug("received service class %u", class); - tty_set_class(tty, class); - - return (0); -} diff --git a/tty.c b/tty.c index 374fb8c6..105a24ed 100644 --- a/tty.c +++ b/tty.c @@ -233,7 +233,6 @@ tty_start_tty(struct tty *tty) tty->flags |= TTY_FOCUS; tty_puts(tty, "\033[?1004h"); } - tty_puts(tty, "\033[c"); } tty->cx = UINT_MAX; @@ -253,14 +252,6 @@ tty_start_tty(struct tty *tty) tty->mouse_drag_release = NULL; } -void -tty_set_class(struct tty *tty, u_int class) -{ - if (tty->class != 0) - return; - tty->class = class; -} - void tty_stop_tty(struct tty *tty) { From 38e3baab2a8f46d910ea5104b48d4c71480d4814 Mon Sep 17 00:00:00 2001 From: nicm Date: Wed, 2 Sep 2015 17:43:25 +0000 Subject: [PATCH 14/17] A one line helper function is a little silly. --- alerts.c | 4 ++-- tmux.h | 1 - tty.c | 6 ------ 3 files changed, 2 insertions(+), 9 deletions(-) diff --git a/alerts.c b/alerts.c index cfdd30e3..5d52f7ad 100644 --- a/alerts.c +++ b/alerts.c @@ -174,7 +174,7 @@ alerts_check_bell(struct session *s, struct winlink *wl) (action == BELL_OTHER && c->session->curw->window != w) || action == BELL_ANY) - tty_bell(&c->tty); + tty_putcode(&c->tty, TTYC_BEL); continue; } if (action == BELL_CURRENT && c->session->curw->window == w) @@ -258,6 +258,6 @@ alerts_ring_bell(struct session *s) TAILQ_FOREACH(c, &clients, entry) { if (c->session == s && !(c->flags & CLIENT_CONTROL)) - tty_bell(&c->tty); + tty_putcode(&c->tty, TTYC_BEL); } } diff --git a/tmux.h b/tmux.h index 9e028194..0223d857 100644 --- a/tmux.h +++ b/tmux.h @@ -1596,7 +1596,6 @@ void tty_cmd_utf8character(struct tty *, const struct tty_ctx *); void tty_cmd_reverseindex(struct tty *, const struct tty_ctx *); void tty_cmd_setselection(struct tty *, const struct tty_ctx *); void tty_cmd_rawstring(struct tty *, const struct tty_ctx *); -void tty_bell(struct tty *); /* tty-term.c */ extern struct tty_terms tty_terms; diff --git a/tty.c b/tty.c index 105a24ed..c4dfde1d 100644 --- a/tty.c +++ b/tty.c @@ -1712,9 +1712,3 @@ tty_default_colours(struct grid_cell *gc, const struct window_pane *wp) } } } - -void -tty_bell(struct tty *tty) -{ - tty_putcode(tty, TTYC_BEL); -} From 6c10fc659a096d2d3514e23b1300c4bf51a122a4 Mon Sep 17 00:00:00 2001 From: nicm Date: Wed, 2 Sep 2015 17:52:57 +0000 Subject: [PATCH 15/17] Log pane which received input data. --- input.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/input.c b/input.c index 1b0c1752..ab56fc38 100644 --- a/input.c +++ b/input.c @@ -862,8 +862,8 @@ input_parse(struct window_pane *wp) notify_input(wp, evb); off = 0; - log_debug("%s: %s, %zu bytes: %.*s", __func__, ictx->state->name, len, - (int)len, buf); + log_debug("%s: %%%u %s, %zu bytes: %.*s", __func__, wp->id, + ictx->state->name, len, (int)len, buf); /* Parse the input. */ while (off < len) { From 82326dcbe2e833476c2b8961d6b8b5c2cee69c0e Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 3 Sep 2015 14:30:23 +0000 Subject: [PATCH 16/17] A couple of style nits. --- format.c | 3 +-- tmux.c | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/format.c b/format.c index ae22a844..20cf0adb 100644 --- a/format.c +++ b/format.c @@ -218,8 +218,7 @@ format_job_get(struct format_tree *ft, const char *cmd) struct format_job fj0, *fj; fj0.cmd = cmd; - if ((fj = RB_FIND(format_job_tree, &format_jobs, &fj0)) == NULL) - { + if ((fj = RB_FIND(format_job_tree, &format_jobs, &fj0)) == NULL) { fj = xcalloc(1, sizeof *fj); fj->cmd = xstrdup(cmd); fj->status = ft->status; diff --git a/tmux.c b/tmux.c index 69097bf9..875e8d72 100644 --- a/tmux.c +++ b/tmux.c @@ -321,8 +321,7 @@ main(int argc, char **argv) free(path); label = xstrdup("default"); } - } - else + } else label = xstrdup("default"); } From aceae73b9a401c0b124a3534079e9c0d998f0dbd Mon Sep 17 00:00:00 2001 From: nicm Date: Fri, 4 Sep 2015 12:02:44 +0000 Subject: [PATCH 17/17] Change wait-for to work when the signal comes before the wait, also use some helper functions and add some logging. --- cmd-wait-for.c | 105 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 70 insertions(+), 35 deletions(-) diff --git a/cmd-wait-for.c b/cmd-wait-for.c index a3e85856..0dce438b 100644 --- a/cmd-wait-for.c +++ b/cmd-wait-for.c @@ -41,6 +41,7 @@ const struct cmd_entry cmd_wait_for_entry = { struct wait_channel { const char *name; int locked; + int woken; TAILQ_HEAD(, cmd_q) waiters; TAILQ_HEAD(, cmd_q) lockers; @@ -69,8 +70,49 @@ enum cmd_retval cmd_wait_for_lock(struct cmd_q *, const char *, enum cmd_retval cmd_wait_for_unlock(struct cmd_q *, const char *, struct wait_channel *); +struct wait_channel *cmd_wait_for_add(const char *); +void cmd_wait_for_remove(struct wait_channel *wc); + +struct wait_channel * +cmd_wait_for_add(const char *name) +{ + struct wait_channel *wc; + + wc = xmalloc(sizeof *wc); + wc->name = xstrdup(name); + + wc->locked = 0; + wc->woken = 0; + + TAILQ_INIT(&wc->waiters); + TAILQ_INIT(&wc->lockers); + + RB_INSERT(wait_channels, &wait_channels, wc); + + log_debug("add wait channel %s", wc->name); + + return (wc); +} + +void +cmd_wait_for_remove(struct wait_channel *wc) +{ + + if (wc->locked) + return; + if (!TAILQ_EMPTY(&wc->waiters) || !wc->woken) + return; + + log_debug("remove wait channel %s", wc->name); + + RB_REMOVE(wait_channels, &wait_channels, wc); + + free((void *)wc->name); + free(wc); +} + enum cmd_retval -cmd_wait_for_exec(struct cmd *self, struct cmd_q *cmdq) +cmd_wait_for_exec(struct cmd *self, unused struct cmd_q *cmdq) { struct args *args = self->args; const char *name = args->argv[0]; @@ -89,15 +131,20 @@ cmd_wait_for_exec(struct cmd *self, struct cmd_q *cmdq) } enum cmd_retval -cmd_wait_for_signal(struct cmd_q *cmdq, const char *name, +cmd_wait_for_signal(unused struct cmd_q *cmdq, const char *name, struct wait_channel *wc) { struct cmd_q *wq, *wq1; - if (wc == NULL || TAILQ_EMPTY(&wc->waiters)) { - cmdq_error(cmdq, "no waiting clients on %s", name); - return (CMD_RETURN_ERROR); + if (wc == NULL) + wc = cmd_wait_for_add(name); + + if (TAILQ_EMPTY(&wc->waiters) && !wc->woken) { + log_debug("signal wait channel %s, no waiters", wc->name); + wc->woken = 1; + return (CMD_RETURN_NORMAL); } + log_debug("signal wait channel %s, with waiters", wc->name); TAILQ_FOREACH_SAFE(wq, &wc->waiters, waitentry, wq1) { TAILQ_REMOVE(&wc->waiters, wq, waitentry); @@ -105,12 +152,7 @@ cmd_wait_for_signal(struct cmd_q *cmdq, const char *name, cmdq_continue(wq); } - if (!wc->locked) { - RB_REMOVE(wait_channels, &wait_channels, wc); - free((void *)wc->name); - free(wc); - } - + cmd_wait_for_remove(wc); return (CMD_RETURN_NORMAL); } @@ -118,19 +160,23 @@ enum cmd_retval cmd_wait_for_wait(struct cmd_q *cmdq, const char *name, struct wait_channel *wc) { - if (cmdq->client == NULL || cmdq->client->session != NULL) { + struct client *c = cmdq->client; + + if (c == NULL || c->session != NULL) { cmdq_error(cmdq, "not able to wait"); return (CMD_RETURN_ERROR); } - if (wc == NULL) { - wc = xmalloc(sizeof *wc); - wc->name = xstrdup(name); - wc->locked = 0; - TAILQ_INIT(&wc->waiters); - TAILQ_INIT(&wc->lockers); - RB_INSERT(wait_channels, &wait_channels, wc); + if (wc == NULL) + wc = cmd_wait_for_add(name); + + if (wc->woken) { + log_debug("wait channel %s already woken (client %d)", wc->name, + c->tty.fd); + cmd_wait_for_remove(wc); + return (CMD_RETURN_NORMAL); } + log_debug("wait channel %s not woken (client %d)", wc->name, c->tty.fd); TAILQ_INSERT_TAIL(&wc->waiters, cmdq, waitentry); cmdq->references++; @@ -147,14 +193,8 @@ cmd_wait_for_lock(struct cmd_q *cmdq, const char *name, return (CMD_RETURN_ERROR); } - if (wc == NULL) { - wc = xmalloc(sizeof *wc); - wc->name = xstrdup(name); - wc->locked = 0; - TAILQ_INIT(&wc->waiters); - TAILQ_INIT(&wc->lockers); - RB_INSERT(wait_channels, &wait_channels, wc); - } + if (wc == NULL) + wc = cmd_wait_for_add(name); if (wc->locked) { TAILQ_INSERT_TAIL(&wc->lockers, cmdq, waitentry); @@ -183,11 +223,7 @@ cmd_wait_for_unlock(struct cmd_q *cmdq, const char *name, cmdq_continue(wq); } else { wc->locked = 0; - if (TAILQ_EMPTY(&wc->waiters)) { - RB_REMOVE(wait_channels, &wait_channels, wc); - free((void *)wc->name); - free(wc); - } + cmd_wait_for_remove(wc); } return (CMD_RETURN_NORMAL); @@ -210,8 +246,7 @@ cmd_wait_for_flush(void) if (!cmdq_free(wq)) cmdq_continue(wq); } - RB_REMOVE(wait_channels, &wait_channels, wc); - free((void *)wc->name); - free(wc); + wc->locked = 0; + cmd_wait_for_remove(wc); } }