Mercurial > vim
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; |