diff options
author | David Wragg <david@rabbitmq.com> | 2010-10-27 23:12:59 +0100 |
---|---|---|
committer | David Wragg <david@rabbitmq.com> | 2010-10-27 23:12:59 +0100 |
commit | 692c9b9cb21ab6ed799f7ae0dc9347f75ae7fe50 (patch) | |
tree | 147912ddb8b53e6ebd5ba5d56a339da23928f487 | |
parent | 972c146985ffa9209b53d9f31a4920730f2773b4 (diff) | |
download | rabbitmq-c-github-ask-692c9b9cb21ab6ed799f7ae0dc9347f75ae7fe50.tar.gz |
Construct the command line to conform to Windows escaping conventions
Those conventions are crazier than I thought. I leaned about this
from
<http://blogs.msdn.com/b/oldnewthing/archive/2010/09/17/10063629.aspx>.
-rw-r--r-- | tools/windows/process.c | 36 |
1 files changed, 28 insertions, 8 deletions
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; } |