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