implementation of system()
implementation of system()
am 04.09.2007 21:36:18 von markhn
While working on a souped-up replacement for system(), I realized that
it's significantly more magical than I originally thought.
Specifically, I can't explain how it's able to set $! and return -1 when
exec() fails, since the exec() happens after a fork(), in the child process.
The examples I can find of the fork-and-exec paradigm (IPC::Open3, for
example) invariably seem to just croak or die when exec fails, leaving
the parent with no surefire way to distinguish between a failed exec()
and a successful exec() followed by a failure in the new program. Can
anyone shed some light on how system() works its magic?
Re: implementation of system()
am 04.09.2007 22:36:58 von Klaus
On Sep 4, 9:36 pm, "Nicholas R. Markham" wrote:
> While working on a souped-up replacement for system(), I realized that
> it's significantly more magical than I originally thought.
> Specifically, I can't explain how it's able to set $! and return -1 when
> exec() fails, since the exec() happens after a fork(), in the child process.
>
> The examples I can find of the fork-and-exec paradigm (IPC::Open3, for
> example) invariably seem to just croak or die when exec fails, leaving
> the parent with no surefire way to distinguish between a failed exec()
> and a successful exec() followed by a failure in the new program. Can
> anyone shed some light on how system() works its magic?
the answer lies probably in perldoc -f system:
===================================
[...]
Return value of -1 indicates a failure to start the program or an
error of the wait(2) system call (inspect $! for the reason).
[...]
You can check all the failure possibilities by inspecting $?
like this:
if ($? == -1) {
print "failed to execute: $!\n";
}
elsif ($? & 127) {
printf "child died with signal %d, %s coredump\n",
($? & 127), ($? & 128) ? 'with' : 'without';
}
else {
printf "child exited with value %d\n", $? >> 8;
}
or more portably by using the W*() calls of the POSIX extension;
see perlport for more information.
===================================
--
Klaus
Re: implementation of system()
am 04.09.2007 22:39:02 von pacman
In article <46ddb3bb$0$18964$4c368faf@roadrunner.com>,
Nicholas R. Markham wrote:
>While working on a souped-up replacement for system(), I realized that
>it's significantly more magical than I originally thought.
>Specifically, I can't explain how it's able to set $! and return -1 when
>exec() fails, since the exec() happens after a fork(), in the child process.
It creates a pipe before forking and the child writes errno to the pipe after
exec failure. This makes it more magical and friendly than C's system(). It
has been this way since perl 5.6
--
Alan Curry
pacman@world.std.com
Re: implementation of system()
am 04.09.2007 23:04:57 von Ilya Zakharevich
[A complimentary Cc of this posting was sent to
Alan Curry
], who wrote in article :
> In article <46ddb3bb$0$18964$4c368faf@roadrunner.com>,
> Nicholas R. Markham wrote:
> >While working on a souped-up replacement for system(), I realized that
> >it's significantly more magical than I originally thought.
> >Specifically, I can't explain how it's able to set $! and return -1 when
> >exec() fails, since the exec() happens after a fork(), in the child process.
>
> It creates a pipe before forking and the child writes errno to the pipe after
> exec failure. This makes it more magical and friendly than C's system().
No. Only on legacy OSes it is more friendly than C's one. On
contemporary OSes system() already behaves this way (since they are
not based on the botched fork()/exec() paradigm).
*This* was the motivation to implement this feature...
Hope this helps,
Ilya
Re: implementation of system()
am 04.09.2007 23:35:23 von Ben Morrow
Quoth "Nicholas R. Markham" :
> While working on a souped-up replacement for system(), I realized that
> it's significantly more magical than I originally thought.
> Specifically, I can't explain how it's able to set $! and return -1 when
> exec() fails, since the exec() happens after a fork(), in the child process.
>
> The examples I can find of the fork-and-exec paradigm (IPC::Open3, for
> example) invariably seem to just croak or die when exec fails, leaving
> the parent with no surefire way to distinguish between a failed exec()
> and a successful exec() followed by a failure in the new program. Can
> anyone shed some light on how system() works its magic?
Err, yes, pp_system in pp_sys.c in the perl distribution can, though
it's a little hard to follow. Basically, system creates a pipe before
forking, the child makes sure it's set to close-on-exec (so if the exec
succeeds it doesn't affect the new program in any way), and if the exec
fails the child writes errno to the pipe before _exitting. So the parent
either gets a closed pipe (exec succeeded) or an errno value followed by
a closed pipe (exec failed).
Ben
Re: implementation of system()
am 04.09.2007 23:50:36 von pacman
In article , some PoB barfed up:
>Alan Curry
>> It creates a pipe before forking and the child writes errno to the pipe after
>> exec failure. This makes it more magical and friendly than C's system().
>
>No. Only on legacy OSes it is more friendly than C's one. On
>contemporary OSes system() already behaves this way (since they are
>not based on the botched fork()/exec() paradigm).
>
>*This* was the motivation to implement this feature...
Yeah, we were jealous of Windoze. You've got it exactly. Nobody in the unix
world ever does anything original, like invent perl for instance. No need to
pay any more attention to us.
--
Alan Curry
pacman@world.std.com
Re: implementation of system()
am 05.09.2007 02:43:54 von Ilya Zakharevich
[A complimentary Cc of this posting was sent to
Alan Curry
], who wrote in article :
> >it's significantly more magical than I originally thought.
> >Specifically, I can't explain how it's able to set $! and return -1 when
> >exec() fails, since the exec() happens after a fork(), in the child process.
>
> It creates a pipe before forking and the child writes errno to the pipe after
> exec failure. This makes it more magical and friendly than C's system(). It
> has been this way since perl 5.6
The major trick is to CLOEXEC the kid side of the pipe. So if exec()
succeeds, the parent knows immediately.
Hope this helps,
Ilya
Re: implementation of system()
am 05.09.2007 15:19:37 von markhn
Alan Curry wrote:
> In article <46ddb3bb$0$18964$4c368faf@roadrunner.com>,
> Nicholas R. Markham wrote:
>> While working on a souped-up replacement for system(), I realized that
>> it's significantly more magical than I originally thought.
>> Specifically, I can't explain how it's able to set $! and return -1 when
>> exec() fails, since the exec() happens after a fork(), in the child process.
>
> It creates a pipe before forking and the child writes errno to the pipe after
> exec failure. This makes it more magical and friendly than C's system(). It
> has been this way since perl 5.6
Interesting - this is precisely the solution I came up with on my own.
Scary...
Re: implementation of system()
am 05.09.2007 16:03:07 von Josef Moellers
Nicholas R. Markham wrote:
> Alan Curry wrote:
>> It creates a pipe before forking and the child writes errno to the=20
>> pipe after
>> exec failure. This makes it more magical and friendly than C's=20
>> system(). It
>> has been this way since perl 5.6
>=20
>=20
> Interesting - this is precisely the solution I came up with on my own. =
> Scary...
Why is that "scary"? Developers often think alike and often=20
independently find similar solutions to the same problem. It's one of=20
the reasons why software patents would be the death blow to a lot of=20
software developers.
--=20
These are my personal views and not those of Fujitsu Siemens Computers!
Josef Möllers (Pinguinpfleger bei FSC)
If failure had no penalty success would not be a prize (T. Pratchett)
Company Details: http://www.fujitsu-siemens.com/imprint.html