@@ -4154,10 +4154,13 @@ wait4pid(pid_t child, waitstatus *status)
return wait_pid;
}
#if defined(FEAT_JOB_CHANNEL) || !defined(USE_SYSTEM) || defined(PROTO)
#if defined(FEAT_JOB_CHANNEL) \
|| !defined (USE_SYSTEM) \
|| (defined (FEAT_GUI) && defined (FEAT_TERMINAL)) \
|| defined (PROTO)
/*
* Parse "cmd" and put the white-separated parts in "argv".
* "argv" is an allocated array with "argc" entries.
* "argv" is an allocated array with "argc" entries and room for 4 more .
* Returns FAIL when out of memory.
*/
int
@@ -4359,8 +4362,121 @@ may_send_sigint(int c UNUSED, pid_t pid UNUSED, pid_t wpid UNUSED)
# endif
}
int
mch_call_shell (
#if !defined(USE_SYSTEM) || (defined(FEAT_GUI) && defined(FEAT_TERMINAL))
static int
build_argv (
char_u *cmd,
char ***argvp,
char_u **sh_tofree,
char_u **shcf_tofree)
{
char **argv = NULL ;
int argc;
*sh_tofree = vim_strsave (p_sh);
if (*sh_tofree == NULL ) /* out of memory */
return FAIL;
if (mch_parse_cmd (*sh_tofree, TRUE , &argv, &argc) == FAIL)
return FAIL;
*argvp = argv;
if (cmd != NULL )
{
char_u *s;
char_u *p;
if (extra_shell_arg != NULL )
argv[argc++] = (char *)extra_shell_arg;
/* Break 'shellcmdflag' into white separated parts. This doesn't
* handle quoted strings, they are very unlikely to appear. */
*shcf_tofree = alloc ((unsigned )STRLEN (p_shcf) + 1 );
if (*shcf_tofree == NULL ) /* out of memory */
return FAIL;
s = *shcf_tofree;
p = p_shcf;
while (*p != NUL)
{
argv[argc++] = (char *)s;
while (*p && *p != ' ' && *p != TAB)
*s++ = *p++;
*s++ = NUL;
p = skipwhite (p);
}
argv[argc++] = (char *)cmd;
}
argv[argc] = NULL ;
return OK;
}
#endif
#if defined(FEAT_GUI) && defined(FEAT_TERMINAL)
/*
* Use a terminal window to run a shell command in.
*/
static int
mch_call_shell_terminal (
char_u *cmd,
int options UNUSED) /* SHELL_*, see vim.h */
{
jobopt_T opt;
char **argv = NULL ;
char_u *tofree1 = NULL ;
char_u *tofree2 = NULL ;
int retval = -1 ;
buf_T *buf;
aco_save_T aco;
oparg_T oa; /* operator arguments */
if (build_argv (cmd, &argv, &tofree1, &tofree2) == FAIL)
goto theend;
init_job_options (&opt);
ch_log (NULL , " starting terminal for system command '%s '" , cmd);
buf = term_start (NULL , argv, &opt, TERM_START_SYSTEM);
/* Find a window to make "buf" curbuf. */
aucmd_prepbuf (&aco, buf);
clear_oparg (&oa);
while (term_use_loop ())
{
if (oa.op_type == OP_NOP && oa.regname == NUL && !VIsual_active)
{
/* If terminal_loop() returns OK we got a key that is handled
* in Normal model. We don't do redrawing anyway. */
if (terminal_loop (TRUE ) == OK)
normal_cmd (&oa, TRUE );
}
else
normal_cmd (&oa, TRUE );
}
retval = 0 ;
ch_log (NULL , " system command finished" );
/* restore curwin/curbuf and a few other things */
aucmd_restbuf (&aco);
wait_return (TRUE );
do_buffer (DOBUF_WIPE, DOBUF_FIRST, FORWARD, buf->b_fnum , TRUE );
theend:
vim_free (argv);
vim_free (tofree1);
vim_free (tofree2);
return retval;
}
#endif
#ifdef USE_SYSTEM
/*
* Use system() to start the shell: simple but slow.
*/
static int
mch_call_shell_system (
char_u *cmd,
int options) /* SHELL_*, see vim.h */
{
@@ -4369,7 +4485,6 @@ mch_call_shell(
char *ofn = NULL ;
#endif
int tmode = cur_tmode;
#ifdef USE_SYSTEM /* use system() to start the shell: simple but slow */
char_u *newcmd; /* only needed for unix */
int x;
@@ -4443,14 +4558,23 @@ mch_call_shell(
restore_clipboard ();
# endif
return x;
}
#else /* USE_SYSTEM */ /* don't use system(), use fork()/exec() */
#else /* USE_SYSTEM */
# define EXEC_FAILED 122 /* Exit code when shell didn't execute. Don't use
127, some shells use that already */
# define OPEN_NULL_FAILED 123 /* Exit code if /dev/null can't be opened */
char_u *newcmd;
/*
* Don't use system(), use fork()/exec().
*/
static int
mch_call_shell_fork (
char_u *cmd,
int options) /* SHELL_*, see vim.h */
{
int tmode = cur_tmode;
pid_t pid;
pid_t wpid = 0 ;
pid_t wait_pid = 0 ;
@@ -4461,8 +4585,8 @@ mch_call_shell(
# endif
int retval = -1 ;
char **argv = NULL ;
int argc ;
char_u *p_shcf_copy = NULL ;
char_u *tofree1 = NULL ;
char_u *tofree2 = NULL ;
int i;
char_u *p;
int pty_master_fd = -1 ; /* for pty's */
@@ -4474,44 +4598,13 @@ mch_call_shell(
int pipe_error = FALSE ;
int did_settmode = FALSE ; /* settmode(TMODE_RAW) called */
newcmd = vim_strsave (p_sh);
if (newcmd == NULL ) /* out of memory */
goto error;
out_flush ();
if (options & SHELL_COOKED)
settmode (TMODE_COOK); /* set to normal mode */
if (mch_parse_cmd (newcmd, TRUE , &argv , &argc ) == FAIL)
if (build_argv (cmd, &argv , &tofree1 , &tofree2 ) == FAIL)
goto error;
if (cmd != NULL )
{
char_u *s;
if (extra_shell_arg != NULL )
argv[argc++] = (char *)extra_shell_arg;
/* Break 'shellcmdflag' into white separated parts. This doesn't
* handle quoted strings, they are very unlikely to appear. */
p_shcf_copy = alloc ((unsigned )STRLEN (p_shcf) + 1 );
if (p_shcf_copy == NULL ) /* out of memory */
goto error;
s = p_shcf_copy;
p = p_shcf;
while (*p != NUL)
{
argv[argc++] = (char *)s;
while (*p && *p != ' ' && *p != TAB)
*s++ = *p++;
*s++ = NUL;
p = skipwhite (p);
}
argv[argc++] = (char *)cmd;
}
argv[argc] = NULL ;
/*
* For the GUI, when writing the output into the buffer and when reading
* input from the buffer: Try using a pseudo-tty to get the stdin/stdout
@@ -5319,8 +5412,6 @@ mch_call_shell(
MSG_PUTS (_ (" \n Command terminated\n " ));
}
}
vim_free (argv);
vim_free (p_shcf_copy);
error:
if (!did_settmode)
@@ -5329,11 +5420,28 @@ mch_call_shell(
# ifdef FEAT_TITLE
resettitle ();
# endif
vim_free (newcmd);
vim_free (argv);
vim_free (tofree1);
vim_free (tofree2);
return retval;
}
#endif /* USE_SYSTEM */
int
mch_call_shell (
char_u *cmd,
int options) /* SHELL_*, see vim.h */
{
#if defined(FEAT_GUI) && defined(FEAT_TERMINAL)
if (gui.in_use && vim_strchr (p_go, GO_TERMINAL) != NULL )
return mch_call_shell_terminal (cmd, options);
#endif
#ifdef USE_SYSTEM
return mch_call_shell_system (cmd, options);
#else
return mch_call_shell_fork (cmd, options);
#endif
}
#if defined(FEAT_JOB_CHANNEL) || defined(PROTO)