groff
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Groff] Re: MSVC Port--Quoting Arguments for spawn and exec Functions


From: Jeff Conrad
Subject: [Groff] Re: MSVC Port--Quoting Arguments for spawn and exec Functions
Date: Sat, 17 Jan 2004 00:42:43 -0800

Keith,

> Is 'lp' implemented as a shell script in MKS?

Actually, it's not implemented at all :-( ... my 'lp' script is a wrapper
for Peter Lerup's PrintFile.

> I fully agree that it is not a good idea to rely on undocumented M$
> behaviour; who knows when they may decide that it is a bug, and fix it,
> (without telling anyone, of course)!

I'm shocked that you even could entertain such a thought ...

> I found a (rather long winded) description of how MSVC applications
> parse their command lines at

Thanks! This link includes a link to MSDN
(http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang/html/_pluslang_Parsing_C.2b2b_.Command.2d.Line_Arguments.as
p)
that DOES document the behavior, so I think we're fairly safe.  The
explanation even is in my MSVC documentation ...  RTFM ...  I had assumed
that the parsing was done by CreateProcess(), and searched accordingly.
Like troff, I forgot the proper hyphenation of assume ...

> Using 'append_arg_quoted' looks like a reasonable solution, for the
> "native" Windows builds, where we need to group arguments in the 'argv[]'
> which will eventually get rebuilt by the MSVC startup code,

The 'argv[]' is a bit of an illusion--it gets rebuilt into a single string
even before it's passed to CreateProcess() (which doesn't accept an argv
array).  At startup, the command string gets parsed again, and depending on
embedded quotes, rebuilt(?) into something resembling the original 'argv[]'
before it's passed to the child program ...

> ... however, it needs careful consideration as to *when* to use it --

I agree completely--I'd use it only within #ifdefs (perhaps you can help
ensure that we have the right conditions), or, as Werner seems to prefer,
implement APPEND_ARG as a macro with the appropriate definition for a given
platform--the code usually looks cleaner that way.

> We would also need to pay particular attention to *how* we use
> 'append_arg_quoted' to group args -- basically *all* args which need to
> be grouped need to be passed at once, in the same call

Even within #ifdefs, I'd use the quoting very sparingly--for arguments that
are likely to contain spaces AND for which those spaces are likely to cause
problems.  As nearly as I can tell, the only situations that apply are
filenames with spaces and spooler commands that may contain arguments.

> ... -- perhaps we should consider using *two* functions, e.g.

>     void possible_command::append_arg_quoted_begin(const char *s, const
> char *t)
>     {
>       args += '"';
>       args += s;
>       if (t)
>         args += t;
>       args += '\0';
>     }

The trailing NUL appended by append_arg_quoted actually serves as the
argument separator, so we'd need to avoid it within an argument.  We could
append a space, or perhaps better, append nothing and make the caller
responsible for including the necessary space.

Actually, I think we could handle this by building a string and then handing
it to append_arg_quoted, as in

    commands[SPOOL_INDEX].set_name(BSHELL);
    commands[SPOOL_INDEX].append_arg(BSHELL_DASH_C);
    Largs += '\0';
    Largs = spooler + Largs;
    commands[SPOOL_INDEX].APPEND_ARG(Largs.contents());

It looks a bit weird to have both the actual function call and the macro,
but I have no better ideas, though I suppose a QUOTED argument
would be an alternative.

I tend to prefer a single function, if possible, because doing so should
require the least change to the program, making us less vulnerable to the
law of unintended consequences.  If problems do arise because of the
change, at least they should be easy to isolate.  Moreover, a single
function would make it much easier to implement as a macro.  What do you
think?

I think we're close to a solution.  The trickiest quoting involves the 'X'
option, because some arguments are handled several times.  I think I have
it right, but unfortunately, I'm not running X, so I have no way of testing
it.

Jeff



reply via email to

[Prev in Thread] Current Thread [Next in Thread]