http://qs321.pair.com?node_id=605706

jdtoronto has asked for the wisdom of the Perl Monks concerning the following question:

Esteemed monks,

My monstrous Win32 app has, inevitably, been installed on a machine running VIsata (Business edition). To start and external editor to edit email documents I use the code:

@command = ( "gc_edemail.exe", $::cini_global->{newsletter}->{email_ +template_file} ); print "Now actually execute the command to edit \n"; if ( system( 1, @command) == 0 ) { print "Command: @command executed and returned 0\n"; } else { if ( $? == -1 ) { print "failed to execute: $!\n"; } else { printf "child ran with value %d\n", $? >> 8; } }
Which appears to execute normally (the editor opens and the main programme prints the "child ran with value..." portion.

But Vista pops up a window which says "..Application Name.. has stopped working." WHen you clear that dialogue the main programme closes and the child (the editor) is left, fully functioning.

Any clues?

jdtoronto

Replies are listed 'Best First'.
Re: Problem with 'system' function in Windows Vista
by ikegami (Patriarch) on Mar 20, 2007 at 17:52 UTC

    Your snippet makes no sense (although none of this explains the crash).

    • system(1, ...) does not return zero on success.
    • system(1, ...) does not return the exit code of the child. It returns the PID of the child.
    • $? is being checked before the child has finished running, so its value is meaningless.

    Did you really mean to execute the child asynchronously? You're acting as if you want the child to end before proceeding. If so, you want system(@cmd), not system(1, @cmd).

      Since this is Windows you might as well say system( "@commands" ) because that's what's really happening anyway. At least its clear then that everything in @commands has to be properly shell quoted.

      ⠤⠤ ⠙⠊⠕⠞⠁⠇⠑⠧⠊

        Yes and no.

        • No, system does quote (in ActivePerl, at least).

          @cmd = ( 'echo', 'identifier', 'a string', '"pre quoted"' ); system(@cmd); # identifier "a string" "pre quoted" $cmd = "@cmd"; system($cmd); # identifier a string "pre quoted"
        • Yes, sending the command as a string instead of a list of arguments is a good idea in Windows. In Windows, command line parsing is done by the child. That means every program has its own mechanism to quote and escape its parameters (*). In turn, that means that system (or the underlying library) must guess at how the child wants its arguments quoted and escaped.

          Avoid the guessing if possible and provide to the child what the child will receive.

        * — If any! When quoting is supported, it's usually double quotes. As for an escaping mechanism, I don't remember ever seeing one, so good luck trying to pass a double quote to a program...

Re: Problem with 'system' function in Windows Vista
by Joost (Canon) on Mar 20, 2007 at 17:36 UTC

      system(1, ...) is a Windows extention to create a process that runs asynchronously. It's an alternative to fork+exec. Unlike fork, system(1, ...) is natively supported, so it's much more resilient.

      Hi Joost,

      The

      I keep forgetting what system(1, @command) does. (it's windows specific, right?)
      Is Windows specific, it is meant to give a non-blocking system call - it gets the result of the creation of the child process and returns it. I have also tried it without the 1, works as expected and gives the same error.

      jdtoronto