[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Problems with lposix on win32
- From: Rici Lake <lua@...>
- Date: Sat, 14 Jan 2006 19:49:29 -0500
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.