Mercurial > vim
comparison src/os_win32.c @ 8471:c1aae3a79279 v7.4.1526
commit https://github.com/vim/vim/commit/d5d3d307ddb824f59a2f2516c4b6a6d48762aa58
Author: Bram Moolenaar <Bram@vim.org>
Date: Wed Mar 9 20:54:51 2016 +0100
patch 7.4.1526
Problem: Writing to file and not connecting a channel doesn't work for
MS-Windows.
Solution: Make it work. (Yasuhiro Matsumoto)
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Wed, 09 Mar 2016 21:00:05 +0100 |
parents | 20533e3de373 |
children | 9f63e4506c40 |
comparison
equal
deleted
inserted
replaced
8470:552c13b08d0b | 8471:c1aae3a79279 |
---|---|
4990 | 4990 |
4991 return x; | 4991 return x; |
4992 } | 4992 } |
4993 | 4993 |
4994 #if defined(FEAT_JOB) || defined(PROTO) | 4994 #if defined(FEAT_JOB) || defined(PROTO) |
4995 HANDLE | |
4996 job_io_file_open( | |
4997 char_u *fname, | |
4998 DWORD dwDesiredAccess, | |
4999 DWORD dwShareMode, | |
5000 LPSECURITY_ATTRIBUTES lpSecurityAttributes, | |
5001 DWORD dwCreationDisposition, | |
5002 DWORD dwFlagsAndAttributes) | |
5003 { | |
5004 HANDLE h; | |
5005 #ifdef FEAT_MBYTE | |
5006 WCHAR *wn = NULL; | |
5007 if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) | |
5008 { | |
5009 wn = enc_to_utf16(fname, NULL); | |
5010 if (wn != NULL) | |
5011 { | |
5012 h = CreateFileW(wn, dwDesiredAccess, dwShareMode, | |
5013 lpSecurityAttributes, dwCreationDisposition, | |
5014 dwFlagsAndAttributes, NULL); | |
5015 vim_free(wn); | |
5016 if (h == INVALID_HANDLE_VALUE | |
5017 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) | |
5018 wn = NULL; | |
5019 } | |
5020 } | |
5021 if (wn == NULL) | |
5022 #endif | |
5023 | |
5024 h = CreateFile((LPCSTR)fname, dwDesiredAccess, dwShareMode, | |
5025 lpSecurityAttributes, dwCreationDisposition, | |
5026 dwFlagsAndAttributes, NULL); | |
5027 return h; | |
5028 } | |
5029 | |
5030 void | 4995 void |
5031 mch_start_job(char *cmd, job_T *job, jobopt_T *options) | 4996 mch_start_job(char *cmd, job_T *job, jobopt_T *options) |
5032 { | 4997 { |
5033 STARTUPINFO si; | 4998 STARTUPINFO si; |
5034 PROCESS_INFORMATION pi; | 4999 PROCESS_INFORMATION pi; |
5035 HANDLE jo; | 5000 HANDLE jo; |
5036 # ifdef FEAT_CHANNEL | 5001 # ifdef FEAT_CHANNEL |
5037 channel_T *channel; | 5002 SECURITY_ATTRIBUTES saAttr; |
5038 int use_file_for_in = options->jo_io[PART_IN] == JIO_FILE; | 5003 channel_T *channel = NULL; |
5039 int use_file_for_out = options->jo_io[PART_OUT] == JIO_FILE; | |
5040 int use_file_for_err = options->jo_io[PART_ERR] == JIO_FILE; | |
5041 int use_out_for_err = options->jo_io[PART_ERR] == JIO_OUT; | |
5042 HANDLE ifd[2]; | 5004 HANDLE ifd[2]; |
5043 HANDLE ofd[2]; | 5005 HANDLE ofd[2]; |
5044 HANDLE efd[2]; | 5006 HANDLE efd[2]; |
5045 SECURITY_ATTRIBUTES saAttr; | 5007 |
5008 int use_null_for_in = options->jo_io[PART_IN] == JIO_NULL; | |
5009 int use_null_for_out = options->jo_io[PART_OUT] == JIO_NULL; | |
5010 int use_null_for_err = options->jo_io[PART_ERR] == JIO_NULL; | |
5011 int use_file_for_in = options->jo_io[PART_IN] == JIO_FILE; | |
5012 int use_file_for_out = options->jo_io[PART_OUT] == JIO_FILE; | |
5013 int use_file_for_err = options->jo_io[PART_ERR] == JIO_FILE; | |
5014 int use_out_for_err = options->jo_io[PART_ERR] == JIO_OUT; | |
5015 | |
5016 if (use_out_for_err && use_null_for_out) | |
5017 use_null_for_err = TRUE; | |
5046 | 5018 |
5047 ifd[0] = INVALID_HANDLE_VALUE; | 5019 ifd[0] = INVALID_HANDLE_VALUE; |
5048 ifd[1] = INVALID_HANDLE_VALUE; | 5020 ifd[1] = INVALID_HANDLE_VALUE; |
5049 ofd[0] = INVALID_HANDLE_VALUE; | 5021 ofd[0] = INVALID_HANDLE_VALUE; |
5050 ofd[1] = INVALID_HANDLE_VALUE; | 5022 ofd[1] = INVALID_HANDLE_VALUE; |
5051 efd[0] = INVALID_HANDLE_VALUE; | 5023 efd[0] = INVALID_HANDLE_VALUE; |
5052 efd[1] = INVALID_HANDLE_VALUE; | 5024 efd[1] = INVALID_HANDLE_VALUE; |
5053 | |
5054 channel = add_channel(); | |
5055 if (channel == NULL) | |
5056 return; | |
5057 # endif | 5025 # endif |
5058 | 5026 |
5059 jo = CreateJobObject(NULL, NULL); | 5027 jo = CreateJobObject(NULL, NULL); |
5060 if (jo == NULL) | 5028 if (jo == NULL) |
5061 { | 5029 { |
5076 | 5044 |
5077 if (use_file_for_in) | 5045 if (use_file_for_in) |
5078 { | 5046 { |
5079 char_u *fname = options->jo_io_name[PART_IN]; | 5047 char_u *fname = options->jo_io_name[PART_IN]; |
5080 | 5048 |
5081 ifd[0] = job_io_file_open(fname, GENERIC_READ, FILE_SHARE_READ, | 5049 int fd = mch_open((char *)fname, O_RDONLY, 0); |
5082 &saAttr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL); | 5050 if (fd < 0) |
5083 if (ifd[0] == INVALID_HANDLE_VALUE) | |
5084 { | 5051 { |
5085 EMSG2(_(e_notopen), fname); | 5052 EMSG2(_(e_notopen), fname); |
5086 goto failed; | 5053 goto failed; |
5087 } | 5054 } |
5088 } | 5055 ifd[0] = (HANDLE)_get_osfhandle(fd); |
5089 else if (!CreatePipe(&ifd[0], &ifd[1], &saAttr, 0) | 5056 } |
5090 || !pSetHandleInformation(ifd[1], HANDLE_FLAG_INHERIT, 0)) | 5057 else if (!use_null_for_in && |
5058 (!CreatePipe(&ifd[0], &ifd[1], &saAttr, 0) | |
5059 || !pSetHandleInformation(ifd[1], HANDLE_FLAG_INHERIT, 0))) | |
5091 goto failed; | 5060 goto failed; |
5092 | 5061 |
5093 if (use_file_for_out) | 5062 if (use_file_for_out) |
5094 { | 5063 { |
5095 char_u *fname = options->jo_io_name[PART_OUT]; | 5064 char_u *fname = options->jo_io_name[PART_OUT]; |
5096 | 5065 |
5097 ofd[0] = job_io_file_open(fname, GENERIC_WRITE, FILE_SHARE_WRITE, | 5066 int fd = mch_open((char *)fname, O_WRONLY | O_CREAT | O_TRUNC, 0644); |
5098 &saAttr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL); | 5067 if (fd < 0) |
5099 if (ofd[0] == INVALID_HANDLE_VALUE) | |
5100 { | 5068 { |
5101 EMSG2(_(e_notopen), fname); | 5069 EMSG2(_(e_notopen), fname); |
5102 goto failed; | 5070 goto failed; |
5103 } | 5071 } |
5104 } | 5072 ofd[1] = (HANDLE)_get_osfhandle(fd); |
5105 else if (!CreatePipe(&ofd[0], &ofd[1], &saAttr, 0) | 5073 } |
5106 || !pSetHandleInformation(ofd[0], HANDLE_FLAG_INHERIT, 0)) | 5074 else if (!use_null_for_out && |
5075 (!CreatePipe(&ofd[0], &ofd[1], &saAttr, 0) | |
5076 || !pSetHandleInformation(ofd[0], HANDLE_FLAG_INHERIT, 0))) | |
5107 goto failed; | 5077 goto failed; |
5108 | 5078 |
5109 if (use_file_for_err) | 5079 if (use_file_for_err) |
5110 { | 5080 { |
5111 char_u *fname = options->jo_io_name[PART_ERR]; | 5081 char_u *fname = options->jo_io_name[PART_ERR]; |
5112 | 5082 |
5113 efd[0] = job_io_file_open(fname, GENERIC_WRITE, FILE_SHARE_WRITE, | 5083 int fd = mch_open((char *)fname, O_WRONLY | O_CREAT | O_TRUNC, 0600); |
5114 &saAttr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL); | 5084 if (fd < 0) |
5115 if (efd[0] == INVALID_HANDLE_VALUE) | |
5116 { | 5085 { |
5117 EMSG2(_(e_notopen), fname); | 5086 EMSG2(_(e_notopen), fname); |
5118 goto failed; | 5087 goto failed; |
5119 } | 5088 } |
5120 } | 5089 efd[1] = (HANDLE)_get_osfhandle(fd); |
5121 else if (!use_out_for_err | 5090 } |
5122 && (!CreatePipe(&efd[0], &efd[1], &saAttr, 0) | 5091 else if (!use_out_for_err && !use_null_for_err && |
5092 (!CreatePipe(&efd[0], &efd[1], &saAttr, 0) | |
5123 || !pSetHandleInformation(efd[0], HANDLE_FLAG_INHERIT, 0))) | 5093 || !pSetHandleInformation(efd[0], HANDLE_FLAG_INHERIT, 0))) |
5124 goto failed; | 5094 goto failed; |
5125 | 5095 |
5126 si.dwFlags |= STARTF_USESTDHANDLES; | 5096 si.dwFlags |= STARTF_USESTDHANDLES; |
5127 si.hStdInput = ifd[0]; | 5097 si.hStdInput = ifd[0]; |
5128 si.hStdOutput = use_file_for_out ? ofd[0] : ofd[1]; | 5098 si.hStdOutput = ofd[1]; |
5129 si.hStdError = use_out_for_err && !use_file_for_err ? ofd[1] : efd[1]; | 5099 si.hStdError = use_out_for_err ? ofd[1] : efd[1]; |
5100 | |
5101 if (!use_null_for_in || !use_null_for_out || !use_null_for_err) | |
5102 { | |
5103 channel = add_channel(); | |
5104 if (channel == NULL) | |
5105 goto failed; | |
5106 } | |
5130 # endif | 5107 # endif |
5131 | 5108 |
5132 if (!vim_create_process(cmd, TRUE, | 5109 if (!vim_create_process(cmd, TRUE, |
5133 CREATE_SUSPENDED | | 5110 CREATE_SUSPENDED | |
5134 CREATE_DEFAULT_ERROR_MODE | | 5111 CREATE_DEFAULT_ERROR_MODE | |
5157 # ifdef FEAT_CHANNEL | 5134 # ifdef FEAT_CHANNEL |
5158 if (!use_file_for_in) | 5135 if (!use_file_for_in) |
5159 CloseHandle(ifd[0]); | 5136 CloseHandle(ifd[0]); |
5160 if (!use_file_for_out) | 5137 if (!use_file_for_out) |
5161 CloseHandle(ofd[1]); | 5138 CloseHandle(ofd[1]); |
5162 if (!use_out_for_err) | 5139 if (!use_out_for_err && !use_file_for_err) |
5163 CloseHandle(efd[1]); | 5140 CloseHandle(efd[1]); |
5164 | 5141 |
5165 job->jv_channel = channel; | 5142 job->jv_channel = channel; |
5166 channel_set_pipes(channel, | 5143 if (channel != NULL) |
5167 use_file_for_in ? INVALID_FD : (sock_T)ifd[1], | 5144 { |
5168 (sock_T)ofd[0], | 5145 channel_set_pipes(channel, |
5169 use_out_for_err ? INVALID_FD : (sock_T)efd[0]); | 5146 use_file_for_in || use_null_for_in |
5170 channel_set_job(channel, job, options); | 5147 ? INVALID_FD : (sock_T)ifd[1], |
5148 use_file_for_out || use_null_for_out | |
5149 ? INVALID_FD : (sock_T)ofd[0], | |
5150 use_out_for_err || use_file_for_err || use_null_for_err | |
5151 ? INVALID_FD : (sock_T)efd[0]); | |
5152 channel_set_job(channel, job, options); | |
5171 # ifdef FEAT_GUI | 5153 # ifdef FEAT_GUI |
5172 channel_gui_register(channel); | 5154 channel_gui_register(channel); |
5173 # endif | 5155 # endif |
5156 } | |
5174 # endif | 5157 # endif |
5175 return; | 5158 return; |
5176 | 5159 |
5177 failed: | 5160 failed: |
5178 # ifdef FEAT_CHANNEL | 5161 # ifdef FEAT_CHANNEL |