Newsgroup: it.comp.lang.perl
Titolo: File descriptor 0 e 1 passati a prog esterno

Mi rivolgo al NG per un problema per me troppo "ostico".
Perl 5.6.0 su piattaforma Linux (RedHat 7.1).
Devo passare da un mio script Perl delle informazioni (due) ad un software
esterno (per chi conosce QMAIL: /var/qmail/bin/qmail-queue) non scritto da
me.
Questo sw si aspetta che queste due informazioni siano passate tramite i
file descriptor zero ed uno.
In shell si scriverebbe una cosa del genere (tanto per dare l'idea):
echo "informazione1" >msg1.txt
echo "informazione2" | /var/qmail/bin/qmail-queue 1<msg1.txt
In Perl e' semplice "copiare" STDIN (file descriptor 0) e STDOUT e
redirigere quello che ci serve con poche righe di codice e poi ripristinare
STDIN e STDOUT, ma c'e' un problema (leggete il seguito):
---------------< cut here >-----------
#!/usr/bin/perl
$|=1;
$prog = '/var/qmail/bin/qmail-queue';
$infofile1 = './info1.txt';
$infofile2 = './info2.txt';
# salvo i due filehandle
open(CPOUT,">&STDOUT") or die "cp1 stdout";
open(CPIN,"<&STDIN") or die "cp1 stdin";
# li ridirigo
open(STDOUT,"<$infofile1") or die "infofile1";
open(STDIN,"<$infofile2") or die "infofile2";
system($prog);
close(STDOUT);
close(STDIN);
# ripristino il normale funzionamento di STDIN e STDOUT
open(STDOUT,">&CPOUT") or die "cp2 stdout";
open(STDIN,"<&CPIN") or die "cp2 stdin";
etc. etc.
---------------< cut here >-----------
Il problema e' che questo sistema funziona perfettamente, ma mi obbliga a
scrivere le informazioni nei due files info1.txt e info2.txt e questo mi
provoca un sovraccarico del sistema.
Questa routine deve essere chiamata qualcosa come 500.000 volte nel minor
tempo possibile e l'overhead causato dalla scrittura sui due files e'
inaccettabile.
La domanda e': c'e' un modo per ottenere la stessa cosa ma passare il
contenuto di due variabili direttamente al sw esterno, passandole come file
descriptor 0 e 1 ??
Ossia una cosa del genere:
---------------< cut here >-----------
#!/usr/bin/perl
$|=1;
$prog = '/var/qmail/bin/qmail-queue';
$info1 = 'miainformazione numero 1'
$info2 = 'miainformazione numero 2';
?????
$rc=system($prog);
?????
---------------< cut here >-----------
Grazie per ogni commento e suggerimento :-))

Garanzie di funzionamento, zero.
Pero' potrebbe funzionare.
Fossi in te, pero' indagherei su come sostituire qmail-queue con una 
soluzione in perl puro per evitare l'overhead del fork e dell'exec.
## START
my $qmail_queue = "/var/qmail/bin/qmail-queue";
pipe (FILE0IN, FILE0OUT) or die;
pipe (FILE1IN, FILE1OUT) or die;
my $qq_pid = fork;
die unless defined $qq_pid;
if ($qq_pid == 0) { # child
         close FILE0OUT;
         close FILE1OUT;
         open (STDIN,  "<&FILE0IN") or die;
         open (STDOUT, "<&FILE1IN") or die;
         exec $qmail_queue or die;
} else { # parent
         $SIG{'PIPE'} = 'IGNORE';
         close FILE0IN;
         close FILE1IN;
         print FILE0OUT "quel che deve andare sul file descriptor 0";
         print FILE1OUT "quel che deve andare sul file descriptor 1";
         close FILE0OUT;
         close FILE1OUT;
 
         # make sure qmail-queue exits okay
         waitpid ($qq_pid,0);
         my $status = $?;
}
## END


 Pero' potrebbe funzionare.
Si', anch'io avevo trovato degli esempi in tal senso, ma appunto per ragioni
di efficienza NON volevo forkare un processo....
Quindi grazie per l'interessamento ma non mi conviene :-)

Quindi grazie per l'interessamento ma non mi conviene :-)
Beh, tu utilizzavi una system() che il fork lo fa lo stesso :)
Se vuoi usare un programma esterno non lo puoi evitare.