[Info-vax] Command Line Versus Command Line
Arne Vajhøj
arne at vajhoej.dk
Fri May 24 20:12:39 EDT 2024
On 5/24/2024 12:45 PM, Craig A. Berry wrote:
> On 5/24/24 10:28 AM, Arne Vajhøj wrote:
>> On 5/24/2024 11:11 AM, Michael S wrote:
>>> It seems like the simplest solution is to not try to run batch files by
>>> means of spawn("cmd.exe", ...) or CreateProcess("cmd.exe", ...).
>>> They could have use more specialized function: system() from C RTL or
>>> ShellExecuteEx() from Win32 API. The former is easier to use, the later
>>> works as expected in wider range of host console environments, most
>>> importantly, it works from mintty.
>>
>> Both system and ShellExecuteEx still take all parameters as a single
>> string, which require some non-trivial conversion from array of
>> parameters to that string.
>
> The Windows CRT has _spawn() [1] which looks pretty similar to
> posix_spawn() [2]. With either one you pass arguments or an array of
> arguments rather than a complete command line. From the docs it sounds
> like on Windows the arguments get concatenated under the hood, but at
> least "someone else" is doing that rather than each program having to
> take responsibility for it.
> [1]
>
https://learn.microsoft.com/en-us/cpp/c-runtime-library/spawn-wspawn-functions?view=msvc-170
That looked very promising.
But a test did keep the optimism.
parmdump.c:
#include <stdio.h>
int main(int argc, char *argv[])
{
for(int i = 0; i < argc; i++)
{
printf("%d : %s\n", i, argv[i]);
}
return 0;
}
demo.c:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <process.h>
void bad(const char *a1, const char *a2)
{
printf("Bad\n");
char cmd[1000];
snprintf(cmd, sizeof(cmd), "parmdump %s %s", a1, a2);
system(cmd);
}
void mystrcat(char *to, const char *from)
{
int ix = strlen(to);
for(int i = 0; i <= strlen(from); i++)
{
if(from[i] == '"')
{
to[ix] = from[i];
ix++;
to[ix] = from[i];
ix++;
}
else
{
to[ix] = from[i];
ix++;
}
}
}
void hack(const char *a1, const char *a2)
{
char *pto, *pfrom;
printf("Hack\n");
char cmd[1000];
strcpy(cmd, "parmdump \"");
mystrcat(cmd, a1);
strcat(cmd, "\" \"");
mystrcat(cmd, a2);
strcat(cmd, "\"");
system(cmd);
}
void latest_l(const char *a1, const char *a2)
{
printf("Latest (l)\n");
_spawnl(_P_WAIT, "parmdump", a1, a2, NULL);
}
void latest_v(const char *a1, const char *a2)
{
const char *argv[] = { a1, a2, NULL };
printf("Latest (v)\n");
_spawnv(_P_WAIT, "parmdump", argv);
}
void test(const char *a1, const char *a2)
{
bad(a1, a2);
hack(a1, a2);
latest_l(a1, a2);
latest_v(a1, a2);
}
int main()
{
test("a", "b");
test("a", "b c d");
test("a", "b\"c");
return 0;
}
Output:
Bad
0 : parmdump
1 : a
2 : b
Hack
0 : parmdump
1 : a
2 : b
Latest (l)
0 : a
1 : b
Latest (v)
0 : a
1 : b
Bad
0 : parmdump
1 : a
2 : b
3 : c
4 : d
Hack
0 : parmdump
1 : a
2 : b c d
Latest (l)
0 : a
1 : b
2 : c
3 : d
Latest (v)
0 : a
1 : b
2 : c
3 : d
Bad
0 : parmdump
1 : a
2 : bc
Hack
0 : parmdump
1 : a
2 : b"c
Latest (l)
0 : a
1 : bc
Latest (v)
0 : a
1 : bc
Unless I am doing something wrong then these _spawn functions still
expect the caller to handle the proper quoting to avoid problems.
> There was a mention sometime in the last couple of years that
> posix_spawn() is being added to the VMS CRTL.
> [2]
> https://pubs.opengroup.org/onlinepubs/9699919799.2013edition/functions/posix_spawn.html
I don't see it in 9.2-2.
Arne
More information about the Info-vax
mailing list