diff options
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/tmux/cmd-attach-session.c | 4 | ||||
-rw-r--r-- | usr.bin/tmux/hooks.c | 79 | ||||
-rw-r--r-- | usr.bin/tmux/server-client.c | 6 | ||||
-rw-r--r-- | usr.bin/tmux/tmux.h | 10 |
4 files changed, 83 insertions, 16 deletions
diff --git a/usr.bin/tmux/cmd-attach-session.c b/usr.bin/tmux/cmd-attach-session.c index a80bf51259b..43ad4b7b85d 100644 --- a/usr.bin/tmux/cmd-attach-session.c +++ b/usr.bin/tmux/cmd-attach-session.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-attach-session.c,v 1.57 2015/12/14 00:31:54 nicm Exp $ */ +/* $OpenBSD: cmd-attach-session.c,v 1.58 2015/12/15 13:43:07 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -144,7 +144,7 @@ cmd_attach_session(struct cmd_q *cmdq, int dflag, int rflag, const char *cflag, if (~c->flags & CLIENT_CONTROL) proc_send(c->peer, MSG_READY, -1, NULL, 0); - hooks_run(c->session->hooks, "client-attached", c); + hooks_run(c->session->hooks, c, "client-attached"); cmdq->client_exit = 0; } recalculate_sizes(); diff --git a/usr.bin/tmux/hooks.c b/usr.bin/tmux/hooks.c index 8bc72cb1012..e113d64ec2b 100644 --- a/usr.bin/tmux/hooks.c +++ b/usr.bin/tmux/hooks.c @@ -1,4 +1,4 @@ -/* $OpenBSD: hooks.c,v 1.2 2015/12/11 15:46:57 nicm Exp $ */ +/* $OpenBSD: hooks.c,v 1.3 2015/12/15 13:43:07 nicm Exp $ */ /* * Copyright (c) 2012 Thomas Adam <thomas@xteddy.org> @@ -34,6 +34,7 @@ RB_GENERATE(hooks_tree, hook, entry, hooks_cmp); static struct hook *hooks_find1(struct hooks *, const char *); static void hooks_free1(struct hooks *, struct hook *); +static void hooks_emptyfn(struct cmd_q *); static int hooks_cmp(struct hook *hook1, struct hook *hook2) @@ -132,18 +133,78 @@ hooks_find(struct hooks *hooks, const char *name) return (hook); } -void -hooks_run(struct hooks *hooks, const char *name, struct client *c) +static void +hooks_emptyfn(struct cmd_q *hooks_cmdq) +{ + struct cmd_q *cmdq = hooks_cmdq->data; + + if (cmdq != NULL) { + if (hooks_cmdq->client_exit >= 0) + cmdq->client_exit = hooks_cmdq->client_exit; + if (!cmdq_free(cmdq)) + cmdq_continue(cmdq); + } + cmdq_free(hooks_cmdq); +} + +int +hooks_run(struct hooks *hooks, struct client *c, const char *fmt, ...) { struct hook *hook; - struct cmd_q *cmdq; + struct cmd_q *hooks_cmdq; + va_list ap; + char *name; + + va_start(ap, fmt); + xvasprintf(&name, fmt, ap); + va_end(ap); hook = hooks_find(hooks, name); - if (hook == NULL) - return; + if (hook == NULL) { + free(name); + return (-1); + } log_debug("running hook %s", name); + free(name); + + hooks_cmdq = cmdq_new(c); + hooks_cmdq->flags |= CMD_Q_NOHOOKS; + hooks_cmdq->parent = NULL; + + cmdq_run(hooks_cmdq, hook->cmdlist, NULL); + cmdq_free(hooks_cmdq); + return (0); +} + +int +hooks_wait(struct hooks *hooks, struct cmd_q *cmdq, const char *fmt, ...) +{ + struct hook *hook; + struct cmd_q *hooks_cmdq; + va_list ap; + char *name; + + va_start(ap, fmt); + xvasprintf(&name, fmt, ap); + va_end(ap); + + hook = hooks_find(hooks, name); + if (hook == NULL) { + free(name); + return (-1); + } + log_debug("running hook %s (parent %p)", name, cmdq); + free(name); + + hooks_cmdq = cmdq_new(cmdq->client); + hooks_cmdq->flags |= CMD_Q_NOHOOKS; + hooks_cmdq->parent = cmdq; + + hooks_cmdq->emptyfn = hooks_emptyfn; + hooks_cmdq->data = cmdq; - cmdq = cmdq_new(c); - cmdq_run(cmdq, hook->cmdlist, NULL); - cmdq_free(cmdq); + if (cmdq != NULL) + cmdq->references++; + cmdq_run(hooks_cmdq, hook->cmdlist, NULL); + return (0); } diff --git a/usr.bin/tmux/server-client.c b/usr.bin/tmux/server-client.c index 23242cce847..e31e8788050 100644 --- a/usr.bin/tmux/server-client.c +++ b/usr.bin/tmux/server-client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: server-client.c,v 1.178 2015/12/12 18:32:24 nicm Exp $ */ +/* $OpenBSD: server-client.c,v 1.179 2015/12/15 13:43:07 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> @@ -283,7 +283,7 @@ server_client_detach(struct client *c, enum msgtype msgtype) if (s == NULL) return; - hooks_run(c->session->hooks, "client-detached", c); + hooks_run(c->session->hooks, c, "client-detached"); proc_send_s(c->peer, msgtype, s->name); } @@ -1027,7 +1027,7 @@ server_client_dispatch(struct imsg *imsg, void *arg) server_redraw_client(c); } if (c->session != NULL) - hooks_run(c->session->hooks, "client-resized", c); + hooks_run(c->session->hooks, c, "client-resized"); break; case MSG_EXITING: if (datalen != 0) diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h index e26f91ed6d8..14e4ee4bb84 100644 --- a/usr.bin/tmux/tmux.h +++ b/usr.bin/tmux/tmux.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tmux.h,v 1.611 2015/12/15 00:00:01 nicm Exp $ */ +/* $OpenBSD: tmux.h,v 1.612 2015/12/15 13:43:07 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -1368,6 +1368,8 @@ struct cmd_q { int references; int flags; #define CMD_Q_DEAD 0x1 +#define CMD_Q_REENTRY 0x2 +#define CMD_Q_NOHOOKS 0x4 struct client *client; int client_exit; @@ -1375,6 +1377,7 @@ struct cmd_q { struct cmd_q_items queue; struct cmd_q_item *item; struct cmd *cmd; + struct cmd_q *parent; struct cmd_state state; @@ -1581,7 +1584,10 @@ void hooks_add(struct hooks *, const char *, struct cmd_list *); void hooks_copy(struct hooks *, struct hooks *); void hooks_remove(struct hooks *, const char *); struct hook *hooks_find(struct hooks *, const char *); -void hooks_run(struct hooks *, const char *, struct client *); +int printflike(3, 4) hooks_run(struct hooks *, struct client *, const char *, + ...); +int printflike(3, 4) hooks_wait(struct hooks *, struct cmd_q *, const char *, + ...); /* mode-key.c */ extern const struct mode_key_table mode_key_tables[]; |