From: Angus L. <le...@ly...> - 2005-04-15 14:34:39
|
Keith MARSHALL wrote: >>Thanks, Keith, but I plan to move to CreateProcess instead. Code >>written. Further stress testing needed. > > So, you still have the same problem; Microsoft's implementations > of `spawn' and `exec' are themselves wrappers for `CreateProcess', > and it's the argument passing through `CreateProcess' which is > broken -- it simply passes all the arguments as a single string, > leaving the child process to reparse this, as its command line! Understood. > It may still be worth your while to have a look at the quoting > routine in the wrappers Jeff and I wrote -- it's been pretty > thoroughly tested already. Thanks, I'll look. But I assume that it's the same as the stuff below, no? > Also remember, that if you abandon `spawn' and `exec' in favour of > `CreateProcess', your code becomes potentially more difficult to > port to non-MS-Windows platforms in the future. Nahhh. I'm going the other way, porting LyX (www.lyx.org) to windoze. Angus // Inside a "-protected block, any " character must be escaped. // Note also that all adjacent \ characters in a block must be escaped // only if the next character following them is a " (which must // also be escaped). // Thus, using <...> to delimit the string, // <foo \ bar> becomes <"foo \ bar">, // <foo " bar> becomes <"foo \" bar"> and // <foo \\" bar> becomes <"foo \\\\\" bar">. // See http://article.gmane.org/gmane.comp.lib.boost.user/3005 // or http://msdn.microsoft.com/library/en-us/vccelng/htm/progs_12.asp std::ostringstream new_arg; std::string::const_iterator it = old_arg.begin(); std::string::const_iterator const end = old_arg.end(); new_arg << '"'; for (; it != end; ++it) { char const c = *it; if (c == '"') { new_arg << "\\\""; } else if (c == '\\') { std::string::const_iterator it2 = it + 1; while (it2 != end && *it2 == '\\') ++it2; std::string::size_type nbackslashes = std::distance(it, it2); if (it2 != end && *it2 == '"') nbackslashes *= 2; new_arg << std::string(nbackslashes, '\\'); it = it2 - 1; } else { new_arg << c; } } new_arg << '"'; |