patch 7.4.1310
Problem: Jobs don't open a channel.
Solution: Create pipes and add them to the channel. Add ch_logfile().
Only Unix for now.
diff --git a/src/os_unix.c b/src/os_unix.c
index 83ae75f..5578cfe 100644
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -3984,6 +3984,42 @@
}
#endif
+#if !defined(USE_SYSTEM) || defined(FEAT_JOB)
+ static void
+set_child_environment(void)
+{
+# ifdef HAVE_SETENV
+ char envbuf[50];
+# else
+ static char envbuf_Rows[20];
+ static char envbuf_Columns[20];
+# endif
+
+ /* Simulate to have a dumb terminal (for now) */
+# ifdef HAVE_SETENV
+ setenv("TERM", "dumb", 1);
+ sprintf((char *)envbuf, "%ld", Rows);
+ setenv("ROWS", (char *)envbuf, 1);
+ sprintf((char *)envbuf, "%ld", Rows);
+ setenv("LINES", (char *)envbuf, 1);
+ sprintf((char *)envbuf, "%ld", Columns);
+ setenv("COLUMNS", (char *)envbuf, 1);
+# else
+ /*
+ * Putenv does not copy the string, it has to remain valid.
+ * Use a static array to avoid losing allocated memory.
+ */
+ putenv("TERM=dumb");
+ sprintf(envbuf_Rows, "ROWS=%ld", Rows);
+ putenv(envbuf_Rows);
+ sprintf(envbuf_Rows, "LINES=%ld", Rows);
+ putenv(envbuf_Rows);
+ sprintf(envbuf_Columns, "COLUMNS=%ld", Columns);
+ putenv(envbuf_Columns);
+# endif
+}
+#endif
+
int
mch_call_shell(
char_u *cmd,
@@ -4134,12 +4170,6 @@
int fd_toshell[2]; /* for pipes */
int fd_fromshell[2];
int pipe_error = FALSE;
-# ifdef HAVE_SETENV
- char envbuf[50];
-# else
- static char envbuf_Rows[20];
- static char envbuf_Columns[20];
-# endif
int did_settmode = FALSE; /* settmode(TMODE_RAW) called */
newcmd = vim_strsave(p_sh);
@@ -4349,28 +4379,7 @@
# endif
}
# endif
- /* Simulate to have a dumb terminal (for now) */
-# ifdef HAVE_SETENV
- setenv("TERM", "dumb", 1);
- sprintf((char *)envbuf, "%ld", Rows);
- setenv("ROWS", (char *)envbuf, 1);
- sprintf((char *)envbuf, "%ld", Rows);
- setenv("LINES", (char *)envbuf, 1);
- sprintf((char *)envbuf, "%ld", Columns);
- setenv("COLUMNS", (char *)envbuf, 1);
-# else
- /*
- * Putenv does not copy the string, it has to remain valid.
- * Use a static array to avoid losing allocated memory.
- */
- putenv("TERM=dumb");
- sprintf(envbuf_Rows, "ROWS=%ld", Rows);
- putenv(envbuf_Rows);
- sprintf(envbuf_Rows, "LINES=%ld", Rows);
- putenv(envbuf_Rows);
- sprintf(envbuf_Columns, "COLUMNS=%ld", Columns);
- putenv(envbuf_Columns);
-# endif
+ set_child_environment();
/*
* stderr is only redirected when using the GUI, so that a
@@ -5030,13 +5039,34 @@
void
mch_start_job(char **argv, job_T *job)
{
- pid_t pid = fork();
+ pid_t pid;
+ int fd_in[2]; /* for stdin */
+ int fd_out[2]; /* for stdout */
+ int fd_err[2]; /* for stderr */
+ int ch_idx;
- if (pid == -1) /* maybe we should use vfork() */
+ /* default is to fail */
+ job->jv_status = JOB_FAILED;
+ fd_in[0] = -1;
+ fd_out[0] = -1;
+ fd_err[0] = -1;
+
+ /* Open pipes for stdin, stdout, stderr. */
+ if ((pipe(fd_in) < 0) || (pipe(fd_out) < 0) ||(pipe(fd_err) < 0))
+ goto failed;
+
+ ch_idx = add_channel();
+ if (ch_idx < 0)
+ goto failed;
+
+ pid = fork(); /* maybe we should use vfork() */
+ if (pid == -1)
{
- job->jv_status = JOB_FAILED;
+ /* failed to fork */
+ goto failed;
}
- else if (pid == 0)
+
+ if (pid == 0)
{
/* child */
reset_signals(); /* handle signals normally */
@@ -5048,17 +5078,62 @@
(void)setsid();
# endif
+ set_child_environment();
+
+ /* set up stdin for the child */
+ close(fd_in[1]);
+ close(0);
+ ignored = dup(fd_in[0]);
+ close(fd_in[0]);
+
+ /* set up stdout for the child */
+ close(fd_out[0]);
+ close(1);
+ ignored = dup(fd_out[1]);
+ close(fd_out[1]);
+
+ /* set up stderr for the child */
+ close(fd_err[0]);
+ close(2);
+ ignored = dup(fd_err[1]);
+ close(fd_err[1]);
+
/* See above for type of argv. */
execvp(argv[0], argv);
perror("executing job failed");
_exit(EXEC_FAILED); /* exec failed, return failure code */
}
- else
+
+ /* parent */
+ job->jv_pid = pid;
+ job->jv_status = JOB_STARTED;
+ job->jv_channel = ch_idx;
+
+ /* child stdin, stdout and stderr */
+ close(fd_in[0]);
+ close(fd_out[1]);
+ close(fd_err[1]);
+ channel_set_pipes(ch_idx, fd_in[1], fd_out[0], fd_err[0]);
+ channel_set_job(ch_idx, job);
+
+ return;
+
+failed:
+ if (fd_in[0] >= 0)
{
- /* parent */
- job->jv_pid = pid;
- job->jv_status = JOB_STARTED;
+ close(fd_in[0]);
+ close(fd_in[1]);
+ }
+ if (fd_out[0] >= 0)
+ {
+ close(fd_out[0]);
+ close(fd_out[1]);
+ }
+ if (fd_err[0] >= 0)
+ {
+ close(fd_err[0]);
+ close(fd_err[1]);
}
}
@@ -5104,8 +5179,8 @@
int
mch_stop_job(job_T *job, char_u *how)
{
- int sig = -1;
- pid_t job_pid;
+ int sig = -1;
+ pid_t job_pid;
if (STRCMP(how, "hup") == 0)
sig = SIGHUP;