blob: 9a4c076d63f02138c8a0ffc4cf91e457ef56b036 [file] [log] [blame]
Bram Moolenaaredf3f972016-08-29 22:49:24 +02001/* vi:set ts=8 sts=4 sw=4 noet:
Bram Moolenaar071d4272004-06-13 20:20:40 +00002 *
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>
Bram Moolenaarbcc1dcc2016-08-10 22:02:40 +020020#include <conio.h>
21#ifndef WIN32_LEAN_AND_MEAN
22# define WIN32_LEAN_AND_MEAN
Bram Moolenaar071d4272004-06-13 20:20:40 +000023#endif
Bram Moolenaarbcc1dcc2016-08-10 22:02:40 +020024#include <windows.h>
Bram Moolenaar071d4272004-06-13 20:20:40 +000025
Bram Moolenaar071d4272004-06-13 20:20:40 +000026 int
27main(void)
28{
Bram Moolenaarbcc1dcc2016-08-10 22:02:40 +020029 const wchar_t *p;
Bram Moolenaar2efc44b2019-10-05 12:09:32 +020030 wchar_t *cmd;
31 size_t cmdlen;
Bram Moolenaarbcc1dcc2016-08-10 22:02:40 +020032 int retval;
33 int inquote = 0;
34 int silent = 0;
35 HANDLE hstdout;
36 DWORD written;
Bram Moolenaar071d4272004-06-13 20:20:40 +000037
Bram Moolenaarbcc1dcc2016-08-10 22:02:40 +020038 p = (const wchar_t *)GetCommandLineW();
39
Bram Moolenaar071d4272004-06-13 20:20:40 +000040 /*
41 * Skip the executable name, which might be in "".
42 */
43 while (*p)
44 {
Bram Moolenaarbcc1dcc2016-08-10 22:02:40 +020045 if (*p == L'"')
Bram Moolenaar071d4272004-06-13 20:20:40 +000046 inquote = !inquote;
Bram Moolenaarbcc1dcc2016-08-10 22:02:40 +020047 else if (!inquote && *p == L' ')
Bram Moolenaar071d4272004-06-13 20:20:40 +000048 {
49 ++p;
50 break;
51 }
52 ++p;
53 }
Bram Moolenaarbcc1dcc2016-08-10 22:02:40 +020054 while (*p == L' ')
Bram Moolenaar792f0e32018-02-27 17:27:13 +010055 ++p;
Bram Moolenaar071d4272004-06-13 20:20:40 +000056
57 /*
58 * "-s" argument: don't wait for a key hit.
59 */
Bram Moolenaarbcc1dcc2016-08-10 22:02:40 +020060 if (p[0] == L'-' && p[1] == L's' && p[2] == L' ')
Bram Moolenaar071d4272004-06-13 20:20:40 +000061 {
62 silent = 1;
63 p += 3;
Bram Moolenaarbcc1dcc2016-08-10 22:02:40 +020064 while (*p == L' ')
Bram Moolenaar071d4272004-06-13 20:20:40 +000065 ++p;
66 }
67
Bram Moolenaar2efc44b2019-10-05 12:09:32 +020068 // Print the command, including quotes and redirection.
Bram Moolenaarbcc1dcc2016-08-10 22:02:40 +020069 hstdout = GetStdHandle(STD_OUTPUT_HANDLE);
70 WriteConsoleW(hstdout, p, wcslen(p), &written, NULL);
71 WriteConsoleW(hstdout, L"\r\n", 2, &written, NULL);
Bram Moolenaar071d4272004-06-13 20:20:40 +000072
Bram Moolenaar2efc44b2019-10-05 12:09:32 +020073 // 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;
Bram Moolenaar51b6eb42020-08-22 15:19:18 +020080 cmd = malloc(cmdlen * sizeof(wchar_t));
Bram Moolenaar2efc44b2019-10-05 12:09:32 +020081 if (cmd == NULL)
82 {
83 perror("vimrun malloc(): ");
84 return -1;
85 }
86 _snwprintf(cmd, cmdlen, L"(%s)", p);
87 p = cmd;
88 }
89
Bram Moolenaar071d4272004-06-13 20:20:40 +000090 /*
91 * Do it!
92 */
Bram Moolenaarbcc1dcc2016-08-10 22:02:40 +020093 retval = _wsystem(p);
Bram Moolenaar071d4272004-06-13 20:20:40 +000094
Bram Moolenaar2efc44b2019-10-05 12:09:32 +020095 if (cmd)
96 free(cmd);
97
Bram Moolenaar9964e462007-05-05 17:54:07 +000098 if (retval == -1)
99 perror("vimrun system(): ");
100 else if (retval != 0)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000101 printf("shell returned %d\n", retval);
102
103 if (!silent)
104 {
105 puts("Hit any key to close this window...");
106
Bram Moolenaar071d4272004-06-13 20:20:40 +0000107 while (_kbhit())
108 (void)_getch();
Bram Moolenaar071d4272004-06-13 20:20:40 +0000109 (void)_getch();
110 }
111
112 return retval;
113}