patch 7.4.1518
Problem: Channel with disconnected in/out/err is not supported.
Solution: Implement it for Unix.
diff --git a/src/os_unix.c b/src/os_unix.c
index b4921e3..7eb4e71 100644
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -5045,11 +5045,17 @@
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 @@
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 @@
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 @@
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 @@
if (pid == 0)
{
+# ifdef FEAT_CHANNEL
+ int null_fd = -1;
+# endif
+
/* child */
reset_signals(); /* handle signals normally */
@@ -5131,15 +5144,31 @@
/* 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 @@
}
/* 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 @@
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: ;