mirror of
https://github.com/vim/vim.git
synced 2025-09-24 03:44:06 -04:00
patch 7.4.1514
Problem: Channel output to file not implemented yet. Solution: Implement it for Unix.
This commit is contained in:
@@ -5046,13 +5046,18 @@ mch_start_job(char **argv, job_T *job, jobopt_T *options UNUSED)
|
|||||||
int fd_err[2]; /* for stderr */
|
int fd_err[2]; /* for stderr */
|
||||||
channel_T *channel = NULL;
|
channel_T *channel = NULL;
|
||||||
int use_file_for_in = options->jo_io[PART_IN] == JIO_FILE;
|
int use_file_for_in = options->jo_io[PART_IN] == JIO_FILE;
|
||||||
|
int use_file_for_out = options->jo_io[PART_OUT] == JIO_FILE;
|
||||||
|
int use_file_for_err = options->jo_io[PART_ERR] == JIO_FILE;
|
||||||
int use_out_for_err = options->jo_io[PART_ERR] == JIO_OUT;
|
int use_out_for_err = options->jo_io[PART_ERR] == JIO_OUT;
|
||||||
|
|
||||||
/* default is to fail */
|
/* default is to fail */
|
||||||
job->jv_status = JOB_FAILED;
|
job->jv_status = JOB_FAILED;
|
||||||
fd_in[0] = -1;
|
fd_in[0] = -1;
|
||||||
|
fd_in[1] = -1;
|
||||||
fd_out[0] = -1;
|
fd_out[0] = -1;
|
||||||
|
fd_out[1] = -1;
|
||||||
fd_err[0] = -1;
|
fd_err[0] = -1;
|
||||||
|
fd_err[1] = -1;
|
||||||
|
|
||||||
/* 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. */
|
||||||
@@ -5069,9 +5074,33 @@ mch_start_job(char **argv, job_T *job, jobopt_T *options UNUSED)
|
|||||||
}
|
}
|
||||||
else if (pipe(fd_in) < 0)
|
else if (pipe(fd_in) < 0)
|
||||||
goto failed;
|
goto failed;
|
||||||
if (pipe(fd_out) < 0)
|
|
||||||
|
if (use_file_for_out)
|
||||||
|
{
|
||||||
|
char_u *fname = options->jo_io_name[PART_OUT];
|
||||||
|
|
||||||
|
fd_out[1] = mch_open((char *)fname, O_WRONLY | O_CREAT | O_TRUNC, 0644);
|
||||||
|
if (fd_out[1] < 0)
|
||||||
|
{
|
||||||
|
EMSG2(_(e_notopen), fname);
|
||||||
goto failed;
|
goto failed;
|
||||||
if (!use_out_for_err && pipe(fd_err) < 0)
|
}
|
||||||
|
}
|
||||||
|
else if (pipe(fd_out) < 0)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
|
if (use_file_for_err)
|
||||||
|
{
|
||||||
|
char_u *fname = options->jo_io_name[PART_ERR];
|
||||||
|
|
||||||
|
fd_err[1] = mch_open((char *)fname, O_WRONLY | O_CREAT | O_TRUNC, 0600);
|
||||||
|
if (fd_err[1] < 0)
|
||||||
|
{
|
||||||
|
EMSG2(_(e_notopen), fname);
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!use_out_for_err && pipe(fd_err) < 0)
|
||||||
goto failed;
|
goto failed;
|
||||||
|
|
||||||
channel = add_channel();
|
channel = add_channel();
|
||||||
@@ -5117,6 +5146,7 @@ mch_start_job(char **argv, job_T *job, jobopt_T *options UNUSED)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (!use_file_for_err)
|
||||||
close(fd_err[0]);
|
close(fd_err[0]);
|
||||||
close(2);
|
close(2);
|
||||||
ignored = dup(fd_err[1]);
|
ignored = dup(fd_err[1]);
|
||||||
@@ -5124,6 +5154,7 @@ mch_start_job(char **argv, job_T *job, jobopt_T *options UNUSED)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* set up stdout for the child */
|
/* set up stdout for the child */
|
||||||
|
if (!use_file_for_out)
|
||||||
close(fd_out[0]);
|
close(fd_out[0]);
|
||||||
close(1);
|
close(1);
|
||||||
ignored = dup(fd_out[1]);
|
ignored = dup(fd_out[1]);
|
||||||
@@ -5148,13 +5179,15 @@ mch_start_job(char **argv, job_T *job, jobopt_T *options UNUSED)
|
|||||||
/* child stdin, stdout and stderr */
|
/* child stdin, stdout and stderr */
|
||||||
if (!use_file_for_in)
|
if (!use_file_for_in)
|
||||||
close(fd_in[0]);
|
close(fd_in[0]);
|
||||||
|
if (!use_file_for_out)
|
||||||
close(fd_out[1]);
|
close(fd_out[1]);
|
||||||
if (!use_out_for_err)
|
if (!use_out_for_err && !use_file_for_err)
|
||||||
close(fd_err[1]);
|
close(fd_err[1]);
|
||||||
channel_set_pipes(channel,
|
channel_set_pipes(channel,
|
||||||
use_file_for_in ? INVALID_FD : fd_in[1],
|
use_file_for_in ? INVALID_FD : fd_in[1],
|
||||||
fd_out[0],
|
use_file_for_out ? INVALID_FD : fd_out[0],
|
||||||
use_out_for_err ? INVALID_FD : fd_err[0]);
|
use_out_for_err || use_file_for_err
|
||||||
|
? INVALID_FD : fd_err[0]);
|
||||||
channel_set_job(channel, job, options);
|
channel_set_job(channel, job, options);
|
||||||
# ifdef FEAT_GUI
|
# ifdef FEAT_GUI
|
||||||
channel_gui_register(channel);
|
channel_gui_register(channel);
|
||||||
@@ -5168,21 +5201,17 @@ failed: ;
|
|||||||
if (channel != NULL)
|
if (channel != NULL)
|
||||||
channel_free(channel);
|
channel_free(channel);
|
||||||
if (fd_in[0] >= 0)
|
if (fd_in[0] >= 0)
|
||||||
{
|
|
||||||
close(fd_in[0]);
|
close(fd_in[0]);
|
||||||
if (!use_file_for_in)
|
if (fd_in[1] >= 0)
|
||||||
close(fd_in[1]);
|
close(fd_in[1]);
|
||||||
}
|
|
||||||
if (fd_out[0] >= 0)
|
if (fd_out[0] >= 0)
|
||||||
{
|
|
||||||
close(fd_out[0]);
|
close(fd_out[0]);
|
||||||
|
if (fd_out[1] >= 0)
|
||||||
close(fd_out[1]);
|
close(fd_out[1]);
|
||||||
}
|
|
||||||
if (fd_err[0] >= 0)
|
if (fd_err[0] >= 0)
|
||||||
{
|
|
||||||
close(fd_err[0]);
|
close(fd_err[0]);
|
||||||
|
if (fd_err[1] >= 0)
|
||||||
close(fd_err[1]);
|
close(fd_err[1]);
|
||||||
}
|
|
||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -555,6 +555,97 @@ func Test_nl_read_file()
|
|||||||
endtry
|
endtry
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
func Test_nl_write_out_file()
|
||||||
|
if !has('job')
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
" TODO: make this work for MS-Windows
|
||||||
|
if !has('unix')
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
call ch_log('Test_nl_write_out_file()')
|
||||||
|
let job = job_start(s:python . " test_channel_pipe.py",
|
||||||
|
\ {'out-io': 'file', 'out-name': 'Xoutput'})
|
||||||
|
call assert_equal("run", job_status(job))
|
||||||
|
try
|
||||||
|
let handle = job_getchannel(job)
|
||||||
|
call ch_sendraw(handle, "echo line one\n")
|
||||||
|
call ch_sendraw(handle, "echo line two\n")
|
||||||
|
call ch_sendraw(handle, "double this\n")
|
||||||
|
for i in range(50)
|
||||||
|
sleep 10m
|
||||||
|
if len(readfile('Xoutput')) > 2
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
call assert_equal(['line one', 'line two', 'this', 'AND this'], readfile('Xoutput'))
|
||||||
|
finally
|
||||||
|
call job_stop(job)
|
||||||
|
call delete('Xoutput')
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_nl_write_err_file()
|
||||||
|
if !has('job')
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
" TODO: make this work for MS-Windows
|
||||||
|
if !has('unix')
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
call ch_log('Test_nl_write_err_file()')
|
||||||
|
let job = job_start(s:python . " test_channel_pipe.py",
|
||||||
|
\ {'err-io': 'file', 'err-name': 'Xoutput'})
|
||||||
|
call assert_equal("run", job_status(job))
|
||||||
|
try
|
||||||
|
let handle = job_getchannel(job)
|
||||||
|
call ch_sendraw(handle, "echoerr line one\n")
|
||||||
|
call ch_sendraw(handle, "echoerr line two\n")
|
||||||
|
call ch_sendraw(handle, "doubleerr this\n")
|
||||||
|
for i in range(50)
|
||||||
|
sleep 10m
|
||||||
|
if len(readfile('Xoutput')) > 2
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
call assert_equal(['line one', 'line two', 'this', 'AND this'], readfile('Xoutput'))
|
||||||
|
finally
|
||||||
|
call job_stop(job)
|
||||||
|
call delete('Xoutput')
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_nl_write_both_file()
|
||||||
|
if !has('job')
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
" TODO: make this work for MS-Windows
|
||||||
|
if !has('unix')
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
call ch_log('Test_nl_write_both_file()')
|
||||||
|
let job = job_start(s:python . " test_channel_pipe.py",
|
||||||
|
\ {'out-io': 'file', 'out-name': 'Xoutput', 'err-io': 'out'})
|
||||||
|
call assert_equal("run", job_status(job))
|
||||||
|
try
|
||||||
|
let handle = job_getchannel(job)
|
||||||
|
call ch_sendraw(handle, "echoerr line one\n")
|
||||||
|
call ch_sendraw(handle, "echo line two\n")
|
||||||
|
call ch_sendraw(handle, "double this\n")
|
||||||
|
call ch_sendraw(handle, "doubleerr that\n")
|
||||||
|
for i in range(50)
|
||||||
|
sleep 10m
|
||||||
|
if len(readfile('Xoutput')) > 5
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
call assert_equal(['line one', 'line two', 'this', 'AND this', 'that', 'AND that'], readfile('Xoutput'))
|
||||||
|
finally
|
||||||
|
call job_stop(job)
|
||||||
|
call delete('Xoutput')
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
func Test_pipe_to_buffer()
|
func Test_pipe_to_buffer()
|
||||||
if !has('job')
|
if !has('job')
|
||||||
return
|
return
|
||||||
|
@@ -21,10 +21,13 @@ if __name__ == "__main__":
|
|||||||
if typed.startswith("echo "):
|
if typed.startswith("echo "):
|
||||||
print(typed[5:-1])
|
print(typed[5:-1])
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
if typed.startswith("echoerr"):
|
|
||||||
print(typed[8:-1], file=sys.stderr)
|
|
||||||
sys.stderr.flush()
|
|
||||||
if typed.startswith("double "):
|
if typed.startswith("double "):
|
||||||
print(typed[7:-1] + "\nAND " + typed[7:-1])
|
print(typed[7:-1] + "\nAND " + typed[7:-1])
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
|
if typed.startswith("echoerr "):
|
||||||
|
print(typed[8:-1], file=sys.stderr)
|
||||||
|
sys.stderr.flush()
|
||||||
|
if typed.startswith("doubleerr "):
|
||||||
|
print(typed[10:-1] + "\nAND " + typed[10:-1], file=sys.stderr)
|
||||||
|
sys.stderr.flush()
|
||||||
|
|
||||||
|
@@ -743,6 +743,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 */
|
||||||
|
/**/
|
||||||
|
1514,
|
||||||
/**/
|
/**/
|
||||||
1513,
|
1513,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user