develooper Front page | perl.perl5.porters | Postings from May 2004

Re[2]: Problem with system() on Win9x and command.com (perl 5.8.x-5.9.x)

Thread Previous | Thread Next
From:
bilbo
Date:
May 6, 2004 03:25
Subject:
Re[2]: Problem with system() on Win9x and command.com (perl 5.8.x-5.9.x)
Message ID:
443381876.20040506132410@ua.fm
Hello Rafael,

Wednesday, May 5, 2004, 2:38:36 PM, you wrote:

>>   I have problem with perl 5.8.x-5.9.x on Windows98SE (Win9x). When I
>>   run some executable via system() - all work ok. But when I try to
>>   run .bat file with system(), .bat file does not receive command line
>>   parameters.
RGS> [...]
>> I also found source of this bug, in file win32/win32.c:
>> 
>>     /* The NT cmd.exe shell has the following peculiarity that needs to be
>>      * worked around.  It strips a leading and trailing dquote when any
>>      * of the following is true:
>>      *    1. the /S switch was used
>>      *    2. there are more than two dquotes
>>      *    3. there is a special character from this set: &<>()@^|
>>      *    4. no whitespace characters within the two dquotes
>>      *    5. string between two dquotes isn't an executable file
>> >     * To work around this, we always add a leading and trailing dquote
>> >     * to the string, if the first argument is either "cmd.exe" or "cmd",
>> >     * and there were at least two or more arguments passed to cmd.exe
>> >     * (not including switches).
>>      * XXX the above rules (from "cmd /?") don't seem to be applied
>>      * always, making for the convolutions below :-(
>>      */
>> 
>> Because of this, system('test_bat.bat 1 2 3 4 5 6 7 8 9') really run
>> '"test_bat.bat 1 2 3 4 5 6 7 8 9"', and command.com can't understand this.
>> 
>> I make patch for this bug.
>> 
>> --- win32/win32.c       Wed Feb 04 04:22:18 2004
>> +++ win32/win32.c       Sat Apr 17 15:02:42 2004
>> @@ -3538,11 +3538,12 @@
>>         if (clen > 4
>>             && (stricmp(&cname[clen-4], ".bat") == 0
>>                 || (IsWinNT() && stricmp(&cname[clen-4], ".cmd") == 0)))
>>         {
>>             bat_file = TRUE;
>> -           len += 3;
>> +           if (!IsWin95())
>> +               len += 3;

RGS> Sorry for haven't answering to this earlier, but I'm a bit uncomfortable
RGS> to rely on the operating system version to determine which command shell
RGS> is used. Couldn't you instead look at the shell name? (I haven't any
RGS> Win32 machine to test.)

It can be right you. But I have chosen, as I think, the most simple
variant of the fix, because perl/w32 use very strange strategy for
external application run:

1. system(), open() have bug on win98, but exec() work fine.
2. Perl run command processor only in case of shell metasymbols found
in command line. Perl choose cmd.exe on WinNT and command.com
otherwise. PERL5SHELL env. variable override this, but win32 use
COMSPEC env. variable! Because of this, if I set PERL5SHELL to
something like bash.exe, but COMSPEC still pointed to cmd.exe, perl
actually run cmd.exe in case of system("1.bat"), but bash.exe in case
of system("1.bat %").


Another arguments. WinNT never use command.com. I don't hear anything
about Win9x & cmd.exe, because Win9x use command processor at boot
time (from DOS), but cmd.exe is PE executable.

I think, this pseudocode may fix bug more accurately, but I unsure,
that it is 100 % correctly...

if (?bat_file) /* ?"xxx.bat bla-bla-bla" */
{
   get_shell();
   shell = [get_shell_result];
}
else shell = cname;

if (?shell is cmd[.exe])
{
  cmd.exe_workaround
}

-- 
Best regards,
 bilbo                            mailto:bilbo@ua.fm


Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About