4 ms·
I'm absolutely amazed that Windows doesn't offer a process spawning API that takes an array of strings as arguments[0], if only because that's exactly how a C p
by tetrep 10y ago
I'm absolutely amazed that Windows doesn't offer a process spawning API that takes an array of strings as arguments[0], if only because that's exactly how a C program expects them anyway.
[0]: https://linux.die.net/man/3/exec https://linux.die.net/man/3/exec
- dom0 10y agoThese APIs do exist, they just don't work that way: > These functions appear to be precisely what we need: they take an arbitrary number of distinct command line arguments and promise to launch a subprocess. Unfortunately and counter-intuitively, these functions do not quote or process these arguments: instead, they’re all concatenated into a single string, with arguments separated spaces
- Dylan16807 10y agoOr in other words, those APIs don't exist, and mentioning a function that has the same C-type but does something totally different is trivia at best.
- dom0 10y ago... which is exactly my point. They apparently exist, and would even appear to work correctly, until some scrutiny is applied.
- Dylan16807 10y ago> They apparently exist[...]until some scrutiny is applied. But that's the opposite of "does exist"?
- asveikau 10y agoWhen you get to the Windows kernel, the command line is a single PWSTR. Full stop. Any API or C program main() running on Windows that suggests anything else is fiction - the C runtime parsing what the kernel gave it to a string array on one side, or concatenating into a single string on the other.
- quotemstr 10y agoWell, it's actually a UNICODE_STRING. ;-) The limit on the length of the command line comes from the range of the Length field of the UNICODE_STRING structure. (NT uses Pascal-style strings internally.) NT's native process creation functionality is powerful, but baroque: see [1]. There's a ton of stuff that processes can be passed in addition to the command-line. One trick that's not well-known is that CreateProcess allows parent processes to pass an opaque binary blob to subprocesses via the lpReserved2 member of the STARTUPINFO structure. Cygwin uses this blob to pass information about file descriptors, ttys, and other POSIX context; this information block bootstraps Cygwin's fork implementation. The Microsoft C runtime uses it for a vaguely similar purpose: it's how file descriptor inheritance works when neither NT nor Win32 know anything about file descriptors (which are private to libc). [1] http://www.rohitab.com/discuss/topic/40191-ntcreateuserprocess/ http://www.rohitab.com/discuss/topic/40191-ntcreateuserproce... [2] https://msdn.microsoft.com/en-us/library/windows/desktop/ms686331(v=vs.85).aspx https://msdn.microsoft.com/en-us/library/windows/desktop/ms6...
- asveikau 10y agoI was a dev in Windows from 2008-2011 so I am not sure you are aware you are replying to someone who is already a big fan of the NT native API (and not so much a fan of the crude hack that is Windows CRT file descriptors, like most things in the MS CRT...) I did mean to type PWSTR in full awareness that I'm using it as a figure of speech for UNICODE_STRING.
- quotemstr 10y agoAh, I had no idea. It's sometimes hard to distinguish a lie-to-children from ignorance.
- 13of40 10y agoThe problem is that parsing the command line isn't done by the operating system at all, but delegated to each individual console application. If you made a new CreateProcess API that took an array of command line arguments, the operating system would need to serialize the array into a single string that could be passed to legacy commands. Unfortunately, there's no way to tell what weird parsing is buried inside the commands, so there will always be gaps in what you can express in the serialized command line. For example, suppose the console app thinks that apostrophes should be treated as quotes. I pass "'x", "x'" into the new API, and that gets serialized to "'x x'" (two strings to most applications), but this particular app interprets that as one string that says "x x". The OS can't even escape the apostrophes to avoid this, because it doesn't know what language the console application speaks. PowerShell had to deal with this problem because native command lines need to be rehydrated from its AST before they can be passed to CreateProcess, and (IIRC) they ultimately had to add an operator that means "everything after this point in the command line should be passed to the command verbatim" to cover all of the corner cases from this.