Mercurial > vim
comparison src/os_win32.c @ 2935:bf283e37792b v7.3.240
updated for version 7.3.240
Problem: External commands can't use pipes on MS-Windows.
Solution: Implement pipes and use them when 'shelltemp' isn't set. (Vincent
Berthoux)
author | Bram Moolenaar <bram@vim.org> |
---|---|
date | Thu, 07 Jul 2011 16:20:52 +0200 |
parents | ce1dce2af2a3 |
children | e5b17a5f6516 |
comparison
equal
deleted
inserted
replaced
2934:ba9df996e47c | 2935:bf283e37792b |
---|---|
415 static HANDLE advapi_lib = NULL; /* Handle for ADVAPI library */ | 415 static HANDLE advapi_lib = NULL; /* Handle for ADVAPI library */ |
416 static PSNSECINFO pSetNamedSecurityInfo; | 416 static PSNSECINFO pSetNamedSecurityInfo; |
417 static PGNSECINFO pGetNamedSecurityInfo; | 417 static PGNSECINFO pGetNamedSecurityInfo; |
418 #endif | 418 #endif |
419 | 419 |
420 typedef BOOL (WINAPI *PSETHANDLEINFORMATION)(HANDLE, DWORD, DWORD); | |
421 | |
422 static BOOL allowPiping = FALSE; | |
423 static PSETHANDLEINFORMATION pSetHandleInformation; | |
424 | |
420 /* | 425 /* |
421 * Set g_PlatformId to VER_PLATFORM_WIN32_NT (NT) or | 426 * Set g_PlatformId to VER_PLATFORM_WIN32_NT (NT) or |
422 * VER_PLATFORM_WIN32_WINDOWS (Win95). | 427 * VER_PLATFORM_WIN32_WINDOWS (Win95). |
423 */ | 428 */ |
424 void | 429 void |
465 advapi_lib = NULL; | 470 advapi_lib = NULL; |
466 } | 471 } |
467 } | 472 } |
468 } | 473 } |
469 #endif | 474 #endif |
475 /* | |
476 * If we are on windows NT, try to load the pipe functions, only | |
477 * available from Win2K. | |
478 */ | |
479 if (g_PlatformId == VER_PLATFORM_WIN32_NT) | |
480 { | |
481 HANDLE kernel32 = GetModuleHandle("kernel32"); | |
482 pSetHandleInformation = (PSETHANDLEINFORMATION)GetProcAddress( | |
483 kernel32, "SetHandleInformation"); | |
484 | |
485 allowPiping = pSetHandleInformation != NULL; | |
486 } | |
470 done = TRUE; | 487 done = TRUE; |
471 } | 488 } |
472 } | 489 } |
473 | 490 |
474 /* | 491 /* |
1633 return FALSE; | 1650 return FALSE; |
1634 return TRUE; | 1651 return TRUE; |
1635 } | 1652 } |
1636 | 1653 |
1637 #if ((defined(__MINGW32__) || defined (__CYGWIN32__)) && \ | 1654 #if ((defined(__MINGW32__) || defined (__CYGWIN32__)) && \ |
1638 __MSVCRT_VERSION__ >= 0x800) || (defined(_MSC_VER) && _MSC_VER >= 1400) | 1655 __MSVCRT_VERSION__ >= 0x800) || (defined(_MSC_VER) && _MSC_VER >= 1400) |
1639 /* | 1656 /* |
1640 * Bad parameter handler. | 1657 * Bad parameter handler. |
1641 * | 1658 * |
1642 * Certain MS CRT functions will intentionally crash when passed invalid | 1659 * Certain MS CRT functions will intentionally crash when passed invalid |
1643 * parameters to highlight possible security holes. Setting this function as | 1660 * parameters to highlight possible security holes. Setting this function as |
3208 * 2. Run the subprocess (it gets the allocated console by default) | 3225 * 2. Run the subprocess (it gets the allocated console by default) |
3209 * 3. Wait for the subprocess to terminate and get its exit code | 3226 * 3. Wait for the subprocess to terminate and get its exit code |
3210 * 4. Prompt the user to press a key to close the console window | 3227 * 4. Prompt the user to press a key to close the console window |
3211 */ | 3228 */ |
3212 static int | 3229 static int |
3213 mch_system(char *cmd, int options) | 3230 mch_system_classic(char *cmd, int options) |
3214 { | 3231 { |
3215 STARTUPINFO si; | 3232 STARTUPINFO si; |
3216 PROCESS_INFORMATION pi; | 3233 PROCESS_INFORMATION pi; |
3217 DWORD ret = 0; | 3234 DWORD ret = 0; |
3218 HWND hwnd = GetFocus(); | 3235 HWND hwnd = GetFocus(); |
3313 /* Try to get input focus back. Doesn't always work though. */ | 3330 /* Try to get input focus back. Doesn't always work though. */ |
3314 PostMessage(hwnd, WM_SETFOCUS, 0, 0); | 3331 PostMessage(hwnd, WM_SETFOCUS, 0, 0); |
3315 | 3332 |
3316 return ret; | 3333 return ret; |
3317 } | 3334 } |
3335 | |
3336 /* | |
3337 * Thread launched by the gui to send the current buffer data to the | |
3338 * process. This way avoid to hang up vim totally if the children | |
3339 * process take a long time to process the lines. | |
3340 */ | |
3341 static DWORD WINAPI | |
3342 sub_process_writer(LPVOID param) | |
3343 { | |
3344 HANDLE g_hChildStd_IN_Wr = param; | |
3345 linenr_T lnum = curbuf->b_op_start.lnum; | |
3346 DWORD len = 0; | |
3347 DWORD l; | |
3348 char_u *lp = ml_get(lnum); | |
3349 char_u *s; | |
3350 int written = 0; | |
3351 | |
3352 for (;;) | |
3353 { | |
3354 l = (DWORD)STRLEN(lp + written); | |
3355 if (l == 0) | |
3356 len = 0; | |
3357 else if (lp[written] == NL) | |
3358 { | |
3359 /* NL -> NUL translation */ | |
3360 WriteFile(g_hChildStd_IN_Wr, "", 1, &len, NULL); | |
3361 } | |
3362 else | |
3363 { | |
3364 s = vim_strchr(lp + written, NL); | |
3365 WriteFile(g_hChildStd_IN_Wr, (char *)lp + written, | |
3366 s == NULL ? l : (DWORD)(s - (lp + written)), | |
3367 &len, NULL); | |
3368 } | |
3369 if (len == (int)l) | |
3370 { | |
3371 /* Finished a line, add a NL, unless this line should not have | |
3372 * one. */ | |
3373 if (lnum != curbuf->b_op_end.lnum | |
3374 || !curbuf->b_p_bin | |
3375 || (lnum != curbuf->b_no_eol_lnum | |
3376 && (lnum != curbuf->b_ml.ml_line_count | |
3377 || curbuf->b_p_eol))) | |
3378 { | |
3379 WriteFile(g_hChildStd_IN_Wr, "\n", 1, &ignored, NULL); | |
3380 } | |
3381 | |
3382 ++lnum; | |
3383 if (lnum > curbuf->b_op_end.lnum) | |
3384 break; | |
3385 | |
3386 lp = ml_get(lnum); | |
3387 written = 0; | |
3388 } | |
3389 else if (len > 0) | |
3390 written += len; | |
3391 } | |
3392 | |
3393 /* finished all the lines, close pipe */ | |
3394 CloseHandle(g_hChildStd_IN_Wr); | |
3395 ExitThread(0); | |
3396 } | |
3397 | |
3398 | |
3399 # define BUFLEN 100 /* length for buffer, stolen from unix version */ | |
3400 | |
3401 /* | |
3402 * This function read from the children's stdout and write the | |
3403 * data on screen or in the buffer accordingly. | |
3404 */ | |
3405 static void | |
3406 dump_pipe(int options, | |
3407 HANDLE g_hChildStd_OUT_Rd, | |
3408 garray_T *ga, | |
3409 char_u buffer[], | |
3410 DWORD *buffer_off) | |
3411 { | |
3412 DWORD availableBytes = 0; | |
3413 DWORD i; | |
3414 int c; | |
3415 char_u *p; | |
3416 int ret; | |
3417 DWORD len; | |
3418 DWORD toRead; | |
3419 int repeatCount; | |
3420 | |
3421 /* we query the pipe to see if there is any data to read | |
3422 * to avoid to perform a blocking read */ | |
3423 ret = PeekNamedPipe(g_hChildStd_OUT_Rd, /* pipe to query */ | |
3424 NULL, /* optional buffer */ | |
3425 0, /* buffe size */ | |
3426 NULL, /* number of read bytes */ | |
3427 &availableBytes, /* available bytes total */ | |
3428 NULL); /* byteLeft */ | |
3429 | |
3430 repeatCount = 0; | |
3431 /* We got real data in the pipe, read it */ | |
3432 while (ret != 0 && availableBytes > 0 && availableBytes > 0) | |
3433 { | |
3434 repeatCount++; | |
3435 toRead = | |
3436 # ifdef FEAT_MBYTE | |
3437 (DWORD)(BUFLEN - *buffer_off); | |
3438 # else | |
3439 (DWORD)BUFLEN; | |
3440 # endif | |
3441 toRead = availableBytes < toRead ? availableBytes : toRead; | |
3442 ReadFile(g_hChildStd_OUT_Rd, buffer | |
3443 # ifdef FEAT_MBYTE | |
3444 + *buffer_off, toRead | |
3445 # else | |
3446 , toRead | |
3447 # endif | |
3448 , &len, NULL); | |
3449 | |
3450 /* If we haven't read anything, there is a problem */ | |
3451 if (len == 0) | |
3452 break; | |
3453 | |
3454 availableBytes -= len; | |
3455 | |
3456 if (options & SHELL_READ) | |
3457 { | |
3458 /* Do NUL -> NL translation, append NL separated | |
3459 * lines to the current buffer. */ | |
3460 for (i = 0; i < len; ++i) | |
3461 { | |
3462 if (buffer[i] == NL) | |
3463 append_ga_line(ga); | |
3464 else if (buffer[i] == NUL) | |
3465 ga_append(ga, NL); | |
3466 else | |
3467 ga_append(ga, buffer[i]); | |
3468 } | |
3469 } | |
3470 # ifdef FEAT_MBYTE | |
3471 else if (has_mbyte) | |
3472 { | |
3473 int l; | |
3474 | |
3475 len += *buffer_off; | |
3476 buffer[len] = NUL; | |
3477 | |
3478 /* Check if the last character in buffer[] is | |
3479 * incomplete, keep these bytes for the next | |
3480 * round. */ | |
3481 for (p = buffer; p < buffer + len; p += l) | |
3482 { | |
3483 l = mb_cptr2len(p); | |
3484 if (l == 0) | |
3485 l = 1; /* NUL byte? */ | |
3486 else if (MB_BYTE2LEN(*p) != l) | |
3487 break; | |
3488 } | |
3489 if (p == buffer) /* no complete character */ | |
3490 { | |
3491 /* avoid getting stuck at an illegal byte */ | |
3492 if (len >= 12) | |
3493 ++p; | |
3494 else | |
3495 { | |
3496 *buffer_off = len; | |
3497 return; | |
3498 } | |
3499 } | |
3500 c = *p; | |
3501 *p = NUL; | |
3502 msg_puts(buffer); | |
3503 if (p < buffer + len) | |
3504 { | |
3505 *p = c; | |
3506 *buffer_off = (DWORD)((buffer + len) - p); | |
3507 mch_memmove(buffer, p, *buffer_off); | |
3508 return; | |
3509 } | |
3510 *buffer_off = 0; | |
3511 } | |
3512 # endif /* FEAT_MBYTE */ | |
3513 else | |
3514 { | |
3515 buffer[len] = NUL; | |
3516 msg_puts(buffer); | |
3517 } | |
3518 | |
3519 windgoto(msg_row, msg_col); | |
3520 cursor_on(); | |
3521 out_flush(); | |
3522 } | |
3523 } | |
3524 | |
3525 /* | |
3526 * Version of system to use for windows NT > 5.0 (Win2K), use pipe | |
3527 * for communication and doesn't open any new window. | |
3528 */ | |
3529 static int | |
3530 mch_system_piped(char *cmd, int options) | |
3531 { | |
3532 STARTUPINFO si; | |
3533 PROCESS_INFORMATION pi; | |
3534 DWORD ret = 0; | |
3535 | |
3536 HANDLE g_hChildStd_IN_Rd = NULL; | |
3537 HANDLE g_hChildStd_IN_Wr = NULL; | |
3538 HANDLE g_hChildStd_OUT_Rd = NULL; | |
3539 HANDLE g_hChildStd_OUT_Wr = NULL; | |
3540 | |
3541 char_u buffer[BUFLEN + 1]; /* reading buffer + size */ | |
3542 DWORD len; | |
3543 | |
3544 /* buffer used to receive keys */ | |
3545 char_u ta_buf[BUFLEN + 1]; /* TypeAHead */ | |
3546 int ta_len = 0; /* valid bytes in ta_buf[] */ | |
3547 | |
3548 DWORD i; | |
3549 int c; | |
3550 int noread_cnt = 0; | |
3551 garray_T ga; | |
3552 int delay = 1; | |
3553 # ifdef FEAT_MBYTE | |
3554 DWORD buffer_off = 0; /* valid bytes in buffer[] */ | |
3555 # endif | |
3556 | |
3557 SECURITY_ATTRIBUTES saAttr; | |
3558 | |
3559 /* Set the bInheritHandle flag so pipe handles are inherited. */ | |
3560 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); | |
3561 saAttr.bInheritHandle = TRUE; | |
3562 saAttr.lpSecurityDescriptor = NULL; | |
3563 | |
3564 if ( ! CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &saAttr, 0) | |
3565 /* Ensure the read handle to the pipe for STDOUT is not inherited. */ | |
3566 || ! pSetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0) | |
3567 /* Create a pipe for the child process's STDIN. */ | |
3568 || ! CreatePipe(&g_hChildStd_IN_Rd, &g_hChildStd_IN_Wr, &saAttr, 0) | |
3569 /* Ensure the write handle to the pipe for STDIN is not inherited. */ | |
3570 || ! pSetHandleInformation(g_hChildStd_IN_Wr, HANDLE_FLAG_INHERIT, 0) ) | |
3571 { | |
3572 CloseHandle(g_hChildStd_IN_Rd); | |
3573 CloseHandle(g_hChildStd_IN_Wr); | |
3574 CloseHandle(g_hChildStd_OUT_Rd); | |
3575 CloseHandle(g_hChildStd_OUT_Wr); | |
3576 MSG_PUTS(_("\nCannot create pipes\n")); | |
3577 } | |
3578 | |
3579 si.cb = sizeof(si); | |
3580 si.lpReserved = NULL; | |
3581 si.lpDesktop = NULL; | |
3582 si.lpTitle = NULL; | |
3583 si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; | |
3584 | |
3585 /* set-up our file redirection */ | |
3586 si.hStdError = g_hChildStd_OUT_Wr; | |
3587 si.hStdOutput = g_hChildStd_OUT_Wr; | |
3588 si.hStdInput = g_hChildStd_IN_Rd; | |
3589 si.wShowWindow = SW_HIDE; | |
3590 si.cbReserved2 = 0; | |
3591 si.lpReserved2 = NULL; | |
3592 | |
3593 if (options & SHELL_READ) | |
3594 ga_init2(&ga, 1, BUFLEN); | |
3595 | |
3596 /* Now, run the command */ | |
3597 CreateProcess(NULL, /* Executable name */ | |
3598 cmd, /* Command to execute */ | |
3599 NULL, /* Process security attributes */ | |
3600 NULL, /* Thread security attributes */ | |
3601 | |
3602 // this command can be litigeous, handle inheritence was | |
3603 // deactivated for pending temp file, but, if we deactivate | |
3604 // it, the pipes don't work for some reason. | |
3605 TRUE, /* Inherit handles, first deactivated, | |
3606 * but needed */ | |
3607 CREATE_DEFAULT_ERROR_MODE, /* Creation flags */ | |
3608 NULL, /* Environment */ | |
3609 NULL, /* Current directory */ | |
3610 &si, /* Startup information */ | |
3611 &pi); /* Process information */ | |
3612 | |
3613 | |
3614 /* Close our unused side of the pipes */ | |
3615 CloseHandle(g_hChildStd_IN_Rd); | |
3616 CloseHandle(g_hChildStd_OUT_Wr); | |
3617 | |
3618 if (options & SHELL_WRITE) | |
3619 { | |
3620 HANDLE thread = | |
3621 CreateThread(NULL, /* security attributes */ | |
3622 0, /* default stack size */ | |
3623 sub_process_writer, /* function to be executed */ | |
3624 g_hChildStd_IN_Wr, /* parameter */ | |
3625 0, /* creation flag, start immediately */ | |
3626 NULL); /* we don't care about thread id */ | |
3627 CloseHandle(thread); | |
3628 g_hChildStd_IN_Wr = NULL; | |
3629 } | |
3630 | |
3631 /* Keep updating the window while waiting for the shell to finish. */ | |
3632 for (;;) | |
3633 { | |
3634 MSG msg; | |
3635 | |
3636 if (PeekMessage(&msg, (HWND)NULL, 0, 0, PM_REMOVE)) | |
3637 { | |
3638 TranslateMessage(&msg); | |
3639 DispatchMessage(&msg); | |
3640 } | |
3641 | |
3642 /* write pipe information in the window */ | |
3643 if ((options & (SHELL_READ|SHELL_WRITE)) | |
3644 # ifdef FEAT_GUI | |
3645 || gui.in_use | |
3646 # endif | |
3647 ) | |
3648 { | |
3649 len = 0; | |
3650 if (!(options & SHELL_EXPAND) | |
3651 && ((options & | |
3652 (SHELL_READ|SHELL_WRITE|SHELL_COOKED)) | |
3653 != (SHELL_READ|SHELL_WRITE|SHELL_COOKED) | |
3654 # ifdef FEAT_GUI | |
3655 || gui.in_use | |
3656 # endif | |
3657 ) | |
3658 && (ta_len > 0 || noread_cnt > 4)) | |
3659 { | |
3660 if (ta_len == 0) | |
3661 { | |
3662 /* Get extra characters when we don't have any. Reset the | |
3663 * counter and timer. */ | |
3664 noread_cnt = 0; | |
3665 # if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H) | |
3666 gettimeofday(&start_tv, NULL); | |
3667 # endif | |
3668 len = ui_inchar(ta_buf, BUFLEN, 10L, 0); | |
3669 } | |
3670 if (ta_len > 0 || len > 0) | |
3671 { | |
3672 /* | |
3673 * For pipes: Check for CTRL-C: send interrupt signal to | |
3674 * child. Check for CTRL-D: EOF, close pipe to child. | |
3675 */ | |
3676 if (len == 1 && cmd != NULL) | |
3677 { | |
3678 if (ta_buf[ta_len] == Ctrl_C) | |
3679 { | |
3680 /* Learn what exit code is expected, for | |
3681 * now put 9 as SIGKILL */ | |
3682 TerminateProcess(pi.hProcess, 9); | |
3683 } | |
3684 if (ta_buf[ta_len] == Ctrl_D) | |
3685 { | |
3686 CloseHandle(g_hChildStd_IN_Wr); | |
3687 g_hChildStd_IN_Wr = NULL; | |
3688 } | |
3689 } | |
3690 | |
3691 /* replace K_BS by <BS> and K_DEL by <DEL> */ | |
3692 for (i = ta_len; i < ta_len + len; ++i) | |
3693 { | |
3694 if (ta_buf[i] == CSI && len - i > 2) | |
3695 { | |
3696 c = TERMCAP2KEY(ta_buf[i + 1], ta_buf[i + 2]); | |
3697 if (c == K_DEL || c == K_KDEL || c == K_BS) | |
3698 { | |
3699 mch_memmove(ta_buf + i + 1, ta_buf + i + 3, | |
3700 (size_t)(len - i - 2)); | |
3701 if (c == K_DEL || c == K_KDEL) | |
3702 ta_buf[i] = DEL; | |
3703 else | |
3704 ta_buf[i] = Ctrl_H; | |
3705 len -= 2; | |
3706 } | |
3707 } | |
3708 else if (ta_buf[i] == '\r') | |
3709 ta_buf[i] = '\n'; | |
3710 # ifdef FEAT_MBYTE | |
3711 if (has_mbyte) | |
3712 i += (*mb_ptr2len_len)(ta_buf + i, | |
3713 ta_len + len - i) - 1; | |
3714 # endif | |
3715 } | |
3716 | |
3717 /* | |
3718 * For pipes: echo the typed characters. For a pty this | |
3719 * does not seem to work. | |
3720 */ | |
3721 for (i = ta_len; i < ta_len + len; ++i) | |
3722 { | |
3723 if (ta_buf[i] == '\n' || ta_buf[i] == '\b') | |
3724 msg_putchar(ta_buf[i]); | |
3725 # ifdef FEAT_MBYTE | |
3726 else if (has_mbyte) | |
3727 { | |
3728 int l = (*mb_ptr2len)(ta_buf + i); | |
3729 | |
3730 msg_outtrans_len(ta_buf + i, l); | |
3731 i += l - 1; | |
3732 } | |
3733 # endif | |
3734 else | |
3735 msg_outtrans_len(ta_buf + i, 1); | |
3736 } | |
3737 windgoto(msg_row, msg_col); | |
3738 out_flush(); | |
3739 | |
3740 ta_len += len; | |
3741 | |
3742 /* | |
3743 * Write the characters to the child, unless EOF has been | |
3744 * typed for pipes. Write one character at a time, to | |
3745 * avoid losing too much typeahead. When writing buffer | |
3746 * lines, drop the typed characters (only check for | |
3747 * CTRL-C). | |
3748 */ | |
3749 if (options & SHELL_WRITE) | |
3750 ta_len = 0; | |
3751 else if (g_hChildStd_IN_Wr != NULL) | |
3752 { | |
3753 WriteFile(g_hChildStd_IN_Wr, (char*)ta_buf, | |
3754 1, &len, NULL); | |
3755 // if we are typing in, we want to keep things reactive | |
3756 delay = 1; | |
3757 if (len > 0) | |
3758 { | |
3759 ta_len -= len; | |
3760 mch_memmove(ta_buf, ta_buf + len, ta_len); | |
3761 } | |
3762 } | |
3763 } | |
3764 } | |
3765 } | |
3766 | |
3767 if (ta_len) | |
3768 ui_inchar_undo(ta_buf, ta_len); | |
3769 | |
3770 if (WaitForSingleObject(pi.hProcess, delay) != WAIT_TIMEOUT) | |
3771 { | |
3772 dump_pipe(options, g_hChildStd_OUT_Rd, | |
3773 &ga, buffer, &buffer_off); | |
3774 break; | |
3775 } | |
3776 | |
3777 ++noread_cnt; | |
3778 dump_pipe(options, g_hChildStd_OUT_Rd, | |
3779 &ga, buffer, &buffer_off); | |
3780 | |
3781 /* We start waiting for a very short time and then increase it, so | |
3782 * that we respond quickly when the process is quick, and don't | |
3783 * consume too much overhead when it's slow. */ | |
3784 if (delay < 50) | |
3785 delay += 10; | |
3786 } | |
3787 | |
3788 /* Close the pipe */ | |
3789 CloseHandle(g_hChildStd_OUT_Rd); | |
3790 if (g_hChildStd_IN_Wr != NULL) | |
3791 CloseHandle(g_hChildStd_IN_Wr); | |
3792 | |
3793 WaitForSingleObject(pi.hProcess, INFINITE); | |
3794 | |
3795 /* Get the command exit code */ | |
3796 GetExitCodeProcess(pi.hProcess, &ret); | |
3797 | |
3798 if (options & SHELL_READ) | |
3799 { | |
3800 if (ga.ga_len > 0) | |
3801 { | |
3802 append_ga_line(&ga); | |
3803 /* remember that the NL was missing */ | |
3804 curbuf->b_no_eol_lnum = curwin->w_cursor.lnum; | |
3805 } | |
3806 else | |
3807 curbuf->b_no_eol_lnum = 0; | |
3808 ga_clear(&ga); | |
3809 } | |
3810 | |
3811 /* Close the handles to the subprocess, so that it goes away */ | |
3812 CloseHandle(pi.hThread); | |
3813 CloseHandle(pi.hProcess); | |
3814 | |
3815 return ret; | |
3816 } | |
3817 | |
3818 static int | |
3819 mch_system(char *cmd, int options) | |
3820 { | |
3821 /* if we can pipe and the shelltemp option is off */ | |
3822 if (allowPiping && !p_stmp) | |
3823 return mch_system_piped(cmd, options); | |
3824 else | |
3825 return mch_system_classic(cmd, options); | |
3826 } | |
3318 #else | 3827 #else |
3319 | 3828 |
3320 # define mch_system(c, o) system(c) | 3829 # define mch_system(c, o) system(c) |
3321 | 3830 |
3322 #endif | 3831 #endif |
3386 { | 3895 { |
3387 /* we use "command" or "cmd" to start the shell; slow but easy */ | 3896 /* we use "command" or "cmd" to start the shell; slow but easy */ |
3388 char_u *newcmd; | 3897 char_u *newcmd; |
3389 long_u cmdlen = ( | 3898 long_u cmdlen = ( |
3390 #ifdef FEAT_GUI_W32 | 3899 #ifdef FEAT_GUI_W32 |
3391 STRLEN(vimrun_path) + | 3900 (allowPiping && !p_stmp ? 0 : STRLEN(vimrun_path)) + |
3392 #endif | 3901 #endif |
3393 STRLEN(p_sh) + STRLEN(p_shcf) + STRLEN(cmd) + 10); | 3902 STRLEN(p_sh) + STRLEN(p_shcf) + STRLEN(cmd) + 10); |
3394 | 3903 |
3395 newcmd = lalloc(cmdlen, TRUE); | 3904 newcmd = lalloc(cmdlen, TRUE); |
3396 if (newcmd != NULL) | 3905 if (newcmd != NULL) |
3495 "See :help win32-vimrun for more information."), | 4004 "See :help win32-vimrun for more information."), |
3496 _("Vim Warning"), | 4005 _("Vim Warning"), |
3497 MB_ICONWARNING); | 4006 MB_ICONWARNING); |
3498 need_vimrun_warning = FALSE; | 4007 need_vimrun_warning = FALSE; |
3499 } | 4008 } |
3500 if (!s_dont_use_vimrun) | 4009 if (!s_dont_use_vimrun && (!allowPiping || p_stmp)) |
3501 /* Use vimrun to execute the command. It opens a console | 4010 /* Use vimrun to execute the command. It opens a console |
3502 * window, which can be closed without killing Vim. */ | 4011 * window, which can be closed without killing Vim. */ |
3503 vim_snprintf((char *)newcmd, cmdlen, "%s%s%s %s %s", | 4012 vim_snprintf((char *)newcmd, cmdlen, "%s%s%s %s %s", |
3504 vimrun_path, | 4013 vimrun_path, |
3505 (msg_silent != 0 || (options & SHELL_DOOUT)) | 4014 (msg_silent != 0 || (options & SHELL_DOOUT)) |
3519 settmode(TMODE_RAW); /* set to raw mode */ | 4028 settmode(TMODE_RAW); /* set to raw mode */ |
3520 | 4029 |
3521 /* Print the return value, unless "vimrun" was used. */ | 4030 /* Print the return value, unless "vimrun" was used. */ |
3522 if (x != 0 && !(options & SHELL_SILENT) && !emsg_silent | 4031 if (x != 0 && !(options & SHELL_SILENT) && !emsg_silent |
3523 #if defined(FEAT_GUI_W32) | 4032 #if defined(FEAT_GUI_W32) |
3524 && ((options & SHELL_DOOUT) || s_dont_use_vimrun) | 4033 && ((options & SHELL_DOOUT) || s_dont_use_vimrun |
4034 || (allowPiping && !p_stmp)) | |
3525 #endif | 4035 #endif |
3526 ) | 4036 ) |
3527 { | 4037 { |
3528 smsg(_("shell returned %d"), x); | 4038 smsg(_("shell returned %d"), x); |
3529 msg_putchar('\n'); | 4039 msg_putchar('\n'); |