summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2016-03-09 20:54:51 +0100
committerBram Moolenaar <Bram@vim.org>2016-03-09 20:54:51 +0100
commitd5d3d307ddb824f59a2f2516c4b6a6d48762aa58 (patch)
tree5650674d76b7526a6e625fb41700205e052e85b6
parentbeb003b303cde1e55634aae9f810535684b76211 (diff)
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.c121
-rw-r--r--src/testdir/test_channel.vim16
-rw-r--r--src/version.c2
3 files changed, 54 insertions, 85 deletions
diff --git a/src/os_win32.c b/src/os_win32.c
index 3e2e75279a..a59cad2ca1 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 3b15568f2f..12a101e481 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 f27cd552c9..e98a2ae6fe 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,