]> granicus.if.org Git - vim/commitdiff
patch 7.4.1526 v7.4.1526
authorBram Moolenaar <Bram@vim.org>
Wed, 9 Mar 2016 19:54:51 +0000 (20:54 +0100)
committerBram Moolenaar <Bram@vim.org>
Wed, 9 Mar 2016 19:54:51 +0000 (20:54 +0100)
Problem:    Writing to file and not connecting a channel doesn't work for
            MS-Windows.
Solution:   Make it work. (Yasuhiro Matsumoto)

src/os_win32.c
src/testdir/test_channel.vim
src/version.c

index 3e2e75279a9da270fa18e1cb7ae23b4a70a6f497..a59cad2ca1a48ca9544c1d5f61fa4653f5a8d57e 100644 (file)
@@ -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;
 
index 3b15568f2ff59831915c663334d5bfe59d8d6604..12a101e481414cdc630da2383b36590015e7eee1 100644 (file)
@@ -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
index f27cd552c9470080834afa6992f5c51b54b87f09..e98a2ae6fe6ce8f6dc7af4c8633c5bf0ed6cc595 100644 (file)
@@ -743,6 +743,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1526,
 /**/
     1525,
 /**/