mirror of
https://github.com/vim/vim.git
synced 2025-09-25 03:54:15 -04:00
patch 8.1.0890: pty allocation wrong if using file for out channel
Problem: Pty allocation wrong if using file for out channel and using null for in channel and null for error channel. Solution: Correct using use_file_for_out in condition. (Ozaki Kiichi, closes #3917)
This commit is contained in:
@@ -4196,13 +4196,19 @@ set_default_child_environment(int is_terminal)
|
|||||||
/*
|
/*
|
||||||
* Open a PTY, with FD for the master and slave side.
|
* Open a PTY, with FD for the master and slave side.
|
||||||
* When failing "pty_master_fd" and "pty_slave_fd" are -1.
|
* When failing "pty_master_fd" and "pty_slave_fd" are -1.
|
||||||
* When successful both file descriptors are stored.
|
* When successful both file descriptors are stored and the allocated pty name
|
||||||
|
* is stored in both "*name1" and "*name2".
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
open_pty(int *pty_master_fd, int *pty_slave_fd, char_u **namep)
|
open_pty(int *pty_master_fd, int *pty_slave_fd, char_u **name1, char_u **name2)
|
||||||
{
|
{
|
||||||
char *tty_name;
|
char *tty_name;
|
||||||
|
|
||||||
|
if (name1 != NULL)
|
||||||
|
*name1 = NULL;
|
||||||
|
if (name2 != NULL)
|
||||||
|
*name2 = NULL;
|
||||||
|
|
||||||
*pty_master_fd = mch_openpty(&tty_name); // open pty
|
*pty_master_fd = mch_openpty(&tty_name); // open pty
|
||||||
if (*pty_master_fd >= 0)
|
if (*pty_master_fd >= 0)
|
||||||
{
|
{
|
||||||
@@ -4219,8 +4225,13 @@ open_pty(int *pty_master_fd, int *pty_slave_fd, char_u **namep)
|
|||||||
close(*pty_master_fd);
|
close(*pty_master_fd);
|
||||||
*pty_master_fd = -1;
|
*pty_master_fd = -1;
|
||||||
}
|
}
|
||||||
else if (namep != NULL)
|
else
|
||||||
*namep = vim_strsave((char_u *)tty_name);
|
{
|
||||||
|
if (name1 != NULL)
|
||||||
|
*name1 = vim_strsave((char_u *)tty_name);
|
||||||
|
if (name2 != NULL)
|
||||||
|
*name2 = vim_strsave((char_u *)tty_name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -4513,7 +4524,7 @@ mch_call_shell_fork(
|
|||||||
* If the slave can't be opened, close the master pty.
|
* If the slave can't be opened, close the master pty.
|
||||||
*/
|
*/
|
||||||
if (p_guipty && !(options & (SHELL_READ|SHELL_WRITE)))
|
if (p_guipty && !(options & (SHELL_READ|SHELL_WRITE)))
|
||||||
open_pty(&pty_master_fd, &pty_slave_fd, NULL);
|
open_pty(&pty_master_fd, &pty_slave_fd, NULL, NULL);
|
||||||
/*
|
/*
|
||||||
* If not opening a pty or it didn't work, try using pipes.
|
* If not opening a pty or it didn't work, try using pipes.
|
||||||
*/
|
*/
|
||||||
@@ -5352,13 +5363,10 @@ mch_job_start(char **argv, job_T *job, jobopt_T *options, int is_terminal)
|
|||||||
|
|
||||||
if (options->jo_pty
|
if (options->jo_pty
|
||||||
&& (!(use_file_for_in || use_null_for_in)
|
&& (!(use_file_for_in || use_null_for_in)
|
||||||
|| !(use_file_for_in || use_null_for_out)
|
|| !(use_file_for_out || use_null_for_out)
|
||||||
|| !(use_out_for_err || use_file_for_err || use_null_for_err)))
|
|| !(use_out_for_err || use_file_for_err || use_null_for_err)))
|
||||||
{
|
open_pty(&pty_master_fd, &pty_slave_fd,
|
||||||
open_pty(&pty_master_fd, &pty_slave_fd, &job->jv_tty_out);
|
&job->jv_tty_out, &job->jv_tty_in);
|
||||||
if (job->jv_tty_out != NULL)
|
|
||||||
job->jv_tty_in = vim_strsave(job->jv_tty_out);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TODO: without the channel feature connect the child to /dev/null? */
|
/* TODO: without the channel feature connect the child to /dev/null? */
|
||||||
/* Open pipes for stdin, stdout, stderr. */
|
/* Open pipes for stdin, stdout, stderr. */
|
||||||
@@ -5834,9 +5842,7 @@ mch_create_pty_channel(job_T *job, jobopt_T *options)
|
|||||||
int pty_slave_fd = -1;
|
int pty_slave_fd = -1;
|
||||||
channel_T *channel;
|
channel_T *channel;
|
||||||
|
|
||||||
open_pty(&pty_master_fd, &pty_slave_fd, &job->jv_tty_out);
|
open_pty(&pty_master_fd, &pty_slave_fd, &job->jv_tty_out, &job->jv_tty_in);
|
||||||
if (job->jv_tty_out != NULL)
|
|
||||||
job->jv_tty_in = vim_strsave(job->jv_tty_out);
|
|
||||||
close(pty_slave_fd);
|
close(pty_slave_fd);
|
||||||
|
|
||||||
channel = add_channel();
|
channel = add_channel();
|
||||||
|
@@ -2040,3 +2040,55 @@ func Test_job_exitval_and_termsig()
|
|||||||
call assert_equal(-1, info.exitval)
|
call assert_equal(-1, info.exitval)
|
||||||
call assert_equal("term", info.termsig)
|
call assert_equal("term", info.termsig)
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
func Test_job_tty_in_out()
|
||||||
|
if !has('job') || !has('unix')
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
call writefile(['test'], 'Xtestin')
|
||||||
|
let in_opts = [{},
|
||||||
|
\ {'in_io': 'null'},
|
||||||
|
\ {'in_io': 'file', 'in_name': 'Xtestin'}]
|
||||||
|
let out_opts = [{},
|
||||||
|
\ {'out_io': 'null'},
|
||||||
|
\ {'out_io': 'file', 'out_name': 'Xtestout'}]
|
||||||
|
let err_opts = [{},
|
||||||
|
\ {'err_io': 'null'},
|
||||||
|
\ {'err_io': 'file', 'err_name': 'Xtesterr'},
|
||||||
|
\ {'err_io': 'out'}]
|
||||||
|
let opts = []
|
||||||
|
|
||||||
|
for in_opt in in_opts
|
||||||
|
let x = copy(in_opt)
|
||||||
|
for out_opt in out_opts
|
||||||
|
call extend(x, out_opt)
|
||||||
|
for err_opt in err_opts
|
||||||
|
call extend(x, err_opt)
|
||||||
|
let opts += [extend({'pty': 1}, x)]
|
||||||
|
endfor
|
||||||
|
endfor
|
||||||
|
endfor
|
||||||
|
|
||||||
|
for opt in opts
|
||||||
|
let job = job_start('echo', opt)
|
||||||
|
let info = job_info(job)
|
||||||
|
let msg = printf('option={"in_io": "%s", "out_io": "%s", "err_io": "%s"}',
|
||||||
|
\ get(opt, 'in_io', 'tty'),
|
||||||
|
\ get(opt, 'out_io', 'tty'),
|
||||||
|
\ get(opt, 'err_io', 'tty'))
|
||||||
|
|
||||||
|
if !has_key(opt, 'in_io') || !has_key(opt, 'out_io') || !has_key(opt, 'err_io')
|
||||||
|
call assert_notequal('', info.tty_in, msg)
|
||||||
|
else
|
||||||
|
call assert_equal('', info.tty_in, msg)
|
||||||
|
endif
|
||||||
|
call assert_equal(info.tty_in, info.tty_out, msg)
|
||||||
|
|
||||||
|
call WaitForAssert({-> assert_equal('dead', job_status(job))})
|
||||||
|
endfor
|
||||||
|
|
||||||
|
call delete('Xtestin')
|
||||||
|
call delete('Xtestout')
|
||||||
|
call delete('Xtesterr')
|
||||||
|
endfunc
|
||||||
|
@@ -783,6 +783,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
890,
|
||||||
/**/
|
/**/
|
||||||
889,
|
889,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user