1 /* vi:set ts=8 sts=4 sw=4 noet:
2  *
3  * VIM - Vi IMproved	by Bram Moolenaar
4  *			this file by Vince Negri
5  *
6  * Do ":help uganda"  in Vim to read copying and usage conditions.
7  * Do ":help credits" in Vim to see a list of people who contributed.
8  * See README.txt for an overview of the Vim source code.
9  */
10 
11 /*
12  * vimrun.c - Tiny Win32 program to safely run an external command in a
13  *	      DOS console.
14  *	      This program is required to avoid that typing CTRL-C in the DOS
15  *	      console kills Vim.  Now it only kills vimrun.
16  */
17 
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <conio.h>
21 #ifndef WIN32_LEAN_AND_MEAN
22 # define WIN32_LEAN_AND_MEAN
23 #endif
24 #include <windows.h>
25 
26     int
main(void)27 main(void)
28 {
29     const wchar_t   *p;
30     wchar_t	    *cmd;
31     size_t	    cmdlen;
32     int		    retval;
33     int		    inquote = 0;
34     int		    silent = 0;
35     HANDLE	    hstdout;
36     DWORD	    written;
37 
38     p = (const wchar_t *)GetCommandLineW();
39 
40     /*
41      * Skip the executable name, which might be in "".
42      */
43     while (*p)
44     {
45 	if (*p == L'"')
46 	    inquote = !inquote;
47 	else if (!inquote && *p == L' ')
48 	{
49 	    ++p;
50 	    break;
51 	}
52 	++p;
53     }
54     while (*p == L' ')
55 	++p;
56 
57     /*
58      * "-s" argument: don't wait for a key hit.
59      */
60     if (p[0] == L'-' && p[1] == L's' && p[2] == L' ')
61     {
62 	silent = 1;
63 	p += 3;
64 	while (*p == L' ')
65 	    ++p;
66     }
67 
68     // Print the command, including quotes and redirection.
69     hstdout = GetStdHandle(STD_OUTPUT_HANDLE);
70     WriteConsoleW(hstdout, p, wcslen(p), &written, NULL);
71     WriteConsoleW(hstdout, L"\r\n", 2, &written, NULL);
72 
73     // If the command starts and ends with double quotes,
74     // Enclose the command in parentheses.
75     cmd = NULL;
76     cmdlen = wcslen(p);
77     if (cmdlen >= 2 && p[0] == L'"' && p[cmdlen - 1] == L'"')
78     {
79 	cmdlen += 3;
80 	cmd = malloc(cmdlen * sizeof(wchar_t));
81 	if (cmd == NULL)
82 	{
83 	    perror("vimrun malloc(): ");
84 	    return -1;
85 	}
86 	_snwprintf(cmd, cmdlen, L"(%s)", p);
87 	p = cmd;
88     }
89 
90     /*
91      * Do it!
92      */
93     retval = _wsystem(p);
94 
95     if (cmd)
96 	free(cmd);
97 
98     if (retval == -1)
99 	perror("vimrun system(): ");
100     else if (retval != 0)
101 	printf("shell returned %d\n", retval);
102 
103     if (!silent)
104     {
105 	puts("Hit any key to close this window...");
106 
107 	while (_kbhit())
108 	    (void)_getch();
109 	(void)_getch();
110     }
111 
112     return retval;
113 }
114