=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/tmux/cmd-if-shell.c,v retrieving revision 1.60 retrieving revision 1.61 diff -c -r1.60 -r1.61 *** src/usr.bin/tmux/cmd-if-shell.c 2018/08/27 11:03:34 1.60 --- src/usr.bin/tmux/cmd-if-shell.c 2019/05/23 11:13:30 1.61 *************** *** 1,4 **** ! /* $OpenBSD: cmd-if-shell.c,v 1.60 2018/08/27 11:03:34 nicm Exp $ */ /* * Copyright (c) 2009 Tiago Cunha --- 1,4 ---- ! /* $OpenBSD: cmd-if-shell.c,v 1.61 2019/05/23 11:13:30 nicm Exp $ */ /* * Copyright (c) 2009 Tiago Cunha *************** *** 49,56 **** }; struct cmd_if_shell_data { ! char *file; ! u_int line; char *cmd_if; char *cmd_else; --- 49,55 ---- }; struct cmd_if_shell_data { ! struct cmd_parse_input input; char *cmd_if; char *cmd_else; *************** *** 64,114 **** cmd_if_shell_exec(struct cmd *self, struct cmdq_item *item) { struct args *args = self->args; ! struct cmdq_shared *shared = item->shared; struct cmd_if_shell_data *cdata; ! char *shellcmd, *cmd, *cause; ! struct cmd_list *cmdlist; struct cmdq_item *new_item; struct client *c = cmd_find_client(item, NULL, 1); struct session *s = item->target.s; struct winlink *wl = item->target.wl; struct window_pane *wp = item->target.wp; shellcmd = format_single(item, args->argv[0], c, s, wl, wp); if (args_has(args, 'F')) { - cmd = NULL; if (*shellcmd != '0' && *shellcmd != '\0') cmd = args->argv[1]; else if (args->argc == 3) cmd = args->argv[2]; free(shellcmd); if (cmd == NULL) return (CMD_RETURN_NORMAL); ! cmdlist = cmd_string_parse(cmd, NULL, 0, &cause); ! if (cmdlist == NULL) { ! if (cause != NULL) { ! cmdq_error(item, "%s", cause); ! free(cause); ! } return (CMD_RETURN_ERROR); } - new_item = cmdq_get_command(cmdlist, NULL, &shared->mouse, 0); - cmdq_insert_after(item, new_item); - cmd_list_free(cmdlist); return (CMD_RETURN_NORMAL); } cdata = xcalloc(1, sizeof *cdata); - if (self->file != NULL) { - cdata->file = xstrdup(self->file); - cdata->line = self->line; - } cdata->cmd_if = xstrdup(args->argv[1]); if (args->argc == 3) cdata->cmd_else = xstrdup(args->argv[2]); else cdata->cmd_else = NULL; cdata->client = item->client; if (cdata->client != NULL) --- 63,124 ---- cmd_if_shell_exec(struct cmd *self, struct cmdq_item *item) { struct args *args = self->args; ! struct mouse_event *m = &item->shared->mouse; struct cmd_if_shell_data *cdata; ! char *shellcmd, *cmd; struct cmdq_item *new_item; struct client *c = cmd_find_client(item, NULL, 1); struct session *s = item->target.s; struct winlink *wl = item->target.wl; struct window_pane *wp = item->target.wp; + struct cmd_parse_input pi; + struct cmd_parse_result *pr; shellcmd = format_single(item, args->argv[0], c, s, wl, wp); if (args_has(args, 'F')) { if (*shellcmd != '0' && *shellcmd != '\0') cmd = args->argv[1]; else if (args->argc == 3) cmd = args->argv[2]; + else + cmd = NULL; free(shellcmd); if (cmd == NULL) return (CMD_RETURN_NORMAL); ! ! memset(&pi, 0, sizeof pi); ! if (self->file != NULL) ! pi.file = self->file; ! pi.line = self->line; ! pi.item = item; ! pi.c = c; ! cmd_find_copy_state(&pi.fs, &item->target); ! ! pr = cmd_parse_from_string(cmd, &pi); ! switch (pr->status) { ! case CMD_PARSE_EMPTY: ! break; ! case CMD_PARSE_ERROR: ! cmdq_error(item, "%s", pr->error); ! free(pr->error); return (CMD_RETURN_ERROR); + case CMD_PARSE_SUCCESS: + new_item = cmdq_get_command(pr->cmdlist, NULL, m, 0); + cmdq_insert_after(item, new_item); + cmd_list_free(pr->cmdlist); + break; } return (CMD_RETURN_NORMAL); } cdata = xcalloc(1, sizeof *cdata); cdata->cmd_if = xstrdup(args->argv[1]); if (args->argc == 3) cdata->cmd_else = xstrdup(args->argv[2]); else cdata->cmd_else = NULL; + memcpy(&cdata->mouse, m, sizeof cdata->mouse); cdata->client = item->client; if (cdata->client != NULL) *************** *** 118,125 **** cdata->item = item; else cdata->item = NULL; - memcpy(&cdata->mouse, &shared->mouse, sizeof cdata->mouse); if (job_run(shellcmd, s, server_client_get_cwd(item->client, s), NULL, cmd_if_shell_callback, cmd_if_shell_free, cdata, 0) == NULL) { cmdq_error(item, "failed to run command: %s", shellcmd); --- 128,144 ---- cdata->item = item; else cdata->item = NULL; + memset(&cdata->input, 0, sizeof cdata->input); + if (self->file != NULL) + cdata->input.file = xstrdup(self->file); + cdata->input.line = self->line; + cdata->input.item = cdata->item; + cdata->input.c = c; + if (cdata->input.c != NULL) + cdata->input.c->references++; + cmd_find_copy_state(&cdata->input.fs, &item->target); + if (job_run(shellcmd, s, server_client_get_cwd(item->client, s), NULL, cmd_if_shell_callback, cmd_if_shell_free, cdata, 0) == NULL) { cmdq_error(item, "failed to run command: %s", shellcmd); *************** *** 139,149 **** { struct cmd_if_shell_data *cdata = job_get_data(job); struct client *c = cdata->client; ! struct cmd_list *cmdlist; struct cmdq_item *new_item; ! char *cause, *cmd, *file = cdata->file; ! u_int line = cdata->line; int status; status = job_get_status(job); if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) --- 158,168 ---- { struct cmd_if_shell_data *cdata = job_get_data(job); struct client *c = cdata->client; ! struct mouse_event *m = &cdata->mouse; struct cmdq_item *new_item; ! char *cmd; int status; + struct cmd_parse_result *pr; status = job_get_status(job); if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) *************** *** 153,169 **** if (cmd == NULL) goto out; ! cmdlist = cmd_string_parse(cmd, file, line, &cause); ! if (cmdlist == NULL) { ! if (cause != NULL && cdata->item != NULL) ! cmdq_error(cdata->item, "%s", cause); ! free(cause); new_item = NULL; ! } else { ! new_item = cmdq_get_command(cmdlist, NULL, &cdata->mouse, 0); ! cmd_list_free(cmdlist); } - if (new_item != NULL) { if (cdata->item == NULL) cmdq_append(c, new_item); --- 172,191 ---- if (cmd == NULL) goto out; ! pr = cmd_parse_from_string(cmd, &cdata->input); ! switch (pr->status) { ! case CMD_PARSE_EMPTY: new_item = NULL; ! break; ! case CMD_PARSE_ERROR: ! new_item = cmdq_get_error(pr->error); ! free(pr->error); ! break; ! case CMD_PARSE_SUCCESS: ! new_item = cmdq_get_command(pr->cmdlist, NULL, m, 0); ! cmd_list_free(pr->cmdlist); ! break; } if (new_item != NULL) { if (cdata->item == NULL) cmdq_append(c, new_item); *************** *** 187,192 **** free(cdata->cmd_else); free(cdata->cmd_if); ! free(cdata->file); free(cdata); } --- 209,217 ---- free(cdata->cmd_else); free(cdata->cmd_if); ! if (cdata->input.c != NULL) ! server_client_unref(cdata->input.c); ! free((void *)cdata->input.file); ! free(cdata); }