Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??

I don't see a need for a hook between fork and exec hidden in system and open, and abusing %SIG for that hook makes it even worse. That hook introduces action-at-a-distance.

If you intend to make some stuff happen between fork and exec, write it explicitly:

sub redirected_system { my @args=@_; my $pid=fork() // die "Can't fork: $!"; if ($pid) { # (parent) waitpid($pid,0); # plus whatever is needed to collect data from the child } else { # (child) # modify file handles as needed (redirection) # change UID, GID if needed # chdir if needed # chroot if needed exec { $args[0] } @args or die "exec failed: $!"; } }

This is clean, readable, and has no action-at-a-distance. Of course, it is possible to use a generic function to allow changes to the child process without resorting to global variables:

sub hooked_system(&@) { my ($hook,@args)=@; my $pid=fork() // die "Can't fork: $!"; if ($pid) { # (parent) waitpid($pid,0); # plus whatever is needed to collect data from the child } else { # (child) $hook->(); exec { $args[0] } @args or die "exec failed: $!"; } }

I also don't see how a hook would solve the problem of perl invoking the default shell in case of three-argument pipe open or single-argument system. And please don't tell me that the hook code should start guessing how the single string should be splitted into a list of arguments. This is excactly what perl already does: It guesses, and if the string looks too complex to guess (see below), it delegates that to a random default shell. This is the cause of the trouble, not its solution.

qx, ``, system and pipe open are already wrappers for fork and exec. Adding more and more parameters will give us nightmares like CreateProcessAsUser(), effectively passing more than 30 parameters plus command line arguments to a nightmare function that will finally start a child process. See also Re^3: Set env variables as part of a command.


Perl guessing

exec states:

If there is only one element in LIST, 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.

So, what exactly are shell metacharacters? I don't know. My guess is that a lot of the non-alpanumeric, printable ASCII characters count as shell metacharacters. They may depend on the operating system, too. And they may have changed over time. It seems that Perl_do_exec3() in doio.c of the perl 5.24.1 sources contains at least a little bit of the guessing logic. And it seems that the word "exec" at the start of the string also forces perl to invoke the default shell, not only non-alphanumeric characters. To make things even worse, some of the logic depends on the preprocessor symbol CSH. My guess is that happens only if the default shell is a csh variant.

BTW: A trailing 2>&1 seems to be handled by perl as a special case, without resorting to the default shell.

Alexander

--
Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

In reply to Re^2: Improve pipe open? (redirect hook) by afoken
in thread Improve pipe open? by afoken

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others lurking in the Monastery: (2)
As of 2024-04-20 11:18 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found