diff options
author | Bram Moolenaar <Bram@vim.org> | 2016-03-09 20:54:51 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2016-03-09 20:54:51 +0100 |
commit | d5d3d307ddb824f59a2f2516c4b6a6d48762aa58 (patch) | |
tree | 5650674d76b7526a6e625fb41700205e052e85b6 | |
parent | beb003b303cde1e55634aae9f810535684b76211 (diff) | |
download | vim-git-7.4.1526.tar.gz |
patch 7.4.1526v7.4.1526
Problem: Writing to file and not connecting a channel doesn't work for
MS-Windows.
Solution: Make it work. (Yasuhiro Matsumoto)
-rw-r--r-- | src/os_win32.c | 121 | ||||
-rw-r--r-- | src/testdir/test_channel.vim | 16 | ||||
-rw-r--r-- | src/version.c | 2 |
3 files changed, 54 insertions, 85 deletions
diff --git a/src/os_win32.c b/src/os_win32.c index 3e2e75279..a59cad2ca 100644 --- a/src/os_win32.c +++ b/src/os_win32.c @@ -4992,41 +4992,6 @@ mch_call_shell( } #if defined(FEAT_JOB) || defined(PROTO) - HANDLE -job_io_file_open( - char_u *fname, - DWORD dwDesiredAccess, - DWORD dwShareMode, - LPSECURITY_ATTRIBUTES lpSecurityAttributes, - DWORD dwCreationDisposition, - DWORD dwFlagsAndAttributes) -{ - HANDLE h; -#ifdef FEAT_MBYTE - WCHAR *wn = NULL; - if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) - { - wn = enc_to_utf16(fname, NULL); - if (wn != NULL) - { - h = CreateFileW(wn, dwDesiredAccess, dwShareMode, - lpSecurityAttributes, dwCreationDisposition, - dwFlagsAndAttributes, NULL); - vim_free(wn); - if (h == INVALID_HANDLE_VALUE - && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) - wn = NULL; - } - } - if (wn == NULL) -#endif - - h = CreateFile((LPCSTR)fname, dwDesiredAccess, dwShareMode, - lpSecurityAttributes, dwCreationDisposition, - dwFlagsAndAttributes, NULL); - return h; -} - void mch_start_job(char *cmd, job_T *job, jobopt_T *options) { @@ -5034,15 +4999,22 @@ mch_start_job(char *cmd, job_T *job, jobopt_T *options) PROCESS_INFORMATION pi; HANDLE jo; # ifdef FEAT_CHANNEL - channel_T *channel; - int use_file_for_in = options->jo_io[PART_IN] == JIO_FILE; - int use_file_for_out = options->jo_io[PART_OUT] == JIO_FILE; - int use_file_for_err = options->jo_io[PART_ERR] == JIO_FILE; - int use_out_for_err = options->jo_io[PART_ERR] == JIO_OUT; + SECURITY_ATTRIBUTES saAttr; + channel_T *channel = NULL; HANDLE ifd[2]; HANDLE ofd[2]; HANDLE efd[2]; - SECURITY_ATTRIBUTES saAttr; + + int use_null_for_in = options->jo_io[PART_IN] == JIO_NULL; + int use_null_for_out = options->jo_io[PART_OUT] == JIO_NULL; + int use_null_for_err = options->jo_io[PART_ERR] == JIO_NULL; + int use_file_for_in = options->jo_io[PART_IN] == JIO_FILE; + int use_file_for_out = options->jo_io[PART_OUT] == JIO_FILE; + int use_file_for_err = options->jo_io[PART_ERR] == JIO_FILE; + int use_out_for_err = options->jo_io[PART_ERR] == JIO_OUT; + + if (use_out_for_err && use_null_for_out) + use_null_for_err = TRUE; ifd[0] = INVALID_HANDLE_VALUE; ifd[1] = INVALID_HANDLE_VALUE; @@ -5050,10 +5022,6 @@ mch_start_job(char *cmd, job_T *job, jobopt_T *options) ofd[1] = INVALID_HANDLE_VALUE; efd[0] = INVALID_HANDLE_VALUE; efd[1] = INVALID_HANDLE_VALUE; - - channel = add_channel(); - if (channel == NULL) - return; # endif jo = CreateJobObject(NULL, NULL); @@ -5078,55 +5046,64 @@ mch_start_job(char *cmd, job_T *job, jobopt_T *options) { char_u *fname = options->jo_io_name[PART_IN]; - ifd[0] = job_io_file_open(fname, GENERIC_READ, FILE_SHARE_READ, - &saAttr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL); - if (ifd[0] == INVALID_HANDLE_VALUE) + int fd = mch_open((char *)fname, O_RDONLY, 0); + if (fd < 0) { EMSG2(_(e_notopen), fname); goto failed; } + ifd[0] = (HANDLE)_get_osfhandle(fd); } - else if (!CreatePipe(&ifd[0], &ifd[1], &saAttr, 0) - || !pSetHandleInformation(ifd[1], HANDLE_FLAG_INHERIT, 0)) + else if (!use_null_for_in && + (!CreatePipe(&ifd[0], &ifd[1], &saAttr, 0) + || !pSetHandleInformation(ifd[1], HANDLE_FLAG_INHERIT, 0))) goto failed; if (use_file_for_out) { char_u *fname = options->jo_io_name[PART_OUT]; - ofd[0] = job_io_file_open(fname, GENERIC_WRITE, FILE_SHARE_WRITE, - &saAttr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL); - if (ofd[0] == INVALID_HANDLE_VALUE) + int fd = mch_open((char *)fname, O_WRONLY | O_CREAT | O_TRUNC, 0644); + if (fd < 0) { EMSG2(_(e_notopen), fname); goto failed; } + ofd[1] = (HANDLE)_get_osfhandle(fd); } - else if (!CreatePipe(&ofd[0], &ofd[1], &saAttr, 0) - || !pSetHandleInformation(ofd[0], HANDLE_FLAG_INHERIT, 0)) + else if (!use_null_for_out && + (!CreatePipe(&ofd[0], &ofd[1], &saAttr, 0) + || !pSetHandleInformation(ofd[0], HANDLE_FLAG_INHERIT, 0))) goto failed; if (use_file_for_err) { char_u *fname = options->jo_io_name[PART_ERR]; - efd[0] = job_io_file_open(fname, GENERIC_WRITE, FILE_SHARE_WRITE, - &saAttr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL); - if (efd[0] == INVALID_HANDLE_VALUE) + int fd = mch_open((char *)fname, O_WRONLY | O_CREAT | O_TRUNC, 0600); + if (fd < 0) { EMSG2(_(e_notopen), fname); goto failed; } + efd[1] = (HANDLE)_get_osfhandle(fd); } - else if (!use_out_for_err - && (!CreatePipe(&efd[0], &efd[1], &saAttr, 0) + else if (!use_out_for_err && !use_null_for_err && + (!CreatePipe(&efd[0], &efd[1], &saAttr, 0) || !pSetHandleInformation(efd[0], HANDLE_FLAG_INHERIT, 0))) goto failed; si.dwFlags |= STARTF_USESTDHANDLES; si.hStdInput = ifd[0]; - si.hStdOutput = use_file_for_out ? ofd[0] : ofd[1]; - si.hStdError = use_out_for_err && !use_file_for_err ? ofd[1] : efd[1]; + si.hStdOutput = ofd[1]; + si.hStdError = use_out_for_err ? ofd[1] : efd[1]; + + if (!use_null_for_in || !use_null_for_out || !use_null_for_err) + { + channel = add_channel(); + if (channel == NULL) + goto failed; + } # endif if (!vim_create_process(cmd, TRUE, @@ -5159,18 +5136,24 @@ mch_start_job(char *cmd, job_T *job, jobopt_T *options) CloseHandle(ifd[0]); if (!use_file_for_out) CloseHandle(ofd[1]); - if (!use_out_for_err) + if (!use_out_for_err && !use_file_for_err) CloseHandle(efd[1]); job->jv_channel = channel; - channel_set_pipes(channel, - use_file_for_in ? INVALID_FD : (sock_T)ifd[1], - (sock_T)ofd[0], - use_out_for_err ? INVALID_FD : (sock_T)efd[0]); - channel_set_job(channel, job, options); + if (channel != NULL) + { + channel_set_pipes(channel, + use_file_for_in || use_null_for_in + ? INVALID_FD : (sock_T)ifd[1], + use_file_for_out || use_null_for_out + ? INVALID_FD : (sock_T)ofd[0], + use_out_for_err || use_file_for_err || use_null_for_err + ? INVALID_FD : (sock_T)efd[0]); + channel_set_job(channel, job, options); # ifdef FEAT_GUI - channel_gui_register(channel); + channel_gui_register(channel); # endif + } # endif return; diff --git a/src/testdir/test_channel.vim b/src/testdir/test_channel.vim index 3b15568f2..12a101e48 100644 --- a/src/testdir/test_channel.vim +++ b/src/testdir/test_channel.vim @@ -550,10 +550,6 @@ func Test_nl_write_out_file() if !has('job') return endif - " TODO: make this work for MS-Windows - if !has('unix') - return - endif call ch_log('Test_nl_write_out_file()') let job = job_start(s:python . " test_channel_pipe.py", \ {'out-io': 'file', 'out-name': 'Xoutput'}) @@ -575,10 +571,6 @@ func Test_nl_write_err_file() if !has('job') return endif - " TODO: make this work for MS-Windows - if !has('unix') - return - endif call ch_log('Test_nl_write_err_file()') let job = job_start(s:python . " test_channel_pipe.py", \ {'err-io': 'file', 'err-name': 'Xoutput'}) @@ -600,10 +592,6 @@ func Test_nl_write_both_file() if !has('job') return endif - " TODO: make this work for MS-Windows - if !has('unix') - return - endif call ch_log('Test_nl_write_both_file()') let job = job_start(s:python . " test_channel_pipe.py", \ {'out-io': 'file', 'out-name': 'Xoutput', 'err-io': 'out'}) @@ -838,10 +826,6 @@ func Test_pipe_null() if !has('job') return endif - " TODO: implement this for MS-Windows - if !has('unix') - return - endif call ch_log('Test_pipe_null()') " We cannot check that no I/O works, we only check that the job starts diff --git a/src/version.c b/src/version.c index f27cd552c..e98a2ae6f 100644 --- a/src/version.c +++ b/src/version.c @@ -744,6 +744,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1526, +/**/ 1525, /**/ 1524, |