Huidae Cho wrote:
> > > While *something* needs to be done on Windows, the solution *doesn't*
> > > involve grass-xterm-wrapper. Which is why I've reverted the recent
> > > attempt to replace grass-xterm-wrapper (it was getting compiled on
> > > Linux, where it totally won't work; there is no sh.exe on Linux).
> >
> > Probably, that is because of cross-compiling or wrong definition of
> > MINGW in include/Make/Platform.make?
>
> No, it's because you have a target named grass-xterm-wrapper, and a
> source file named grass-xterm-wrapper.c which is older than the
> target, so make assumes that it's supposed to compile and link
> grass-xterm-wrapper.c into grass-xterm-wrapper.
Confirmed. You mean "*newer* than the target."
Yes.
> > If the solution doesn't involve grass-xterm-wrapper, what could be
> > done for Windows *now*?
>
> I'm not sure that anything *can* be done for Windows right now, other
> than "this feature doesn't work on Windows yet".
>
> GRASS has two decades of history as a Unix package. Getting a native
> Windows version working isn't going to happen overnight. And trying to
> rush it will only make things harder in the long run.
>
> > If there are
> > no alternative ways of getting terminals working on Windows, I think
> > it's better to keep it until someone comes up with a better idea
> > although you may not like it.
>
> Running a command in a terminal and handling shell scripts are
> separate issues. Running a binary executable in a Windows console
> shouldn't involve sh.exe in any way.
>
> More significantly, the problem of running scripts on Windows isn't
> limited to whether or not they are run in a terminal. Even
> non-interactive scripts need special treatment. On Unix, the first
> argument to execve() can be a binary executable or a script, and the
> kernel will handle the details. This doesn't work on Windows, which
> doesn't recognise the #! syntax.
>
> Shell scripts need to be run via sh.exe (but *not* via "sh -c ...").
> But we don't really want to have to hardcode knowledge of whether a
> particular program is a binary or a script into gis.m.
>
> Essentially, all calls to "exec" (or "open |...") in Tcl need to be
> modified to allow scripts to work under Windows. This requires a
> "launcher" which would determine whether the command is a binary or
> script based upon the first few bytes of the file (scripts begin with
> #! then the interpreter, Windows executables begin with "MZ"), and
> invoke the interpreter if necessary.
When sh.exe does that interpretation, why do we need another launcher?
Is it because of metacharacters?
Mostly, although there may be other issues. A shell is an extremely
heavy-weight solution.
Also, using sh.exe isn't exactly "native" Windows, IMHO. Obviously, if
we have shell scripts, then we need a shell to execute them. But we
shouldn't need it (and shouldn't be using it) for anything else.
It doesn't help that all of the shells which I've encountered perform
various Unix-compatibility tasks (e.g. translating filenames between a
virtual Unix filesystem and the native Windows filesystem). This
creates a risk of undesirable side-effects (e.g. filenames being
converted in some contexts but not in others, resulting in
mismatches).
What side effects can we expect if sh.exe is used to run binary
files?
There are two ways that the shell can be used. As an interpreter for
shell scripts, and as a mechanism for executing commands ("sh -c").
The latter is inappropriate on Windows, and not even a good idea on
Unix (where its normally used due to laziness). It's far more robust
to use the OS' mechanism(s) (execve(), spawnl()) directly.
Using the shell as an interpreter for shell scripts is safe, e.g.:
spawnl("sh.exe", "script", "arg1", "arg2", NULL);
However, this only works for shell scripts; if you pass the name of a
binary file in the above example, the shell will attempt to interpret
it as a shell script, which obviously won't work.
OTOH, using:
spawnl("sh.exe", "-c", command, NULL);
requires that command be constructed from the name of a program and
its arguments, and that isn't as simple as concatenating the strings
with spaces in between. The simplest solution to the issue of
metacharacters is to replace any occurrences of the single quote
character in arguments with "'\''" (quote, backslash, quote, quote)
and surround each argument with single quotes.
Even then, there might be issues due to the shell messing with the
environment, signal handling, process groups etc (as well as possible
Unix-compatibility "features"). Shells are very complex programs.
> You would need to map the path, as a "/bin/sh" probably won't be found
> at "C:\bin\sh.exe". One option is to look for an association for ".sh"
> in the registry (HKEY_CLASSES_ROOT\.<ext> for the type, then
> HKEY_CLASSES_ROOT\<type>\shell\open\command for the handler).
>
Out of curiosity, is just adding ".sh" to the registry enough to run
*.sh through sh.exe?
I don't think you can map extensions directly to programs; normally,
the extension is mapped to a file type, then various actions are
associated with the type. E.g. ".vbs" is mapped to "VBSFile", then
actions are registered for "VBSFile".
OTOH; it's by no means guaranteed that the registered handler will do
the right thing. E.g. the "open" handler for .sh files might be a text
editor, or it might run them in a new console or an rxvt. In that
case, we might need a $GRASS_SH variable for Windows.
--
Glynn Clements <glynn@gclements.plus.com>