comparison src/os_unix.c @ 8031:ece323e2b57f v7.4.1310

commit https://github.com/vim/vim/commit/6463ca229cb9412581419497924c85fcbfc854ab Author: Bram Moolenaar <Bram@vim.org> Date: Sat Feb 13 17:04:46 2016 +0100 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.
author Christian Brabandt <cb@256bit.org>
date Sat, 13 Feb 2016 17:15:05 +0100
parents 75e0831549f1
children c6443e78cf2d
comparison
equal deleted inserted replaced
8030:05f57db9d8da 8031:ece323e2b57f
3982 } 3982 }
3983 return OK; 3983 return OK;
3984 } 3984 }
3985 #endif 3985 #endif
3986 3986
3987 #if !defined(USE_SYSTEM) || defined(FEAT_JOB)
3988 static void
3989 set_child_environment(void)
3990 {
3991 # ifdef HAVE_SETENV
3992 char envbuf[50];
3993 # else
3994 static char envbuf_Rows[20];
3995 static char envbuf_Columns[20];
3996 # endif
3997
3998 /* Simulate to have a dumb terminal (for now) */
3999 # ifdef HAVE_SETENV
4000 setenv("TERM", "dumb", 1);
4001 sprintf((char *)envbuf, "%ld", Rows);
4002 setenv("ROWS", (char *)envbuf, 1);
4003 sprintf((char *)envbuf, "%ld", Rows);
4004 setenv("LINES", (char *)envbuf, 1);
4005 sprintf((char *)envbuf, "%ld", Columns);
4006 setenv("COLUMNS", (char *)envbuf, 1);
4007 # else
4008 /*
4009 * Putenv does not copy the string, it has to remain valid.
4010 * Use a static array to avoid losing allocated memory.
4011 */
4012 putenv("TERM=dumb");
4013 sprintf(envbuf_Rows, "ROWS=%ld", Rows);
4014 putenv(envbuf_Rows);
4015 sprintf(envbuf_Rows, "LINES=%ld", Rows);
4016 putenv(envbuf_Rows);
4017 sprintf(envbuf_Columns, "COLUMNS=%ld", Columns);
4018 putenv(envbuf_Columns);
4019 # endif
4020 }
4021 #endif
4022
3987 int 4023 int
3988 mch_call_shell( 4024 mch_call_shell(
3989 char_u *cmd, 4025 char_u *cmd,
3990 int options) /* SHELL_*, see vim.h */ 4026 int options) /* SHELL_*, see vim.h */
3991 { 4027 {
4132 char *tty_name; 4168 char *tty_name;
4133 # endif 4169 # endif
4134 int fd_toshell[2]; /* for pipes */ 4170 int fd_toshell[2]; /* for pipes */
4135 int fd_fromshell[2]; 4171 int fd_fromshell[2];
4136 int pipe_error = FALSE; 4172 int pipe_error = FALSE;
4137 # ifdef HAVE_SETENV
4138 char envbuf[50];
4139 # else
4140 static char envbuf_Rows[20];
4141 static char envbuf_Columns[20];
4142 # endif
4143 int did_settmode = FALSE; /* settmode(TMODE_RAW) called */ 4173 int did_settmode = FALSE; /* settmode(TMODE_RAW) called */
4144 4174
4145 newcmd = vim_strsave(p_sh); 4175 newcmd = vim_strsave(p_sh);
4146 if (newcmd == NULL) /* out of memory */ 4176 if (newcmd == NULL) /* out of memory */
4147 goto error; 4177 goto error;
4347 * unless run by root) */ 4377 * unless run by root) */
4348 ioctl(pty_slave_fd, TIOCSCTTY, (char *)NULL); 4378 ioctl(pty_slave_fd, TIOCSCTTY, (char *)NULL);
4349 # endif 4379 # endif
4350 } 4380 }
4351 # endif 4381 # endif
4352 /* Simulate to have a dumb terminal (for now) */ 4382 set_child_environment();
4353 # ifdef HAVE_SETENV
4354 setenv("TERM", "dumb", 1);
4355 sprintf((char *)envbuf, "%ld", Rows);
4356 setenv("ROWS", (char *)envbuf, 1);
4357 sprintf((char *)envbuf, "%ld", Rows);
4358 setenv("LINES", (char *)envbuf, 1);
4359 sprintf((char *)envbuf, "%ld", Columns);
4360 setenv("COLUMNS", (char *)envbuf, 1);
4361 # else
4362 /*
4363 * Putenv does not copy the string, it has to remain valid.
4364 * Use a static array to avoid losing allocated memory.
4365 */
4366 putenv("TERM=dumb");
4367 sprintf(envbuf_Rows, "ROWS=%ld", Rows);
4368 putenv(envbuf_Rows);
4369 sprintf(envbuf_Rows, "LINES=%ld", Rows);
4370 putenv(envbuf_Rows);
4371 sprintf(envbuf_Columns, "COLUMNS=%ld", Columns);
4372 putenv(envbuf_Columns);
4373 # endif
4374 4383
4375 /* 4384 /*
4376 * stderr is only redirected when using the GUI, so that a 4385 * stderr is only redirected when using the GUI, so that a
4377 * program like gpg can still access the terminal to get a 4386 * program like gpg can still access the terminal to get a
4378 * passphrase using stderr. 4387 * passphrase using stderr.
5028 5037
5029 #if defined(FEAT_JOB) || defined(PROTO) 5038 #if defined(FEAT_JOB) || defined(PROTO)
5030 void 5039 void
5031 mch_start_job(char **argv, job_T *job) 5040 mch_start_job(char **argv, job_T *job)
5032 { 5041 {
5033 pid_t pid = fork(); 5042 pid_t pid;
5034 5043 int fd_in[2]; /* for stdin */
5035 if (pid == -1) /* maybe we should use vfork() */ 5044 int fd_out[2]; /* for stdout */
5036 { 5045 int fd_err[2]; /* for stderr */
5037 job->jv_status = JOB_FAILED; 5046 int ch_idx;
5038 } 5047
5039 else if (pid == 0) 5048 /* default is to fail */
5049 job->jv_status = JOB_FAILED;
5050 fd_in[0] = -1;
5051 fd_out[0] = -1;
5052 fd_err[0] = -1;
5053
5054 /* Open pipes for stdin, stdout, stderr. */
5055 if ((pipe(fd_in) < 0) || (pipe(fd_out) < 0) ||(pipe(fd_err) < 0))
5056 goto failed;
5057
5058 ch_idx = add_channel();
5059 if (ch_idx < 0)
5060 goto failed;
5061
5062 pid = fork(); /* maybe we should use vfork() */
5063 if (pid == -1)
5064 {
5065 /* failed to fork */
5066 goto failed;
5067 }
5068
5069 if (pid == 0)
5040 { 5070 {
5041 /* child */ 5071 /* child */
5042 reset_signals(); /* handle signals normally */ 5072 reset_signals(); /* handle signals normally */
5043 5073
5044 # ifdef HAVE_SETSID 5074 # ifdef HAVE_SETSID
5046 * children can be kill()ed. Don't do this when using pipes, 5076 * children can be kill()ed. Don't do this when using pipes,
5047 * because stdin is not a tty, we would lose /dev/tty. */ 5077 * because stdin is not a tty, we would lose /dev/tty. */
5048 (void)setsid(); 5078 (void)setsid();
5049 # endif 5079 # endif
5050 5080
5081 set_child_environment();
5082
5083 /* set up stdin for the child */
5084 close(fd_in[1]);
5085 close(0);
5086 ignored = dup(fd_in[0]);
5087 close(fd_in[0]);
5088
5089 /* set up stdout for the child */
5090 close(fd_out[0]);
5091 close(1);
5092 ignored = dup(fd_out[1]);
5093 close(fd_out[1]);
5094
5095 /* set up stderr for the child */
5096 close(fd_err[0]);
5097 close(2);
5098 ignored = dup(fd_err[1]);
5099 close(fd_err[1]);
5100
5051 /* See above for type of argv. */ 5101 /* See above for type of argv. */
5052 execvp(argv[0], argv); 5102 execvp(argv[0], argv);
5053 5103
5054 perror("executing job failed"); 5104 perror("executing job failed");
5055 _exit(EXEC_FAILED); /* exec failed, return failure code */ 5105 _exit(EXEC_FAILED); /* exec failed, return failure code */
5056 } 5106 }
5057 else 5107
5058 { 5108 /* parent */
5059 /* parent */ 5109 job->jv_pid = pid;
5060 job->jv_pid = pid; 5110 job->jv_status = JOB_STARTED;
5061 job->jv_status = JOB_STARTED; 5111 job->jv_channel = ch_idx;
5112
5113 /* child stdin, stdout and stderr */
5114 close(fd_in[0]);
5115 close(fd_out[1]);
5116 close(fd_err[1]);
5117 channel_set_pipes(ch_idx, fd_in[1], fd_out[0], fd_err[0]);
5118 channel_set_job(ch_idx, job);
5119
5120 return;
5121
5122 failed:
5123 if (fd_in[0] >= 0)
5124 {
5125 close(fd_in[0]);
5126 close(fd_in[1]);
5127 }
5128 if (fd_out[0] >= 0)
5129 {
5130 close(fd_out[0]);
5131 close(fd_out[1]);
5132 }
5133 if (fd_err[0] >= 0)
5134 {
5135 close(fd_err[0]);
5136 close(fd_err[1]);
5062 } 5137 }
5063 } 5138 }
5064 5139
5065 char * 5140 char *
5066 mch_job_status(job_T *job) 5141 mch_job_status(job_T *job)
5102 } 5177 }
5103 5178
5104 int 5179 int
5105 mch_stop_job(job_T *job, char_u *how) 5180 mch_stop_job(job_T *job, char_u *how)
5106 { 5181 {
5107 int sig = -1; 5182 int sig = -1;
5108 pid_t job_pid; 5183 pid_t job_pid;
5109 5184
5110 if (STRCMP(how, "hup") == 0) 5185 if (STRCMP(how, "hup") == 0)
5111 sig = SIGHUP; 5186 sig = SIGHUP;
5112 else if (*how == NUL || STRCMP(how, "term") == 0) 5187 else if (*how == NUL || STRCMP(how, "term") == 0)
5113 sig = SIGTERM; 5188 sig = SIGTERM;