Return Value from Background System Call

Discussion in 'Perl Misc' started by goodcall1@hotmail.com, Dec 1, 2006.

  1. Guest

    Problem: I am having trouble figuring out why a system call in the
    background *always* returns 0. Debian Linux Perl 5.8.7

    What am I trying to do: I am trying to launch a browser from a perl/Tk
    button and it always returns 0 (and hence prints the failed to open
    browser message) whether or not the browser actually gets launched.

    Here is some sample code:

    my $browser = '/usr/bin/firefox';
    my $url = 'http://www.google.ca';

    my $return = system ("$browser \"$url\" &");
    if (!$return) {
    print "failed to open browser\n";
    }
     
    , Dec 1, 2006
    #1
    1. Advertising

  2. Guest

    Sherm Pendley wrote:
    > writes:
    >
    > > Problem: I am having trouble figuring out why a system call in the
    > > background *always* returns 0. Debian Linux Perl 5.8.7
    > >
    > > What am I trying to do: I am trying to launch a browser from a perl/Tk
    > > button and it always returns 0 (and hence prints the failed to open
    > > browser message)

    >
    > As the docs for system() state, a return value of 0 does not indicate failure:
    >
    > perldoc -f system
    >


    That is correct - 0 should indicate success - this is why I have if
    (!$return) - i.e. for a non-zero return print the error message. The
    problem is - no matter what happens a 0 *always* gets returned. I threw
    in a false location of /usr/bin/firfox (note the e is missing) but a 0
    gets returned (indicating success) but no window get launched obviously
    as there is no such executable (firfox) on my system.

    I beginning to wonder what the "success" indicator of 0 points to? Ok
    - so I found this in the docs:

    "The return value is the exit status of the program as returned by
    the "wait" call. "

    So I look up perldoc -f wait and see this:

    "The status is returned in $?"

    So - again checking $? gives a value of zero.

    Let's start from the beginning and hopefully someone can answer one
    specific question:

    How do I launch a browser as a background process and *know* whether or
    not it was launched?

    Jack
     
    , Dec 1, 2006
    #2
    1. Advertising

  3. J. Gleixner Guest

    Sherm Pendley wrote:
    > writes:
    >
    >> Problem: I am having trouble figuring out why a system call in the
    >> background *always* returns 0. Debian Linux Perl 5.8.7
    >>
    >> What am I trying to do: I am trying to launch a browser from a perl/Tk
    >> button and it always returns 0 (and hence prints the failed to open
    >> browser message)

    >
    > As the docs for system() state, a return value of 0 does not indicate failure:
    >
    > perldoc -f system


    I think it's always 0 because the backgrounding of the process was
    successful.

    #!/usr/local/bin/perl
    my $cmd = '/some/made/up/cmd';

    print "Running $cmd\n";
    $ret = system( $cmd );
    print "ret=$ret\n"

    print "Running $cmd &\n";
    $ret = system( "$cmd &" );
    print "ret=$ret\n";


    Running /some/made/up/cmd
    /some/made/up/cmd: not found
    ret=-1
    Running /some/made/up/cmd &
    ret=0


    You could redirect STDERR to a file, sleep for a couple of seconds, then
    read the file for errors, or possibly if its size is > 0 bytes.
     
    J. Gleixner, Dec 1, 2006
    #3
  4. Ben Morrow Guest

    Quoth Sherm Pendley <>:
    > writes:
    >
    > > Sherm Pendley wrote:
    > >> writes:
    > >>
    > >> > Problem: I am having trouble figuring out why a system call in the
    > >> > background *always* returns 0. Debian Linux Perl 5.8.7
    > >> >
    > >> > What am I trying to do: I am trying to launch a browser from a perl/Tk
    > >> > button and it always returns 0 (and hence prints the failed to open
    > >> > browser message)
    > >>
    > >> As the docs for system() state, a return value of 0 does not indicate
    > >> failure:
    > >>
    > >> perldoc -f system
    > >>

    > >
    > > That is correct - 0 should indicate success

    >
    > That's not what I said, although I'll admit the difference is subtle. The
    > fact that 0 does not indicate failure does not necessarily imply that it
    > always indicates success. All it means is that the system() call itself
    > succeeded, and that the launched app returned a 0 exit status.
    >
    > The meaning of a 0 exit status has to be interpreted in the context of the
    > launched app. For many apps, a 0 exit status is used to indicate failure of
    > a different sort than a general failure to execute the app,


    I think you are getting confused here. A 0 exit status indicates
    success...

    > such as bogus arguments or malformed input files. This allows command
    > "chains" such as the following:
    >
    > gcc -o foo foo.c && mv ./foo /usr/local/bin/foo


    ....otherwise this would *not* work as desired. The shell treats 0 as
    true and not-0 as false. gcc only exits with 0 if it was successful.

    > Also keep in mind that the exit status of a program is whatever value is
    > returned from exit() or main(). Since you're launching this app in the
    > background and it's still running, that's probably why you're getting all
    > zeroes - you can't get an exit status from an app until it actually exits.


    Please read the docs for the functions you are talking about. system
    does not return until the command has exitted. Adding an & doesn't
    change that. However, it *does* make system execute the command via a
    shell instead of directly, and it is the shell which is exitting with 0,
    as it has sucessfully finished executing the script '/usr/bin/firefox
    &'.

    I would advise the OP to fork/exec manually in Perl, as then you can see
    what is actually happening.

    Ben

    --
    All persons, living or dead, are entirely coincidental.
    Kurt Vonnegut
     
    Ben Morrow, Dec 2, 2006
    #4
  5. On Mon, 04 Dec 2006 13:02:47 -0500, Sherm Pendley wrote:

    > One-argument system() will *always* execute its command via a shell. To
    > bypass shell command parsing and execute a program directly, one uses
    > the multi-argument form of system().


    No actually not. System defers for an explantion to exec, which says:

    If there is more than one argument in LIST, or if LIST is
    an array with more than one value, calls execvp(3) with the
    arguments in LIST. If there is only one scalar argument or
    an array with one element in it, the argument is checked
    for shell metacharacters, and if there are any, the entire
    argument is passed to the system’s command shell for
    parsing (this is "/bin/sh -c" on Unix platforms, but varies
    on other platforms). If there are no shell metacharacters
    in the argument, it is split into words and passed directly
    to "execvp", which is more efficient.

    M4
    --
    Redundancy is a great way to introduce more single points of failure.
     
    Martijn Lievaart, Dec 4, 2006
    #5
  6. Jack D Guest

    "Martijn Lievaart" <> wrote in message
    news:p...
    > On Mon, 04 Dec 2006 13:02:47 -0500, Sherm Pendley wrote:
    >
    > > One-argument system() will *always* execute its command via a shell. To
    > > bypass shell command parsing and execute a program directly, one uses
    > > the multi-argument form of system().

    >
    > No actually not. System defers for an explantion to exec, which says:
    >
    > If there is more than one argument in LIST, or if LIST is
    > an array with more than one value, calls execvp(3) with the
    > arguments in LIST. If there is only one scalar argument or
    > an array with one element in it, the argument is checked
    > for shell metacharacters, and if there are any, the entire
    > argument is passed to the system's command shell for
    > parsing (this is "/bin/sh -c" on Unix platforms, but varies
    > on other platforms). If there are no shell metacharacters
    > in the argument, it is split into words and passed directly
    > to "execvp", which is more efficient.
    >


    Thanks to *all* for your insight.

    For something I thought would be so simple, this is turning out not to be
    the case.

    I did try the fork and exec route (remember this is Tk) but it hung the
    MainLoop. I'm not sure why - as there are success stories on the c.l.p.t.
    newsgroup. I have given up and decided *not* to check if the browser was
    launched. The user will know whether it launches or not. As long as it
    doesn't leave any zombies - I'm okay with it. When I'm back in front if my
    Linux box - I will try varying the argument list as above.

    Thanks.

    Jack
     
    Jack D, Dec 5, 2006
    #6
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. David Scott Williams

    Strange return value from os.system(...) call

    David Scott Williams, Oct 13, 2004, in forum: Python
    Replies:
    1
    Views:
    1,815
    Michael Fuhr
    Oct 13, 2004
  2. Greenhorn
    Replies:
    15
    Views:
    847
    Keith Thompson
    Mar 6, 2005
  3. POSIX system() call return value

    , Oct 23, 2006, in forum: C Programming
    Replies:
    4
    Views:
    438
    Keith Thompson
    Oct 23, 2006
  4. Calder Coalson

    Return value from os.system() call

    Calder Coalson, Oct 28, 2007, in forum: Python
    Replies:
    1
    Views:
    1,331
    Wildemar Wildenburger
    Oct 28, 2007
  5. Raymond O'Connor
    Replies:
    1
    Views:
    151
    Raymond O'Connor
    Mar 8, 2007
Loading...

Share This Page