mirror of
https://github.com/vim/vim.git
synced 2025-09-23 03:43:49 -04:00
patch 7.4.1518
Problem: Channel with disconnected in/out/err is not supported. Solution: Implement it for Unix.
This commit is contained in:
@@ -5045,11 +5045,17 @@ mch_start_job(char **argv, job_T *job, jobopt_T *options UNUSED)
|
||||
int fd_out[2]; /* for stdout */
|
||||
int fd_err[2]; /* for stderr */
|
||||
channel_T *channel = NULL;
|
||||
int use_null_for_in = options->jo_io[PART_IN] == JIO_NULL;
|
||||
int use_null_for_out = options->jo_io[PART_OUT] == JIO_NULL;
|
||||
int use_null_for_err = options->jo_io[PART_ERR] == JIO_NULL;
|
||||
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;
|
||||
|
||||
if (use_out_for_err && use_null_for_out)
|
||||
use_null_for_err = TRUE;
|
||||
|
||||
/* default is to fail */
|
||||
job->jv_status = JOB_FAILED;
|
||||
fd_in[0] = -1;
|
||||
@@ -5072,7 +5078,7 @@ mch_start_job(char **argv, job_T *job, jobopt_T *options UNUSED)
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
else if (pipe(fd_in) < 0)
|
||||
else if (!use_null_for_in && pipe(fd_in) < 0)
|
||||
goto failed;
|
||||
|
||||
if (use_file_for_out)
|
||||
@@ -5086,7 +5092,7 @@ mch_start_job(char **argv, job_T *job, jobopt_T *options UNUSED)
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
else if (pipe(fd_out) < 0)
|
||||
else if (!use_null_for_out && pipe(fd_out) < 0)
|
||||
goto failed;
|
||||
|
||||
if (use_file_for_err)
|
||||
@@ -5100,12 +5106,15 @@ mch_start_job(char **argv, job_T *job, jobopt_T *options UNUSED)
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
else if (!use_out_for_err && pipe(fd_err) < 0)
|
||||
else if (!use_out_for_err && !use_null_for_err && pipe(fd_err) < 0)
|
||||
goto failed;
|
||||
|
||||
channel = add_channel();
|
||||
if (channel == NULL)
|
||||
goto failed;
|
||||
if (!use_null_for_in || !use_null_for_out || !use_null_for_err)
|
||||
{
|
||||
channel = add_channel();
|
||||
if (channel == NULL)
|
||||
goto failed;
|
||||
}
|
||||
# endif
|
||||
|
||||
pid = fork(); /* maybe we should use vfork() */
|
||||
@@ -5117,6 +5126,10 @@ mch_start_job(char **argv, job_T *job, jobopt_T *options UNUSED)
|
||||
|
||||
if (pid == 0)
|
||||
{
|
||||
# ifdef FEAT_CHANNEL
|
||||
int null_fd = -1;
|
||||
# endif
|
||||
|
||||
/* child */
|
||||
reset_signals(); /* handle signals normally */
|
||||
|
||||
@@ -5131,15 +5144,31 @@ mch_start_job(char **argv, job_T *job, jobopt_T *options UNUSED)
|
||||
|
||||
/* TODO: re-enable this when pipes connect without a channel */
|
||||
# ifdef FEAT_CHANNEL
|
||||
if (use_null_for_in || use_null_for_out || use_null_for_err)
|
||||
null_fd = open("/dev/null", O_RDWR | O_EXTRA, 0);
|
||||
|
||||
/* set up stdin for the child */
|
||||
if (!use_file_for_in)
|
||||
close(fd_in[1]);
|
||||
close(0);
|
||||
ignored = dup(fd_in[0]);
|
||||
close(fd_in[0]);
|
||||
if (use_null_for_in)
|
||||
{
|
||||
close(0);
|
||||
ignored = dup(null_fd);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!use_file_for_in)
|
||||
close(fd_in[1]);
|
||||
close(0);
|
||||
ignored = dup(fd_in[0]);
|
||||
close(fd_in[0]);
|
||||
}
|
||||
|
||||
/* set up stderr for the child */
|
||||
if (use_out_for_err)
|
||||
if (use_null_for_err)
|
||||
{
|
||||
close(2);
|
||||
ignored = dup(null_fd);
|
||||
}
|
||||
else if (use_out_for_err)
|
||||
{
|
||||
close(2);
|
||||
ignored = dup(fd_out[1]);
|
||||
@@ -5154,11 +5183,21 @@ mch_start_job(char **argv, job_T *job, jobopt_T *options UNUSED)
|
||||
}
|
||||
|
||||
/* set up stdout for the child */
|
||||
if (!use_file_for_out)
|
||||
close(fd_out[0]);
|
||||
close(1);
|
||||
ignored = dup(fd_out[1]);
|
||||
close(fd_out[1]);
|
||||
if (use_null_for_out)
|
||||
{
|
||||
close(0);
|
||||
ignored = dup(null_fd);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!use_file_for_out)
|
||||
close(fd_out[0]);
|
||||
close(1);
|
||||
ignored = dup(fd_out[1]);
|
||||
close(fd_out[1]);
|
||||
}
|
||||
if (null_fd >= 0)
|
||||
close(null_fd);
|
||||
# endif
|
||||
|
||||
/* See above for type of argv. */
|
||||
@@ -5183,17 +5222,23 @@ mch_start_job(char **argv, job_T *job, jobopt_T *options UNUSED)
|
||||
close(fd_out[1]);
|
||||
if (!use_out_for_err && !use_file_for_err)
|
||||
close(fd_err[1]);
|
||||
channel_set_pipes(channel,
|
||||
use_file_for_in ? INVALID_FD : fd_in[1],
|
||||
use_file_for_out ? INVALID_FD : fd_out[0],
|
||||
use_out_for_err || use_file_for_err
|
||||
if (channel != NULL)
|
||||
{
|
||||
channel_set_pipes(channel,
|
||||
use_file_for_in || use_null_for_in
|
||||
? INVALID_FD : fd_in[1],
|
||||
use_file_for_out || use_null_for_out
|
||||
? INVALID_FD : fd_out[0],
|
||||
use_out_for_err || use_file_for_err || use_null_for_err
|
||||
? INVALID_FD : fd_err[0]);
|
||||
channel_set_job(channel, job, options);
|
||||
channel_set_job(channel, job, options);
|
||||
# ifdef FEAT_GUI
|
||||
channel_gui_register(channel);
|
||||
channel_gui_register(channel);
|
||||
# endif
|
||||
}
|
||||
# endif
|
||||
|
||||
/* success! */
|
||||
return;
|
||||
|
||||
failed: ;
|
||||
|
Reference in New Issue
Block a user