lua-users home
lua-l archive

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

On 14-Jan-06, at 6:27 PM, D Burgess wrote:

Hi Rici, Wim,

I consider myself a bit of a "CreateProcess" expert.

Cool. I only read the description in the MSDN library, so
I'm perfectly happy to defer to your practical knowledge.

There are lots
of issues here and exec/spawn probably deserves a thread of
its own.


1) I would suggest that posix spawn() be used rather fork()/exec().
posix_spawn() is avalable under linux and some others. Th spawn()
behaviour is implementable under win32.

I don't know how widely posix_spawn is implemented; it's not supported by FreeBSD afaik, and I doubt whether it's supported by Mac OS X. However, it can be implemented in terms of fork() and execve(). I wouldn't suggest a complete binding to posix_spawn() (or the Windows equivalent); rather a simplified (and extensible, perhaps) version which covered common cases.

2) ShellExecute (and relatives) vs CreateProcess. As you point out
they are very different beasts. I have implemented different Lua
functions for both of these. I believe that ShellExecute does not
have a *nix equivalent.

You could fork() and execve() /bin/sh, with more or less the same semantics, as far as I can see. I might be missing something, of course. I don't think that the Unix and Windows concepts of what a "shell" is are very well aligned.

3) The fun starts when one allows the remapping of stdin/stderr/stdout.
I have done this (without threads) using named pipes and overlapped
io. It works ok.

Maybe I misunderstood the MSDN writeup. A quick skim seemed to indicate that you could just hand a file handle over to the new process as its stdin handle, which would be the sort of thing you'd want to do in a standard "forking" server architecture. I'm aware that forking servers are considered declassé these days, and that event-driven single-process collaboration is sexier. On the other hand, forking servers are perfectly suitable, and a lot less subject to random resource leaks.

Anyway, it would be sufficient for most purposes if there were a way of doing the remapping of the three standard streams, however it was done. Lua only defines the three streams, so there would be no need to go beyond that in a basic implementation.

4) Both the A and W versions of CreateProcess modify the command
string. Note that this "feature" is also a security hole.
"c:\program files param1"
Windows parses the string so that it attempts to execute c:\program.
It may expand or reduce the length of the command string.

As I read the docs, you have the option of providing a specific file and a command line, or a commmand line from which Windows will extract the filename, but no option to provide a pre-chunked argv vector. I regard this as an error in API design, but as I said, the Unix version is not bullet-proof either. It's just easier to fix; if you're about to put a filename into an argv list, you pretty much only have to check to see if the first character is '-' or not. Unfortunately, the convention that -- terminates options parsing is only a convention, not enforced.

I quoted the section on the string being modified not because of the security issues involved with parsing metacharacters in the command line (which are a separate issue) but because it might be relevant to someone doing a naive binding; passing tostring(L, 3) to CreateProcess would be a Really Bad Idea if CreateProcess treats its argument as a mutable char* rather than a const char*. Of course, this is a general rule for binding functions which take character string arguments; if you don't know for sure that the parameter is const char* (and is not overridden), then you must make a copy of the string before passing it.

On the other hand, I don't offhand see an interface which abstracts command-line chunking. You can't insert escape characters into an argv vector without changing the semantics, so a note saying that "metacharacters may or may not be interpreted" would make the interface unusable.