version 1.69, 2020/06/12 10:31:12 |
version 1.70, 2021/01/01 08:36:51 |
|
|
.name = "run-shell", |
.name = "run-shell", |
.alias = "run", |
.alias = "run", |
|
|
.args = { "bd:t:", 0, 1 }, |
.args = { "bd:Ct:", 0, 1 }, |
.usage = "[-b] [-d delay] " CMD_TARGET_PANE_USAGE " [shell-command]", |
.usage = "[-bC] [-d delay] " CMD_TARGET_PANE_USAGE " [shell-command]", |
|
|
.target = { 't', CMD_FIND_PANE, CMD_FIND_CANFAIL }, |
.target = { 't', CMD_FIND_PANE, CMD_FIND_CANFAIL }, |
|
|
|
|
}; |
}; |
|
|
struct cmd_run_shell_data { |
struct cmd_run_shell_data { |
|
struct client *client; |
char *cmd; |
char *cmd; |
|
int shell; |
char *cwd; |
char *cwd; |
struct cmdq_item *item; |
struct cmdq_item *item; |
struct session *s; |
struct session *s; |
int wp_id; |
int wp_id; |
struct event timer; |
struct event timer; |
int flags; |
int flags; |
|
struct cmd_parse_input pi; |
}; |
}; |
|
|
static void |
static void |
|
|
struct args *args = cmd_get_args(self); |
struct args *args = cmd_get_args(self); |
struct cmd_find_state *target = cmdq_get_target(item); |
struct cmd_find_state *target = cmdq_get_target(item); |
struct cmd_run_shell_data *cdata; |
struct cmd_run_shell_data *cdata; |
|
struct client *tc = cmdq_get_target_client(item); |
struct session *s = target->s; |
struct session *s = target->s; |
struct window_pane *wp = target->wp; |
struct window_pane *wp = target->wp; |
const char *delay; |
const char *delay; |
double d; |
double d; |
struct timeval tv; |
struct timeval tv; |
char *end; |
char *end; |
|
int wait = !args_has(args, 'b'); |
|
|
|
if ((delay = args_get(args, 'd')) != NULL) { |
|
d = strtod(delay, &end); |
|
if (*end != '\0') { |
|
cmdq_error(item, "invalid delay time: %s", delay); |
|
return (CMD_RETURN_ERROR); |
|
} |
|
} else if (args->argc == 0) |
|
return (CMD_RETURN_NORMAL); |
|
|
cdata = xcalloc(1, sizeof *cdata); |
cdata = xcalloc(1, sizeof *cdata); |
if (args->argc != 0) |
if (args->argc != 0) |
cdata->cmd = format_single_from_target(item, args->argv[0]); |
cdata->cmd = format_single_from_target(item, args->argv[0]); |
|
|
|
cdata->shell = !args_has(args, 'C'); |
|
if (!cdata->shell) { |
|
memset(&cdata->pi, 0, sizeof cdata->pi); |
|
cmd_get_source(self, &cdata->pi.file, &cdata->pi.line); |
|
if (wait) |
|
cdata->pi.item = item; |
|
cdata->pi.c = tc; |
|
cmd_find_copy_state(&cdata->pi.fs, target); |
|
} |
|
|
if (args_has(args, 't') && wp != NULL) |
if (args_has(args, 't') && wp != NULL) |
cdata->wp_id = wp->id; |
cdata->wp_id = wp->id; |
else |
else |
cdata->wp_id = -1; |
cdata->wp_id = -1; |
|
|
if (!args_has(args, 'b')) |
if (wait) { |
|
cdata->client = cmdq_get_client(item); |
cdata->item = item; |
cdata->item = item; |
else |
} else { |
|
cdata->client = tc; |
cdata->flags |= JOB_NOWAIT; |
cdata->flags |= JOB_NOWAIT; |
|
} |
|
if (cdata->client != NULL) |
|
cdata->client->references++; |
|
|
cdata->cwd = xstrdup(server_client_get_cwd(cmdq_get_client(item), s)); |
cdata->cwd = xstrdup(server_client_get_cwd(cmdq_get_client(item), s)); |
|
|
cdata->s = s; |
cdata->s = s; |
if (s != NULL) |
if (s != NULL) |
session_add_ref(s, __func__); |
session_add_ref(s, __func__); |
|
|
evtimer_set(&cdata->timer, cmd_run_shell_timer, cdata); |
evtimer_set(&cdata->timer, cmd_run_shell_timer, cdata); |
|
if (delay != NULL) { |
if ((delay = args_get(args, 'd')) != NULL) { |
|
d = strtod(delay, &end); |
|
if (*end != '\0') { |
|
cmdq_error(item, "invalid delay time: %s", delay); |
|
cmd_run_shell_free(cdata); |
|
return (CMD_RETURN_ERROR); |
|
} |
|
timerclear(&tv); |
timerclear(&tv); |
tv.tv_sec = (time_t)d; |
tv.tv_sec = (time_t)d; |
tv.tv_usec = (d - (double)tv.tv_sec) * 1000000U; |
tv.tv_usec = (d - (double)tv.tv_sec) * 1000000U; |
evtimer_add(&cdata->timer, &tv); |
evtimer_add(&cdata->timer, &tv); |
} else |
} else |
cmd_run_shell_timer(-1, 0, cdata); |
event_active(&cdata->timer, EV_TIMEOUT, 1); |
|
|
if (args_has(args, 'b')) |
if (!wait) |
return (CMD_RETURN_NORMAL); |
return (CMD_RETURN_NORMAL); |
return (CMD_RETURN_WAIT); |
return (CMD_RETURN_WAIT); |
} |
} |
|
|
cmd_run_shell_timer(__unused int fd, __unused short events, void* arg) |
cmd_run_shell_timer(__unused int fd, __unused short events, void* arg) |
{ |
{ |
struct cmd_run_shell_data *cdata = arg; |
struct cmd_run_shell_data *cdata = arg; |
|
struct client *c = cdata->client; |
|
const char *cmd = cdata->cmd; |
|
char *error; |
|
struct cmdq_item *item = cdata->item; |
|
enum cmd_parse_status status; |
|
|
if (cdata->cmd != NULL) { |
if (cmd != NULL && cdata->shell) { |
if (job_run(cdata->cmd, cdata->s, cdata->cwd, NULL, |
if (job_run(cmd, cdata->s, cdata->cwd, NULL, |
cmd_run_shell_callback, cmd_run_shell_free, cdata, |
cmd_run_shell_callback, cmd_run_shell_free, cdata, |
cdata->flags, -1, -1) == NULL) |
cdata->flags, -1, -1) == NULL) |
cmd_run_shell_free(cdata); |
cmd_run_shell_free(cdata); |
} else { |
return; |
if (cdata->item != NULL) |
|
cmdq_continue(cdata->item); |
|
cmd_run_shell_free(cdata); |
|
} |
} |
|
|
|
if (cmd != NULL) { |
|
if (item != NULL) { |
|
status = cmd_parse_and_insert(cmd, &cdata->pi, item, |
|
cmdq_get_state(item), &error); |
|
} else { |
|
status = cmd_parse_and_append(cmd, &cdata->pi, c, NULL, |
|
&error); |
|
} |
|
if (status == CMD_PARSE_ERROR) { |
|
cmdq_error(cdata->item, "%s", error); |
|
free(error); |
|
} |
|
} |
|
|
|
if (cdata->item != NULL) |
|
cmdq_continue(cdata->item); |
|
cmd_run_shell_free(cdata); |
} |
} |
|
|
static void |
static void |
|
|
evtimer_del(&cdata->timer); |
evtimer_del(&cdata->timer); |
if (cdata->s != NULL) |
if (cdata->s != NULL) |
session_remove_ref(cdata->s, __func__); |
session_remove_ref(cdata->s, __func__); |
|
if (cdata->client != NULL) |
|
server_client_unref(cdata->client); |
free(cdata->cwd); |
free(cdata->cwd); |
free(cdata->cmd); |
free(cdata->cmd); |
free(cdata); |
free(cdata); |