Perl / Embperl - IPC::Open3
У меня есть пример программы в 2 форматах Perl и Embperl
Версия perl работает как CGI, но версия embperl не работает.
Любые предложения или указатели на решения будут оценены
ОС: Linux версии 2.6.35.6-48.fc14.i686.PAE (...) (версия gcc 4.5.1 20100924 (Red Hat 4.5.1-4) (GCC)) #1 SMP пт 22 октября 15:27:53 UTC 2010
ПРИМЕЧАНИЕ: я первоначально разместил этот вопрос в perlmonks [x] и списке рассылки embperl [x], но не нашел решения.
Perl рабочий скрипт
#!/usr/bin/perl
use warnings;
use strict;
use IPC::Open3;
print "Content-type: text/plain\n\n";
my $cmd = 'ls';
my $pid = open3(*HIS_IN, *HIS_OUT, *HIS_ERR, $cmd);
close(HIS_IN); # give end of file to kid, or feed him
my @outlines = <HIS_OUT>; # read till EOF
my @errlines = <HIS_ERR>; # XXX: block potential if massive
print "STDOUT: ", @outlines, "\n";
print "STDERR: ", @errlines, "\n";
waitpid( $pid, 0 );
my $child_exit_status = $? >> 8;
print "child_exit_status: $child_exit_status\n";
неработающий скрипт embperl
[-
use warnings;
use strict;
use IPC::Open3;
my $cmd = 'ls';
my $pid = open3(*HIS_IN, *HIS_OUT, *HIS_ERR, $cmd);
close(HIS_IN); # give end of file to kid, or feed him
my @outlines = <HIS_OUT>; # read till EOF
my @errlines = <HIS_ERR>; # XXX: block potential if massive
print OUT "STDOUT: ", @outlines, "\n";
print OUT "STDERR: ", @errlines, "\n";
waitpid( $pid, 0 );
my $child_exit_status = $? >> 8;
print OUT "child_exit_status: $child_exit_status\n";
-]
Вот вывод, который я получаю
STDERR: ls: write error: Bad file descriptor
child_exit_status: 2
2 ответа
open3
перенаправляет файловый дескриптор, связанный с STDOUT, исключая его как fd 1
(какая программа у тебя exec
рассмотрим STDOUT). Но это не 1
, С ним даже не связан дескриптор файла! Я считаю это ошибкой в open3
, Я думаю, что вы можете обойти это следующим образом:
local *STDOUT;
open(STDOUT, '>&=', 1) or die $!;
...open3...
Спасибо ооочень большое ikegami!!!!
Вот код embperl, который работает. PS Есть похожая проблема с STDIN. Я пока не знаю решения, но думаю, что оно похоже.
[-
use warnings;
use strict;
use IPC::Open3;
use POSIX;
$http_headers_out{'Content-Type'} = "text/plain";
my $cmd = 'ls';
open(my $fh, '>', '/dev/null') or die $!;
dup2(fileno($fh), 1) or die $! if fileno($fh) != 1;
local *STDOUT;
open(STDOUT, '>&=', 1) or die $!;
my $pid = open3(*HIS_IN, *HIS_OUT, *HIS_ERR, $cmd);
close(HIS_IN); # give end of file to kid, or feed him
my @outlines = <HIS_OUT>; # read till EOF
my @errlines = <HIS_ERR>; # XXX: block potential if massive
print OUT "STDOUT: ", @outlines, "\n";
print OUT "STDERR: ", @errlines, "\n";
waitpid( $pid, 0 );
my $child_exit_status = $? >> 8;
print OUT "child_exit_status: $child_exit_status\n";
-]