Commit deb4d95
John Howard
Windows:Have native CommandLine in Process
Signed-off-by: John Howard <jhoward@microsoft.com>
This adds a new field `CommandLine` in the `Process` structure for use
on Windows. A Windows runtime will check this first and use it as-is when
launching WCOW processes in a container. If omitted, the Windows runtime
will fall back to the previous behaviour of escaping (eg Windows.EscapeArg
in golang) each of the `args` array elements, and space-concatenating them.
The reason for this change is to avoid loss of fidelity for launching
processes. One such example is the following:
`cmd /S /C mkdir "c:/foo"`
When parsed into a JSON array such as `Args`, it becomes 5 elements
- cmd
- /S
- /C
- mkdir
- c:/foo
Here, note the lost information being the double-quotes around `c:/foo`.
When using the required contenation, space separation required on Windows,
(https://github.com/golang/sys/blob/c4afb3effaa53fd9a06ca61262dc7ce8df4c081b/windows/exec_windows.go#L9-L18),
this becomes the following command line:
`cmd /S /C mkdir c:/foo`
When the double-quotes are missing, mkdir would fail, but with the
double-quotes, it succeeds as expected:
```
C:\>cmd /s /c mkdir c:/foo
The syntax of the command is incorrect.
C:\>cmd /s /c mkdir "c:/foo"
C:\>
```
The addition of a full `commandLine` in Process for use on Windows alleviates
issues where fidelity can be lost.
Some further background:
For historical reasons, Windows only has native support for launching
processes using a command line. It does not support an argument array as
per Linux. See the `CreateProcess` API documentation on MSDN.
What happens under the covers is that prior to invoking a programs
main, the language runtime will convert the command line to a set of argv[]
suach as in the C-style `int main(int argc, char* argv), or the golang
`os.Args` prior to the programs `main` being invoked, using Windows-
specific rules.
In go, that's the `commandLineToArgv` function which is called in the init()
function of the os package https://github.com/golang/go/blob/ff7b245a31394b700a252fd547cf16ad0ad838b6/src/os/exec_windows.go#L100,
In the Microsoft C++ startup code, it does exactly the same processing
as documented here prior to invoking main itself:
https://docs.microsoft.com/en-us/cpp/cpp/parsing-cpp-command-line-arguments?view=vs-2017.
The processing it describes is documented at
https://msdn.microsoft.com/en-us/library/windows/desktop/ms683156(v=vs.85).aspx and
https://docs.microsoft.com/en-us/windows/desktop/api/shellapi/nf-shellapi-commandlinetoargvw
Some related links which provide a lot more information about the
very specific (and unique to Windows) command line escaping rules,
and handling of them are below:
https://blogs.msdn.microsoft.com/twistylittlepassagesallalike/2011/04/23/everyone-quotes-command-line-arguments-the-wrong-way/
https://stackoverflow.com/questions/31838469/how-do-i-convert-argv-to-lpcommandline-parameter-of-createprocess
https://docs.microsoft.com/en-us/cpp/cpp/parsing-cpp-command-line-arguments?view=vs-20171 parent 1722abf commit deb4d95
3 files changed
+12
-5
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
155 | 155 | | |
156 | 156 | | |
157 | 157 | | |
158 | | - | |
159 | | - | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
160 | 163 | | |
161 | 164 | | |
162 | 165 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
50 | 50 | | |
51 | 51 | | |
52 | 52 | | |
53 | | - | |
54 | | - | |
| 53 | + | |
55 | 54 | | |
56 | 55 | | |
57 | 56 | | |
58 | 57 | | |
59 | 58 | | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
60 | 62 | | |
61 | 63 | | |
62 | 64 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
38 | 38 | | |
39 | 39 | | |
40 | 40 | | |
41 | | - | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
42 | 44 | | |
43 | 45 | | |
44 | 46 | | |
| |||
0 commit comments