Канал Perl и процесс C как дочерний [Windows] - PullRequest
1 голос
/ 02 июля 2010

Я хочу разветвить дочерний элемент (который является моим исполняемым файлом C) и разделить канал между процессом perl и C, возможно ли использовать STDOUT и STDIN для использования в качестве канала.

Пробовал с помощью следующего кода, нодочерний процесс продолжает работать.

use IPC::Open2;
use Symbol;
my $CHILDPROCESS= "chile.exe";
$WRITER = gensym();
$READER = gensym();

my $pid = open2($READER,$WRITER,$CHILDPROCESS);
while(<STDIN>)
{
   print $WRITER $_;
}
close($WRITER);
while(<$READER>)
{
    print STDOUT "$_";
}

Ответы [ 3 ]

1 голос
/ 02 июля 2010

Раздел Safe Pipe Opens документации perlipc описывает полезную функцию для этого:

Функция open примет файловый аргумент либо "-|", либо "|-", чтобы сделать очень интересную вещь: она разветвляет дочернего элемента, подключенного к открытому вами дескриптору файла. Ребенок выполняет ту же программу, что и родитель. Это полезно для безопасного открытия файла, например, при работе с предполагаемым UID или GID. Если вы открываете канал в минус, вы можете написать в файловый дескриптор, который вы открыли, и ваш ребенок найдет его в своем STDIN. Если вы открываете канал из минуса, вы можете прочитать из файлового дескриптора, который вы открыли, все, что ваш ребенок пишет в его STDOUT.

Но согласно документации perlport

открыт

открыто для |- и -| не поддерживаются. (Win32, RISC OS)

0 голосов
/ 30 октября 2010

Это вопросы и ответы на Perlmonks предполагает, что open2 отлично работает в Windows, при условии, что вы управляете им достаточно осторожно.

0 голосов
/ 02 июля 2010

РЕДАКТИРОВАТЬ: Это может работать только для Linux.Я не пробовал это для Windows.Хотя может быть способ эмулировать его в Windows.

Вот что вы хотите, я думаю:

#Set up pipes to talk to the shell.
pipe(FROM_PERL, TO_C) or die "pipe: $!\n";
pipe(FROM_C, TO_PERL) or die "pipe: $!\n";

#auto flush so we don't have (some) problems with deadlocks.
TO_C->autoflush(1);
TO_PERL->autoflush(1);

if($pid = fork()){
    #parent
    close(FROM_PERL) or die "close: $!\n";
    close(TO_PERL) or die "close: $!\n";
}
else{
    #child
    die "Error on fork.\n" unless defined($pid);

    #redirect I/O
    open STDIN, "<&FROM_PERL";
    open STDOUT, ">&TO_PERL";
    open STDERR, ">&TO_PERL";
    close(TO_C) or die "close: $!\n";
    close(FROM_C) or die "close $!\n";

    exec("./cprogram"); #start program
}

Теперь вы можете общаться с оболочкой через FROM_C и TO_C как ввод и выводсоответственно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...