Return Value from Background System Call

G

goodcall1

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";
}
 
G

goodcall1

Sherm said:
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
 
J

J. Gleixner

Sherm said:
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.
 
B

Ben Morrow

Quoth Sherm Pendley said:
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
 
M

Martijn Lievaart

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
 
J

Jack D

Martijn Lievaart said:
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
 

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. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,997
Messages
2,570,241
Members
46,831
Latest member
RusselWill

Latest Threads

Top