|
From: Hans-Bernhard B. <br...@ph...> - 2004-04-12 16:21:51
|
Gents,
an old issue just resurfaced after laying dormant for most of 2 years.
It's the behaviour of the '!' shell-escape on Windows platforms, and was
brought to our attention by Don Taber in 2002 without every reaching a
conclusion.
Here's the beef: for a reason that's not explained particularly well,
wgnuplot rolls it's own version of the system() function to implement the
'!' command. The home-grown version relies on a deprecated Windows API
entry WinExec(). That probably even made sense back in the days of 16-bit
Windows-3.x. but it's currently experiencing at least two serious
drawbacks. Does anybody here still remember when, or why that code was
put in there in the first place? It must have been there since at least
3.6. For all I know, it could even be from the initial port to Windows.
The code in question is command.c:winsystem(), which essentially does
this:
if (WinExec(cmd) fails)
WinExec("%COMSPEC% /c " + cmd);
The problems are:
1) WinExec() doesn't really wait for the called programm to finish the way
system() is supposed to. This wreaks havoc to gnuplot scripts like
! tool input -o output.dat
plot 'output.dat'
2) WinExec doesn't support redirection or internal commands of the command
line processor.
The second WinExec() call is supposed to address issue 2) by handing the
job over to the shell, but fails to do so, silently, if the command is an
external .exe that just silently ignores the redirection options (--> the
first WinExec() succeeds). It can be worked around by "hiding" this fact
from WinExec(), e.g. by prepending a space:
!command > output.dat
will fail, but
! command > output.dat
seems to work. That's stupid, to put it mildly. And it still fails to
wait for the termination of the external command.
Proposed solution #1: get rid of winsystem() altogether. Just call
system() like on all other platforms, and trust the compiler authors to
know what they're doing. Drawback: there's no time to go through a test
of'em all to make sure that assumption is reliable.
Proposed solution #2: only get rid of the if(), so the job always ends up
being done by the shell. Drawback: wouldn't solve the wait-for-subcommand
issue at all.
Proposed solution #3: Like #2, but also change from WinExec to the
Win32-only function CreateProcess() with appropriate waiting.
--
Hans-Bernhard Broeker (br...@ph...)
Even if all the snow were burnt, ashes would remain.
|