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. |