From 692c9b9cb21ab6ed799f7ae0dc9347f75ae7fe50 Mon Sep 17 00:00:00 2001 From: David Wragg Date: Wed, 27 Oct 2010 23:12:59 +0100 Subject: Construct the command line to conform to Windows escaping conventions Those conventions are crazier than I thought. I leaned about this from . --- tools/windows/process.c | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) (limited to 'tools') diff --git a/tools/windows/process.c b/tools/windows/process.c index 0a005bd..d0e162a 100644 --- a/tools/windows/process.c +++ b/tools/windows/process.c @@ -98,37 +98,57 @@ static char *make_command_line(const char *const *argv) dest = buf = malloc(len); if (!buf) die("allocating memory for subprocess command line"); - - *dest++ = '\"'; + + /* Here we perform the inverse of the CommandLineToArgvW + function. Note that it's rules are slightly crazy: A + sequence of backslashes only act to escape if followed by + double quotes. A seuqence of backslashes not followed by + double quotes is unaffected. */ for (i = 0;;) { const char *src = argv[i]; + int backslashes = 0; + + *dest++ = '\"'; + for (;;) { switch (*src) { case 0: goto done; case '\"': + for (; backslashes; backslashes--) + *dest++ = '\\'; + + *dest++ = '\\'; + *dest++ = '\"'; + break; + case '\\': + backslashes++; *dest++ = '\\'; - /* fall through */ + break; default: - *dest++ = *src++; + backslashes = 0; + *dest++ = *src; break; } + + src++; } - done: + done: + for (; backslashes; backslashes--) + *dest++ = '\\'; + + *dest++ = '\"'; if (!argv[++i]) break; - *dest++ = '\"'; *dest++ = ' '; - *dest++ = '\"'; } - *dest++ = '\"'; *dest++ = 0; return buf; } -- cgit v1.2.1