summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2019-11-03 23:37:12 +0100
committerBram Moolenaar <Bram@vim.org>2019-11-03 23:37:12 +0100
commit197c6b7da3ad4c3e3942a553f5dbc35722a4a349 (patch)
treef4369612e764bf0ba88fcac151d3d43bb866dd06 /src
parent30efcf3d26bd14af71cd306c4c5f9e789a7130c9 (diff)
patch 8.1.2251: ":term command" may not work without a shellv8.1.2251
Problem: ":term command" may not work without a shell. Solution: Add the ++shell option to :term. (closes #3340)
Diffstat (limited to 'src')
-rw-r--r--src/os_unix.c10
-rw-r--r--src/proto/os_unix.pro1
-rw-r--r--src/terminal.c33
-rw-r--r--src/testdir/test_terminal.vim12
-rw-r--r--src/version.c2
5 files changed, 48 insertions, 10 deletions
diff --git a/src/os_unix.c b/src/os_unix.c
index e8fe90a1c0..6fa0702747 100644
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -4299,10 +4299,10 @@ may_send_sigint(int c UNUSED, pid_t pid UNUSED, pid_t wpid UNUSED)
# endif
}
-#if !defined(USE_SYSTEM) || (defined(FEAT_GUI) && defined(FEAT_TERMINAL))
+#if !defined(USE_SYSTEM) || defined(FEAT_TERMINAL) || defined(PROTO)
- static int
-build_argv(
+ int
+unix_build_argv(
char_u *cmd,
char ***argvp,
char_u **sh_tofree,
@@ -4369,7 +4369,7 @@ mch_call_shell_terminal(
aco_save_T aco;
oparg_T oa; /* operator arguments */
- if (build_argv(cmd, &argv, &tofree1, &tofree2) == FAIL)
+ if (unix_build_argv(cmd, &argv, &tofree1, &tofree2) == FAIL)
goto theend;
init_job_options(&opt);
@@ -4546,7 +4546,7 @@ mch_call_shell_fork(
if (options & SHELL_COOKED)
settmode(TMODE_COOK); /* set to normal mode */
- if (build_argv(cmd, &argv, &tofree1, &tofree2) == FAIL)
+ if (unix_build_argv(cmd, &argv, &tofree1, &tofree2) == FAIL)
goto error;
/*
diff --git a/src/proto/os_unix.pro b/src/proto/os_unix.pro
index 86e12a0f69..14cde4a135 100644
--- a/src/proto/os_unix.pro
+++ b/src/proto/os_unix.pro
@@ -59,6 +59,7 @@ int mch_get_shellsize(void);
int mch_report_winsize(int fd, int rows, int cols);
void mch_set_shellsize(void);
void mch_new_shellsize(void);
+int unix_build_argv(char_u *cmd, char ***argvp, char_u **sh_tofree, char_u **shcf_tofree);
int mch_call_shell(char_u *cmd, int options);
void mch_job_start(char **argv, job_T *job, jobopt_T *options, int is_terminal);
char *mch_job_status(job_T *job);
diff --git a/src/terminal.c b/src/terminal.c
index 10343fe20e..290d7c7baf 100644
--- a/src/terminal.c
+++ b/src/terminal.c
@@ -703,6 +703,7 @@ ex_terminal(exarg_T *eap)
{
typval_T argvar[2];
jobopt_T opt;
+ int opt_shell = FALSE;
char_u *cmd;
char_u *tofree = NULL;
@@ -738,6 +739,8 @@ ex_terminal(exarg_T *eap)
opt.jo_hidden = 1;
else if (OPTARG_HAS("norestore"))
opt.jo_term_norestore = 1;
+ else if (OPTARG_HAS("shell"))
+ opt_shell = TRUE;
else if (OPTARG_HAS("kill") && ep != NULL)
{
opt.jo_set2 |= JO2_TERM_KILL;
@@ -831,10 +834,30 @@ ex_terminal(exarg_T *eap)
opt.jo_in_bot = eap->line2;
}
- argvar[0].v_type = VAR_STRING;
- argvar[0].vval.v_string = cmd;
- argvar[1].v_type = VAR_UNKNOWN;
- term_start(argvar, NULL, &opt, eap->forceit ? TERM_START_FORCEIT : 0);
+ if (opt_shell && tofree == NULL)
+ {
+#ifdef UNIX
+ char **argv = NULL;
+ char_u *tofree1 = NULL;
+ char_u *tofree2 = NULL;
+
+ // :term ++shell command
+ if (unix_build_argv(cmd, &argv, &tofree1, &tofree2) == OK)
+ term_start(NULL, argv, &opt, eap->forceit ? TERM_START_FORCEIT : 0);
+ vim_free(tofree1);
+ vim_free(tofree2);
+#else
+ emsg(_("E279: Sorry, ++shell is not supported on this system"));
+#endif
+ }
+ else
+ {
+ argvar[0].v_type = VAR_STRING;
+ argvar[0].vval.v_string = cmd;
+ argvar[1].v_type = VAR_UNKNOWN;
+ term_start(argvar, NULL, &opt, eap->forceit ? TERM_START_FORCEIT : 0);
+ }
+
vim_free(tofree);
theend:
@@ -6474,7 +6497,7 @@ failed:
term_and_job_init(
term_T *term,
typval_T *argvar,
- char **argv UNUSED,
+ char **argv,
jobopt_T *opt,
jobopt_T *orig_opt)
{
diff --git a/src/testdir/test_terminal.vim b/src/testdir/test_terminal.vim
index 9aae680b4f..1a126b9e10 100644
--- a/src/testdir/test_terminal.vim
+++ b/src/testdir/test_terminal.vim
@@ -2214,6 +2214,18 @@ func Test_terminal_altscreen()
call delete('Xtext')
endfunc
+func Test_terminal_shell_option()
+ CheckUnix
+ " exec is a shell builtin command, should fail without a shell.
+ term exec ls runtest.vim
+ call WaitForAssert({-> assert_match('job failed', term_getline(bufnr(), 1))})
+ bwipe!
+
+ term ++shell exec ls runtest.vim
+ call WaitForAssert({-> assert_match('runtest.vim', term_getline(bufnr(), 1))})
+ bwipe!
+endfunc
+
func Test_terminal_setapi_and_call()
if !CanRunVimInTerminal()
return
diff --git a/src/version.c b/src/version.c
index 5a4a1e4851..767cbec8bd 100644
--- a/src/version.c
+++ b/src/version.c
@@ -742,6 +742,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 2251,
+/**/
2250,
/**/
2249,