diff options
Diffstat (limited to 'cmd.c')
-rw-r--r-- | cmd.c | 186 |
1 files changed, 103 insertions, 83 deletions
@@ -112,6 +112,7 @@ const struct cmd_entry *cmd_table[] = { &cmd_switch_client_entry, &cmd_unbind_key_entry, &cmd_unlink_window_entry, + &cmd_wait_for_entry, NULL }; @@ -121,13 +122,14 @@ struct session *cmd_choose_session(int); struct client *cmd_choose_client(struct clients *); struct client *cmd_lookup_client(const char *); struct session *cmd_lookup_session(const char *, int *); +struct session *cmd_lookup_session_id(const char *); struct winlink *cmd_lookup_window(struct session *, const char *, int *); int cmd_lookup_index(struct session *, const char *, int *); struct window_pane *cmd_lookup_paneid(const char *); struct winlink *cmd_lookup_winlink_windowid(struct session *, const char *); struct window *cmd_lookup_windowid(const char *); -struct session *cmd_window_session(struct cmd_ctx *, - struct window *, struct winlink **); +struct session *cmd_window_session(struct cmd_q *, struct window *, + struct winlink **); struct winlink *cmd_find_window_offset(const char *, struct session *, int *); int cmd_find_index_offset(const char *, struct session *, int *); struct window_pane *cmd_find_pane_offset(const char *, struct winlink *); @@ -205,7 +207,7 @@ cmd_free_argv(int argc, char **argv) } struct cmd * -cmd_parse(int argc, char **argv, char **cause) +cmd_parse(int argc, char **argv, const char *file, u_int line, char **cause) { const struct cmd_entry **entryp, *entry; struct cmd *cmd; @@ -255,9 +257,14 @@ cmd_parse(int argc, char **argv, char **cause) if (entry->check != NULL && entry->check(args) != 0) goto usage; - cmd = xmalloc(sizeof *cmd); + cmd = xcalloc(1, sizeof *cmd); cmd->entry = entry; cmd->args = args; + + if (file != NULL) + cmd->file = xstrdup(file); + cmd->line = line; + return (cmd); ambiguous: @@ -281,19 +288,6 @@ usage: return (NULL); } -enum cmd_retval -cmd_exec(struct cmd *cmd, struct cmd_ctx *ctx) -{ - return (cmd->entry->exec(cmd, ctx)); -} - -void -cmd_free(struct cmd *cmd) -{ - args_free(cmd->args); - free(cmd); -} - size_t cmd_print(struct cmd *cmd, char *buf, size_t len) { @@ -319,31 +313,33 @@ cmd_print(struct cmd *cmd, char *buf, size_t len) * session from all sessions. */ struct session * -cmd_current_session(struct cmd_ctx *ctx, int prefer_unattached) +cmd_current_session(struct cmd_q *cmdq, int prefer_unattached) { - struct msg_command_data *data = ctx->msgdata; - struct client *c = ctx->cmdclient; + struct msg_command_data *data = cmdq->msgdata; + struct client *c = cmdq->client; struct session *s; struct sessionslist ss; struct winlink *wl; struct window_pane *wp; + const char *path; int found; - if (ctx->curclient != NULL && ctx->curclient->session != NULL) - return (ctx->curclient->session); + if (c != NULL && c->session != NULL) + return (c->session); /* - * If the name of the calling client's pty is know, build a list of the - * sessions that contain it and if any choose either the first or the - * newest. + * If the name of the calling client's pty is known, build a list of + * the sessions that contain it and if any choose either the first or + * the newest. */ - if (c != NULL && c->tty.path != NULL) { + path = c == NULL ? NULL : c->tty.path; + if (path != NULL) { ARRAY_INIT(&ss); RB_FOREACH(s, sessions, &sessions) { found = 0; RB_FOREACH(wl, winlinks, &s->windows) { TAILQ_FOREACH(wp, &wl->window->panes, entry) { - if (strcmp(wp->tty, c->tty.path) == 0) { + if (strcmp(wp->tty, path) == 0) { found = 1; break; } @@ -362,8 +358,8 @@ cmd_current_session(struct cmd_ctx *ctx, int prefer_unattached) } /* Use the session from the TMUX environment variable. */ - if (data != NULL && data->pid == getpid() && data->idx != -1) { - s = session_find_by_index(data->idx); + if (data != NULL && data->pid == getpid() && data->session_id != -1) { + s = session_find_by_id(data->session_id); if (s != NULL) return (s); } @@ -434,21 +430,21 @@ cmd_choose_session_list(struct sessionslist *ss) * then of all clients. */ struct client * -cmd_current_client(struct cmd_ctx *ctx) +cmd_current_client(struct cmd_q *cmdq) { struct session *s; struct client *c; struct clients cc; u_int i; - if (ctx->curclient != NULL) - return (ctx->curclient); + if (cmdq->client != NULL && cmdq->client->session != NULL) + return (cmdq->client); /* * No current client set. Find the current session and return the * newest of its clients. */ - s = cmd_current_session(ctx, 0); + s = cmd_current_session(cmdq, 0); if (s != NULL && !(s->flags & SESSION_UNATTACHED)) { ARRAY_INIT(&cc); for (i = 0; i < ARRAY_LENGTH(&clients); i++) { @@ -493,15 +489,19 @@ cmd_choose_client(struct clients *cc) /* Find the target client or report an error and return NULL. */ struct client * -cmd_find_client(struct cmd_ctx *ctx, const char *arg) +cmd_find_client(struct cmd_q *cmdq, const char *arg, int quiet) { struct client *c; char *tmparg; size_t arglen; /* A NULL argument means the current client. */ - if (arg == NULL) - return (cmd_current_client(ctx)); + if (arg == NULL) { + c = cmd_current_client(cmdq); + if (c == NULL && !quiet) + cmdq_error(cmdq, "no clients"); + return (c); + } tmparg = xstrdup(arg); /* Trim a single trailing colon if any. */ @@ -513,8 +513,8 @@ cmd_find_client(struct cmd_ctx *ctx, const char *arg) c = cmd_lookup_client(tmparg); /* If no client found, report an error. */ - if (c == NULL) - ctx->error(ctx, "client not found: %s", tmparg); + if (c == NULL && !quiet) + cmdq_error(cmdq, "client not found: %s", tmparg); free(tmparg); return (c); @@ -533,7 +533,7 @@ cmd_lookup_client(const char *name) for (i = 0; i < ARRAY_LENGTH(&clients); i++) { c = ARRAY_ITEM(&clients, i); - if (c == NULL || c->session == NULL) + if (c == NULL || c->session == NULL || c->tty.path == NULL) continue; path = c->tty.path; @@ -551,6 +551,21 @@ cmd_lookup_client(const char *name) return (NULL); } +/* Find the target session or report an error and return NULL. */ +struct session * +cmd_lookup_session_id(const char *arg) +{ + char *endptr; + long id; + + if (arg[0] != '$') + return (NULL); + id = strtol(arg + 1, &endptr, 10); + if (arg[1] != '\0' && *endptr == '\0') + return (session_find_by_id(id)); + return (NULL); +} + /* Lookup a session by name. If no session is found, NULL is returned. */ struct session * cmd_lookup_session(const char *name, int *ambiguous) @@ -559,6 +574,10 @@ cmd_lookup_session(const char *name, int *ambiguous) *ambiguous = 0; + /* Look for $id first. */ + if ((s = cmd_lookup_session_id(name)) != NULL) + return (s); + /* * Look for matches. First look for exact matches - session names must * be unique so an exact match can't be ambigious and can just be @@ -716,14 +735,14 @@ cmd_lookup_windowid(const char *arg) /* Find session and winlink for window. */ struct session * -cmd_window_session(struct cmd_ctx *ctx, struct window *w, struct winlink **wlp) +cmd_window_session(struct cmd_q *cmdq, struct window *w, struct winlink **wlp) { struct session *s; struct sessionslist ss; struct winlink *wl; /* If this window is in the current session, return that winlink. */ - s = cmd_current_session(ctx, 0); + s = cmd_current_session(cmdq, 0); if (s != NULL) { wl = winlink_find_by_window(&s->windows, w); if (wl != NULL) { @@ -748,7 +767,7 @@ cmd_window_session(struct cmd_ctx *ctx, struct window *w, struct winlink **wlp) /* Find the target session or report an error and return NULL. */ struct session * -cmd_find_session(struct cmd_ctx *ctx, const char *arg, int prefer_unattached) +cmd_find_session(struct cmd_q *cmdq, const char *arg, int prefer_unattached) { struct session *s; struct window_pane *wp; @@ -760,13 +779,13 @@ cmd_find_session(struct cmd_ctx *ctx, const char *arg, int prefer_unattached) /* A NULL argument means the current session. */ if (arg == NULL) - return (cmd_current_session(ctx, prefer_unattached)); + return (cmd_current_session(cmdq, prefer_unattached)); /* Lookup as pane id or window id. */ if ((wp = cmd_lookup_paneid(arg)) != NULL) - return (cmd_window_session(ctx, wp->window, NULL)); + return (cmd_window_session(cmdq, wp->window, NULL)); if ((w = cmd_lookup_windowid(arg)) != NULL) - return (cmd_window_session(ctx, w, NULL)); + return (cmd_window_session(cmdq, w, NULL)); /* Trim a single trailing colon if any. */ tmparg = xstrdup(arg); @@ -777,7 +796,7 @@ cmd_find_session(struct cmd_ctx *ctx, const char *arg, int prefer_unattached) /* An empty session name is the current session. */ if (*tmparg == '\0') { free(tmparg); - return (cmd_current_session(ctx, prefer_unattached)); + return (cmd_current_session(cmdq, prefer_unattached)); } /* Find the session, if any. */ @@ -790,9 +809,9 @@ cmd_find_session(struct cmd_ctx *ctx, const char *arg, int prefer_unattached) /* If no session found, report an error. */ if (s == NULL) { if (ambiguous) - ctx->error(ctx, "more than one session: %s", tmparg); + cmdq_error(cmdq, "more than one session: %s", tmparg); else - ctx->error(ctx, "session not found: %s", tmparg); + cmdq_error(cmdq, "session not found: %s", tmparg); } free(tmparg); @@ -801,7 +820,7 @@ cmd_find_session(struct cmd_ctx *ctx, const char *arg, int prefer_unattached) /* Find the target session and window or report an error and return NULL. */ struct winlink * -cmd_find_window(struct cmd_ctx *ctx, const char *arg, struct session **sp) +cmd_find_window(struct cmd_q *cmdq, const char *arg, struct session **sp) { struct session *s; struct winlink *wl; @@ -814,8 +833,8 @@ cmd_find_window(struct cmd_ctx *ctx, const char *arg, struct session **sp) * Find the current session. There must always be a current session, if * it can't be found, report an error. */ - if ((s = cmd_current_session(ctx, 0)) == NULL) { - ctx->error(ctx, "can't establish current session"); + if ((s = cmd_current_session(cmdq, 0)) == NULL) { + cmdq_error(cmdq, "can't establish current session"); return (NULL); } @@ -828,7 +847,7 @@ cmd_find_window(struct cmd_ctx *ctx, const char *arg, struct session **sp) /* Lookup as pane id. */ if ((wp = cmd_lookup_paneid(arg)) != NULL) { - s = cmd_window_session(ctx, wp->window, &wl); + s = cmd_window_session(cmdq, wp->window, &wl); if (sp != NULL) *sp = s; return (wl); @@ -909,17 +928,17 @@ lookup_session: no_session: if (ambiguous) - ctx->error(ctx, "multiple sessions: %s", arg); + cmdq_error(cmdq, "multiple sessions: %s", arg); else - ctx->error(ctx, "session not found: %s", arg); + cmdq_error(cmdq, "session not found: %s", arg); free(sessptr); return (NULL); not_found: if (ambiguous) - ctx->error(ctx, "multiple windows: %s", arg); + cmdq_error(cmdq, "multiple windows: %s", arg); else - ctx->error(ctx, "window not found: %s", arg); + cmdq_error(cmdq, "window not found: %s", arg); free(sessptr); return (NULL); } @@ -951,7 +970,7 @@ cmd_find_window_offset(const char *winptr, struct session *s, int *ambiguous) * example if it is going to be created). */ int -cmd_find_index(struct cmd_ctx *ctx, const char *arg, struct session **sp) +cmd_find_index(struct cmd_q *cmdq, const char *arg, struct session **sp) { struct session *s; struct winlink *wl; @@ -963,8 +982,8 @@ cmd_find_index(struct cmd_ctx *ctx, const char *arg, struct session **sp) * Find the current session. There must always be a current session, if * it can't be found, report an error. */ - if ((s = cmd_current_session(ctx, 0)) == NULL) { - ctx->error(ctx, "can't establish current session"); + if ((s = cmd_current_session(cmdq, 0)) == NULL) { + cmdq_error(cmdq, "can't establish current session"); return (-2); } @@ -1047,25 +1066,25 @@ lookup_session: no_session: if (ambiguous) - ctx->error(ctx, "multiple sessions: %s", arg); + cmdq_error(cmdq, "multiple sessions: %s", arg); else - ctx->error(ctx, "session not found: %s", arg); + cmdq_error(cmdq, "session not found: %s", arg); free(sessptr); return (-2); invalid_index: if (ambiguous) goto not_found; - ctx->error(ctx, "invalid index: %s", arg); + cmdq_error(cmdq, "invalid index: %s", arg); free(sessptr); return (-2); not_found: if (ambiguous) - ctx->error(ctx, "multiple windows: %s", arg); + cmdq_error(cmdq, "multiple windows: %s", arg); else - ctx->error(ctx, "window not found: %s", arg); + cmdq_error(cmdq, "window not found: %s", arg); free(sessptr); return (-2); } @@ -1102,7 +1121,7 @@ cmd_find_index_offset(const char *winptr, struct session *s, int *ambiguous) * such as mysession:mywindow.0. */ struct winlink * -cmd_find_pane(struct cmd_ctx *ctx, +cmd_find_pane(struct cmd_q *cmdq, const char *arg, struct session **sp, struct window_pane **wpp) { struct session *s; @@ -1112,8 +1131,8 @@ cmd_find_pane(struct cmd_ctx *ctx, u_int idx; /* Get the current session. */ - if ((s = cmd_current_session(ctx, 0)) == NULL) { - ctx->error(ctx, "can't establish current session"); + if ((s = cmd_current_session(cmdq, 0)) == NULL) { + cmdq_error(cmdq, "can't establish current session"); return (NULL); } if (sp != NULL) @@ -1127,7 +1146,7 @@ cmd_find_pane(struct cmd_ctx *ctx, /* Lookup as pane id. */ if ((*wpp = cmd_lookup_paneid(arg)) != NULL) { - s = cmd_window_session(ctx, (*wpp)->window, &wl); + s = cmd_window_session(cmdq, (*wpp)->window, &wl); if (sp != NULL) *sp = s; return (wl); @@ -1142,7 +1161,7 @@ cmd_find_pane(struct cmd_ctx *ctx, winptr[period - arg] = '\0'; if (*winptr == '\0') wl = s->curw; - else if ((wl = cmd_find_window(ctx, winptr, sp)) == NULL) + else if ((wl = cmd_find_window(cmdq, winptr, sp)) == NULL) goto error; /* Find the pane section and look it up. */ @@ -1166,7 +1185,7 @@ cmd_find_pane(struct cmd_ctx *ctx, lookup_string: /* Try pane string description. */ if ((*wpp = window_find_string(wl->window, paneptr)) == NULL) { - ctx->error(ctx, "can't find pane: %s", paneptr); + cmdq_error(cmdq, "can't find pane: %s", paneptr); goto error; } @@ -1191,7 +1210,7 @@ lookup_window: return (s->curw); /* Try as a window and use the active pane. */ - if ((wl = cmd_find_window(ctx, arg, sp)) != NULL) + if ((wl = cmd_find_window(cmdq, arg, sp)) != NULL) *wpp = wl->window->active; return (wl); @@ -1221,14 +1240,14 @@ cmd_find_pane_offset(const char *paneptr, struct winlink *wl) /* Replace the first %% or %idx in template by s. */ char * -cmd_template_replace(char *template, const char *s, int idx) +cmd_template_replace(const char *template, const char *s, int idx) { - char ch; - char *buf, *ptr; - int replaced; - size_t len; + char ch, *buf; + const char *ptr; + int replaced; + size_t len; - if (strstr(template, "%") == NULL) + if (strchr(template, '%') == NULL) return (xstrdup(template)); buf = xmalloc(1); @@ -1269,8 +1288,9 @@ cmd_template_replace(char *template, const char *s, int idx) * directory. */ const char * -cmd_get_default_path(struct cmd_ctx *ctx, const char *cwd) +cmd_get_default_path(struct cmd_q *cmdq, const char *cwd) { + struct client *c = cmdq->client; struct session *s; struct environ_entry *envent; const char *root; @@ -1280,7 +1300,7 @@ cmd_get_default_path(struct cmd_ctx *ctx, const char *cwd) size_t skip; static char path[MAXPATHLEN]; - if ((s = cmd_current_session(ctx, 0)) == NULL) + if ((s = cmd_current_session(cmdq, 0)) == NULL) return (NULL); if (cwd == NULL) @@ -1310,10 +1330,10 @@ cmd_get_default_path(struct cmd_ctx *ctx, const char *cwd) return (cwd); } else { /* Empty or relative path. */ - if (ctx->cmdclient != NULL && ctx->cmdclient->cwd != NULL) - root = ctx->cmdclient->cwd; - else if (ctx->curclient != NULL && s->curw != NULL) - root = osdep_get_cwd(s->curw->window->active->fd); + if (c != NULL && c->session == NULL && c->cwd != NULL) + root = c->cwd; + else if (s->curw != NULL) + root = get_proc_cwd(s->curw->window->active->fd); else return (s->cwd); skip = 0; |