dissident has asked for the wisdom of the Perl Monks concerning the following question:
So I have a subroutine "system2" in the code below.
It takes as argument a command line string, and other stuff.
This subroutine "system2" gets called from the subroutine "main" at the end of the code.
To test it, I am using a simple C program:
#include <stdio.h> main() { fprintf(stdout,"This is output on stdout! \n"); fprintf(stderr,"This is output on stderr! \n"); sleep(10); return 0; }
My Perl script described above is this:
#!/usr/local/bin/perl use strict; use warnings; use POSIX ":sys_wait_h"; $|++; # away with buffering # stringref read_a_file( string filename) sub read_a_file { my $fn = shift; local $/ = undef; open FILE, $fn or return undef; my $text = <FILE>; close FILE or return undef; return \$text; } # int system2( string cmdline, # stringref retmsg, # stringref stdoutttxr, # stringref stderrtxr) sub system2 { my $er = shift; my $cmd = shift; my $stdouttxr = shift; my $stderrtxr = shift; my $retval; my $stdoutfn = '/tmp/teststdout'; my $stderrfn = '/tmp/teststderr'; unlink ($stdoutfn) if (-e $stdoutfn); unlink ($stderrfn) if (-e $stderrfn); my $pid = fork(); if ($pid < 0) { $$er .= "Forking failed with return code $pid."; return $pid; } elsif ($pid == 0) { # CHILD use POSIX qw(setsid); setsid() or die "Can't start a new session: $!"; chdir('/'); $SIG{HUP} = 'IGNORE'; umask 0033; close STDIN or die; close STDOUT or die; close STDERR or die; open(STDIN, '</dev/null') or die; open(STDOUT, ">$stdoutfn") or die; open(STDERR, ">$stderrfn") or die; my @argv = split(/ /, $cmd); exec( @argv); } my $wpid = waitpid($pid,0); my $normalexit = WIFEXITED(${^CHILD_ERROR_NATIVE}); if ($normalexit) { $retval = WEXITSTATUS(${^CHILD_ERROR_NATIVE}); } else { if (WIFSIGNALED(${^CHILD_ERROR_NATIVE})) { $$er .= "Child terminated due to signal"; if (WTERMSIG(${^CHILD_ERROR_NATIVE})) { $$er .= ": SIGTERM"; } } } if (-e $stdoutfn) { if (-s $stdoutfn) { my $s = read_a_file($stdoutfn); die if (not defined $s); $$$stdouttxr = $s; } unlink ($stdoutfn); } if (-e $stderrfn) { if (-s $stderrfn) { my $s = read_a_file($stderrfn); die if (not defined $s); $$$stderrtxr = $s; } unlink ($stderrfn); } return $retval; } sub main { my $er = ''; my $cmd = '/path_to_a_out/a.out'; my $stdouttxr = undef; my $stderrtxr = undef; my $ret = system2($cmd,\$er,\$stdouttxr,\$stderrtxr); if (defined $ret) { print "return value = '$ret'\n"; } else { print "return value = undef\n"; } if ($er ne '') { print "Error text: '$er'\n"; } else { print "No error text!\n"; } if (defined $stdouttxr) { print "STDOUT: '$$$stdouttxr'\n"; } else { print "No stdout output!\n"; } if (defined $stderrtxr) { print "STDERR: '$$$stderrtxr'\n"; } else { print "No stderr output!\n"; } return 0; } exit main();
No matter whether I use '/path_to_a_out/a.out' or 'exec /path_to_a_out/a.out' as command string, the output is always this:
% perl -w system2.pl return value = '2' No error text! No stdout output! STDERR: 'sh: Syntax error: word unexpected (expecting ")") ' %
This looks to me as if Perl gives something to sh, which the latter is unable to swallow.
Any idea what am I doing wrong?
|
---|
Replies are listed 'Best First'. | |
---|---|
Re: exec() fails with strange message
by hv (Prior) on May 17, 2024 at 21:43 UTC | |
by dissident (Beadle) on May 17, 2024 at 22:21 UTC |