ActiveState: Can't spawn "cmd.exe"?

Discussion in 'Perl Misc' started by Daniel Pfeiffer, Jun 12, 2005.

  1. Hi,

    I am a developer of makepp.sourceforge.net, a way enhanced (GNU) make
    replacement. I have been busy these last weeks extending the Cygwin port
    first to MinGW (the easy part) and then to ActiveState Perl, with just the
    native Windows 2000 (no Unixy stuff around).

    We have an extensive test suite. Most of what fails is related to test Shell
    scripts, which are beyond the capabilities of the system call. These will
    have to be ported to Perl (in which both makepp and the test harness are written).

    But the test variable_expansion gives an error -1 when running a simple echo
    command. And additional_tests/2003_10_11_idash is also baffling, with more
    detailed analysis:

    A rule excutes this command (with CC set to the first two words) on one line.
    This single string gets passed to the system function:

    echo nocc -g -I subdir1 -I- -Isubdir2 -c compilation_test.c -o compilation_test.o

    This gives a warning (I installed a $SIG{__WARN__} locally around system):

    Can't spawn "cmd.exe": No such file or directory at C:/TEMP/cvs/Rule.pm line 1128.

    And system gives a return of 255 << 8. What could be causing this, and how
    could it be evited?

    NB: Passing the identical string to perl -e "system '...'" works just fine.

    If this is not a known issue with ActiveState Perl (I tried both 5.6.1 and
    5.8.6), I would be extremely glad for help by a Windows expert! This would
    require picking up the latest makepp version from CVS.

    thank you very much in advance!

    coralament / best Grötens / liebe Grüße / best regards / elkorajn salutojn
    Daniel Pfeiffer
     
    Daniel Pfeiffer, Jun 12, 2005
    #1
    1. Advertisements

  2. Daniel Pfeiffer

    Rick Measham Guest

    Can't be sure what/where your problem is, but cmd.exe is a Norton AV
    file. Could be that your external execution is trying to be run through
    cmd.exe, but is failing for some reason. Try getting rid of Norton and
    run it again.

    Cheers!
    Rick Measham
     
    Rick Measham, Jun 13, 2005
    #2
    1. Advertisements

  3. Daniel Pfeiffer

    Sisyphus Guest


    I don't quite understand. Line 1128 of Rule.pm is:
    system( format_exec_args( $action ));

    Are you saying that there's no problem with that line on MinGW-built perl,
    but there *is* a problem with that line on ActiveState perl ?

    If so, then the solution would surely be to ensure that
    'format_exec_args($action)' returns the same string with ActiveState perl as
    it does for MinGW perl. (Or is that already the case ?)

    Precisely what is the full string returned by 'format_exec_args($action)' ?
    (I couldn't understand the meaning of "with CC set to the first two words".)
    The "identical string" is the string returned by 'format_exec_args($action)'
    ...... right ?
    And it's working fine in the 'perl -e....' system call, but producing that
    error when run from Rule.pm .... right ?

    When testing with ActiveState perl what shell are you running in ?
    When testing with MinGW perl what shell are you running in ?
    Could it be that you're invoking the wrong shell without realising it?

    I don't know how to generate the "Can't spawn cmd.exe" error. Anyone ?

    Cheers,
    Rob
     
    Sisyphus, Jun 13, 2005
    #3
  4. Daniel Pfeiffer

    Sisyphus Guest

    Oh ... yes I do know how to generate that warning. Just run a system()
    command in a shell that doesn't have the path to cmd.exe in its 'path'
    environment variable.

    eg:
    #### test.pl####
    use warnings;
    system "dir";
    __END__

    And then, running in the cmd.exe shell:

    F:\makepp>set path=

    F:\makepp>path
    PATH=(null)

    F:\>D:\perl58_M\bin\perl -lwe "system 'dir'"
    Can't spawn "cmd.exe": No such file or directory at -e line 1.

    F:\>D:\perl58_M\bin\perl test.pl
    Can't spawn "cmd.exe": No such file or directory at test.pl line 2.

    F:\>

    I probably need answers to the questions I asked in my earlier reply before
    I could speculate further.

    Cheers,
    Rob
     
    Sisyphus, Jun 13, 2005
    #4
  5. Daniel Pfeiffer

    Sisyphus Guest

    'cmd.exe' is also the native Win32 shell program that ships with Windows
    NT/2000/XP - and it's *that* cmd.exe (not the Norton file) that's being
    sought.

    Cheers,
    Rob
     
    Sisyphus, Jun 13, 2005
    #5
  6. la 13.06.2005 04:23 Sisyphus skribis:
    format_exec_args is a workaround for Perl's buggy system function. When Perl
    sees no special chars in the string it internally does a split on whitespace
    and execs. But it misses some special characters and builtin commands. On
    anything except ActiveState this function returns ('/bin/sh', '-c', $_[0]) in
    such cases.
    On ActiveState it returns the string verbatim.
    The make rule in question runs $(CC) ..., and since I'm not yet at the point
    of messing with the weirdness of Windows compilers, I "set CC=echo nocc".
    Normal DOS command window, so I suppose cmd.exe.
    /usr/bin/sh which is MinGW's bash 2.04.
    Probably! In all three environments, I reduce the PATH to a minimum, so as to
    not get any "goodies" from another environment. E.g. ActiveState would
    happily pick up Unix commands from MKS, MinGW and Cygwin, so I do

    set PATH=C:\WINNT\system32;C:\WINNT;C:\Perl\bin

    The first directory contains CMD.EXE. (Which answers your 2nd post). The
    funny thing is that when I don't reduce the PATH, something does happen. I
    modified export.test to do

    echo %X% %Y% >testfile

    and then testfile contains the line "Syntaxfehler." (german for error), which
    is not what happens when I type that command in the DOS window.

    Thanks for taking so much time!
    Daniel
     
    Daniel Pfeiffer, Jun 13, 2005
    #6
  7. Daniel Pfeiffer

    Sisyphus Guest

    Normally, perl is built using MinGW in the cmd.exe shell, following the
    instructions in the README.win32 (which involves editing the
    Win32\makefile.mk). It's also normal to run that perl in the cmd.exe shell.
    I believe it's quite a trivial thing to run MinGW-built perl (and
    ActiveState perl, too) in a bash shell, though I've not personally done
    that. Not sure why I'm mentioning this .... I guess it's just that the
    reference to MinGW's bash shell makes me wonder whether you've built perl
    with MinGW in some unusual way .... and if that's the case I'm further
    wondering whether it should be brought to your attention :)
    That makes it very hard (for me) to work out why a system call that works
    when invoked by 'perl -e ..' is unable to spawn the cmd.exe when called from
    file (Rule.pm).

    What happens if you run a script containing a system command (such as the
    test.pl in my 2nd post) from that very same shell ? Does it fail to spawn
    cmd.exe, too ?

    Maybe:
    #### test.pl ####
    use warnings;
    $ENV{PATH} = '';
    system "cd";
    __END__

    D:\pscrpt>perl -lwe "system 'cd'"
    D:\pscrpt

    D:\pscrpt>perl try.pl
    Can't spawn "cmd.exe": No such file or directory at try.pl line 3.

    D:\pscrpt>perl -lwe "system 'cd'"
    D:\pscrpt

    That's one simple way of getting a system command to work with 'perl -e...'
    but fail when called from file. Now, I'm not suggesting that Rule.pm
    explicitly removes C:\winnt\system32 from the path - but could that be
    happening somehow ??

    I'll continue to puzzle over this, and post again if I think of something -
    but it doesn't look like I'll be able to offer much help.

    Maybe you could also try perlmonks if there's no useful help here.

    Cheers,
    Rob
     
    Sisyphus, Jun 13, 2005
    #7
  8. la 13.06.2005 13:15 Sisyphus skribis:
    I had a hard time getting MinGW together, even though Msys is supposed to give
    all you need. I picked up a lot of packages, before I finally had a Perl.
    It's the Perl 5.6.1 they deliver on their server. I compiled nothing myself.
    I finally sorted this one out. Coming from Unix, makepp assumes PATH to be
    colon separated and splits it on that. I haven't tracked where it gets put
    together again (after all we still have the full PATH intact as well) but
    splitting it on ';' and stripping the quotes has solved the cmd.exe problem :)

    So now finally makepp works on Windows. The remaining issues are to teach it
    to parse typical Windows compiler invocations, because it figures out implicit
    dependencies from -I and -l/-L options, such that you don't need makedep.

    It would also be great to have it implicitly add .exe, such that you don't
    need separate handling of Windows targets, and being case-preserving on file
    names, rather than lowercasing everything. These issues can be a bit tricky,
    because makepp knows about potential files from the rules, even before they
    actually exist, but then it can only guess these things.

    Thanks again for all your support!
    Daniel
     
    Daniel Pfeiffer, Jun 14, 2005
    #8
  9. And what is your excuse for not using File::Spec?
    Very confidence inspiring.

    Indeed, these posts have helped me decide never to give makepp a shot.
    Oh yeah! Repeat again, what is your excuse for not using File::Spec?

    <URL: http://search.cpan.org/~kwilliams/PathTools-3.08/lib/File/Spec.pm>

    File::Spec - portably perform operations on file names
    And probably introduced a bunch more given the haphazard way you are
    approaching this.

    Sinan
     
    A. Sinan Unur, Jun 14, 2005
    #9
  10. Daniel Pfeiffer

    Sisyphus Guest

    [snip]
    myself.

    Aaah - that would have been a perl package that came with one of the
    "extras" MSYS packages - probably msysDTK I'm guessing.
    Fyi: I don't know of anyone actually using that perl build - and had
    forgotten that I had read of its existence. Needless to say, I haven't
    actually tried it out. It sounds like it has a particularly nixy flavour
    (similar to Cygwin's perl ?). Any people I know of who are using MinGW-built
    perl built it as I outlined in my last post. That way you get a native Win32
    perl - same as ActiveState perl, but built with the MinGW port of the gcc
    compiler. Built that way, MinGW perl and ActiveState perl are binary
    compatible (assuming the MinGW perl has been built, like ActiveState perl,
    with threads support). I doubt that you could swap binaries around between
    your MinGW perl and an ActiveState perl 5.6 (even if your MinGW perl *is*
    multithreaded).

    Cheers,
    Rob
     
    Sisyphus, Jun 15, 2005
    #10
  11. la 14.06.2005 23:36 A. Sinan Unur skribis:
    And what is your excuse for not knowing what you are talking about?
    File::Spec handles only part of OS specifics, and PATH variables are not one
    of them. Even the file system related ones are handled too superficially,
    e.g. only string manipulations rather than checking results against the file
    system.

    Besides the stable version of makepp still supports 5.005, which didn't yet
    include this module. And the version that comes with 5.8.6 for Cygwin, though
    at 1.1, claims to be beta. It also pretends not to be case_tolerant :-( This
    shouldn't be a system specific anyway but a file system specific one. I can
    well mount a Samba drive somewhere, giving me mixed case sensitivity within
    one path.

    And even if Sysiphus thinks that the only MinGW port available for download is
    not the usual one, it does exist and is not handled by File::Spec ($^O eq 'msys').
    The result counts, and we verify that with an extensive test suite, as well as
    using the bleeding edge version in our various big real life projects.
    That's freedom as in (lots of) free beer ;-)
    I've already got some in my finder, none of which would be helped by
    File::Spec. But they'll be sorted out.

    best regards
    Daniel
     
    Daniel Pfeiffer, Jun 21, 2005
    #11
  12. File::Spec->path

    Takes no argument. Returns the environment variable PATH (or
    the local platform's equivalent) as a list.

    <URL:http://search.cpan.org/~kwilliams/PathTools-3.09/lib/File/Spec.pm>

    Even the file system related ones are handled too
    What you were doing was string manipulation using the wrong strings.
    Using File::Spec->path would have been the right thing to do.
    There was a very illuminating discussion on this in the last few months.
    Check the archives.

    Sinan
     
    A. Sinan Unur, Jun 21, 2005
    #12
  13. Daniel Pfeiffer

    Sisyphus Guest

    Rare as it is, it sounds nonetheless interesting, and I must take a look at
    it one day. File::Spec certainly won't handle an operating system named
    'msys' - and I would think that ExtUtils::MakeMaker might experience some
    problems, too. I expect other caveats as well.

    I doubt that they recommend it as a production utility - rather I think it's
    supplied so that apps whose build process needs perl can be successfully
    built (but I could be wrong about that).

    Cheers,
    Rob
     
    Sisyphus, Jun 21, 2005
    #13
  14. la 21.06.2005 12:22 A. Sinan Unur skribis:
    Ooops, I'm sorry! I read over that one too fast, maybe because "path" also
    refers to full filenames (as in canonpath).

    However, checking the coding of those functions, they are broken. Cygwin
    wrongly inherits from Unix, and that only splits on :, which will completely
    fail on the like of '/bin:"C:/WINNT":"/Path/with space"'. I'm amazed that
    after years of publication the module is still so poor.
    I wasn't referring to that. Makepp needs to know when two files point to the
    same physical file.
    There's quite a bit of discussion -- not sure which you mean. But what I see,
    is that for the nitty details you have to do quite a bit of coding around the
    provided methods. And even then the authors are often not sure their thing is
    still portable.

    I agree that rebasing makepp's FileInfo.pm on this might make some sence. But
    given the problems and incompleteness of File::Spec it is hardly a panacea...
    Not sure about performance either. FileInfo is very central to makepp, and
    when I took out the method lookup, converting it to function calls, makepp
    became noticeably faster.

    Daniel
     
    Daniel Pfeiffer, Jun 21, 2005
    #14
  15. What are you talking about??? Let me fire up Cygwin shell ... Oooops,
    better add a directory with spaces to my path ... Done, now I fire up
    the shell.

    Here is my $PATH:

    PATH='/usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin:
    /cygdrive/c/opt/Perl/bin/:/cygdrive/c/opt/gs8.50/bin:
    /cygdrive/c/opt/gs8.50/lib:/cygdrive/c/opt/Perl/bin:
    /cygdrive/c/opt/jdk/bin:/cygdrive/c/opt/GTK/2.0/bin:
    /cygdrive/c/opt/GIMP-2.2/bin:/cygdrive/c/opt/PuTTY:
    /cygdrive/c/Program Files/HighMAT CD Writing Wizard:
    /cygdrive/c/WINDOWS/system32:/cygdrive/c/WINDOWS:
    /cygdrive/c/WINDOWS/System32/Wbem:/cygdrive/c/opt/util:
    /cygdrive/c/opt/vim/vim63:/cygdrive/c/opt/TeX/bin/win32

    Note the requisite path with spaces in the middle of this list. Now:

    $ cat p.pl
    #!/usr/bin/perl

    use strict;
    use warnings;

    use File::Spec::Functions 'path';

    print "$_\n" for path;

    __END__

    $ ./p.pl
    /usr/local/bin
    /usr/bin
    /bin
    /usr/X11R6/bin
    /cygdrive/c/opt/Perl/bin/
    /cygdrive/c/opt/gs8.50/bin
    /cygdrive/c/opt/gs8.50/lib
    /cygdrive/c/opt/Perl/bin
    /cygdrive/c/opt/jdk/bin
    /cygdrive/c/opt/GTK/2.0/bin
    /cygdrive/c/opt/GIMP-2.2/bin
    /cygdrive/c/opt/PuTTY
    /cygdrive/c/Program Files/HighMAT CD Writing Wizard
    /cygdrive/c/WINDOWS/system32
    /cygdrive/c/WINDOWS
    /cygdrive/c/WINDOWS/System32/Wbem
    /cygdrive/c/opt/util
    /cygdrive/c/opt/vim/vim63
    /cygdrive/c/opt/TeX/bin/win32
    /usr/bin
    /usr/bin
    /usr/local/bin
    /usr/lib
    I don't see a problem.

    FYI:

    $ perl -v
    This is perl, v5.8.6 built for cygwin-thread-multi-64int

    $ perl -MFile::Spec -e 'print $File::Spec::VERSION'
    3.01

    So, I guess, I need to update.
    That is not what you originally identified as the issue with your code:

    ##
    #> I finally sorted this one out. Coming from Unix, makepp assumes PATH
    #> to be colon separated and splits it on that. I haven't tracked where
    #> it gets put together again (after all we still have the full PATH
    #> intact as well) but splitting it on ';' and stripping the quotes has
    #> solved the cmd.exe problem :)

    There is no reason to reinvent the wheel, and come up with an octogonal
    one.

    Besides, I do not see why your application is interested in figuring out
    if two paths refer to the same physical file.
    Given your reputation, I am inclined not believe the assertions above.
    File::Spec has never failed me.
    What are the problems with File::Spec?
    I am inclined to believe any performance problems you had were not due to
    method versus function calls.

    Sinan
     
    A. Sinan Unur, Jun 21, 2005
    #15
  16. la 22.06.2005 00:16 A. Sinan Unur skribis:
    The problem are the quotes, which can occur both in native Windows and Cygwin.
    Neither module eliminates them. And in the latter they also protect the
    colon in C:/, which is not a separator. Makepp gets this right, because it
    parses the path. File::Spec::Unix (superclass of Cygwin) just does split(':',
    $ENV{PATH}), splitting right through the middle of C:/ pathes :-(
    Updating may help the individual. But say this is fixed in 5.8.7 or .8, then
    a widely distributed program, which has to cater to older buggy versions, can
    wait years before relying on this.
    Sure, but you brought up a Module as the solution, so I went and looked if it
    would help makepp. As discussions go, then the scope of this thread
    widenened. If we were to use the module you propose, then in its full
    breadth, since all of its methods are relevant to makepp.
    Makepp goes far beyond the erratic "timestamp changed" checks of older makes.
    It takes many aspects of a file into consideration to find out if a
    dependency *really* requires rebuilds.
    Wow, I have a reputaion — how exciting ;-) When people post various 20-30
    line wrappers around File::Spec to chase symlinks, then an important task is
    clearly missing in this module.
    If you still don't know, reread this mail, which reiterates two things I
    noticed even before really going into depth. I had also mentioned
    case_tolerant being wrong on Unix, because not all file systems respect case,
    and on Cygwin, where it doesn't bother to override the wrong inherited value.

    Further analysis might or might not reveal more problems. Software
    correctness is not proveable, and most certainly not with a casual "I never
    had a problem." But proof to the contrary is not contestable! (Unless you
    disproove the proofs, which you got wrong on the path case.)
    Inclinations may be an interesting hobby, but I am only interested in facts:

    $ time perl -e '1 for 0..1000000' # just to show nop does get called
    0.41s real 0.39s user 0.01s system
    $ time perl -e 'sub nop {}; nop for 0..1000000'
    2.18s real 2.11s user 0.01s system
    $ time perl -e 'sub nop {}; $x = bless {}; $x->nop for 0..1000000'
    2.95s real 2.84s user 0.02s system

    That's a 34% overhead for method lookup. This is especially penalizing for
    accessor methods which do no real work.

    coralament / best Grötens / liebe Grüße / best regards / elkorajn salutojn
    Daniel Pfeiffer
     
    Daniel Pfeiffer, Jun 23, 2005
    #16
  17. I don't think he's talking about the spaces. I think he's talking about
    the colons. One of his directories is "C:/WINNT". While I'd never have
    such a directory listed in cygwin myself (preferring /cygdrive/c/WINNT),
    it does appear to work...

    $ ls -ld "C:/WINDOWS"
    drwxrwx---+ 65 Administrators SYSTEM 0 Jun 15 08:37 C:/WINDOWS

    Then again, I'd argue that such a path isn't a valid "UNIX" path, so
    having that cause an error within cygwin isn't really a surprise.
     
    Darren Dunham, Jun 24, 2005
    #17
  18. I understand what you are saying, but I do not see how this is relevant
    to $PATH.

    I have my path set only in My Computer -> Properties > Advanced ->
    Environment Variables.

    If I run Cygwin perl, whether in Cygwin bash it correctly sees
    /cygdrive/c/WINDOWS where it is set as C:\WINDOWS in the My Computer
    dialog.

    Anyway, I have not seen a concrete code example from the OP that
    illustrates the problem.

    Sinan
     
    A. Sinan Unur, Jun 24, 2005
    #18
  19. la 24.06.2005 03:55 A. Sinan Unur skribis:
    I have no clue why, but on my company PC configured by an external company,
    when I start Cygwin, I get this kind of PATH='/bin:"C:/WINNT":"/Path/with
    space"' with some directories even listed
    both ways. And Cygwin finds commands in those "C:/..." entries, so it must be
    valid. Then also Perl programs should work with this, and not say "We'd like
    you to configure qour computer differently!"
     
    Daniel Pfeiffer, Jun 25, 2005
    #19
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.