groff
[Top][All Lists]
Advanced

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

[Groff] Re: MSVC Port--Behavior of spawn and exec functions


From: Jeff Conrad
Subject: [Groff] Re: MSVC Port--Behavior of spawn and exec functions
Date: Thu, 15 Jan 2004 16:02:24 -0800

Keith,

Thanks for the comments.  It looks as if this is a feature of MSVC that
any "native" port must contend with.

> ... or alternatively, I can use 'cmd.exe' in place of 'sh.exe':
> 
>    spawnlp( _P_WAIT, "cmd", "cmd", "/c", "ls -l", NULL )
>    spawnlp( _P_WAIT, "cmd", "sh", "/c", "ls -l", NULL )

Using cmd.exe won't work with a spooler interface that's a shell script,
however.

> Actually, it is surprising that the "sh" variants omitting the closing
> quote to the "'ls -l" and "\"ls -l" forms *do* work!

Not really that surprising ... the shell never sees the mismatched quotes!

> AIUI, when any Windows program is started, it is simply handed a single
> string of arguments, and left to parse it itself.

This is my general understanding as well.  However, there seems to be a bit
more involved than this.  Microsoft hint at the behavior
(http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/createprocess.asp):

    'The lpApplicationName parameter can be NULL.  In that case, the module
    name must be the first white space-delimited token in the lpCommandLine
    string.  If you are using a long file name that contains a space, USE
    QUOTED STRINGS to indicate where the file name ends and the arguments
    begin; otherwise, the file name is ambiguous.  For example, consider
    the string "c:\program files\sub dir\program name".'

[emphasis mine] lpApplicationName is analogous to (but not quite the same
as) the first argument to exec??(), and lpCommandLine is the command line
that is the second argument to CreateProcess().  I can't find anything that
decribes the handling of quotes beyoind the first argument, but testing the
behavior by calling a program that simply prints its arguments, one per
line, confirms the behavior with the remainder of the command line string.

The handling of double quotes by CreateProcess() (or perhaps by crt0) seems
largely undocumented, so I hate to rely on its behavior; however, I'm not
sure there's a good alternative.

My preference is to have groff quote arguments that might contain spaces,
using a function such as

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

in place of

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

I don't know that it will handle every imaginable case of shell quoting,
but it seems to work with most reasonable approaches; e.g., 'my file' can
be given as 'my file', "my file", or my\ file.  Note that test-groff can
give misleading results because the shell strips the outer layer of
quoting, so that it accepts '"my file"' and "'my file'".

This solution obviously isn't perfect, but it seems a considerable
improvement over the current behavior.

Thoughts?

Jeff Conrad



reply via email to

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