diomedea has asked for the wisdom of the Perl Monks concerning the following question:

Dear Perl monks, i am trying to write the results of some parsing to a fifo to be read by the oracle sqlloader, all in the same perl script but i cant make it work without blocking.. heres the code:
if ($pid = open ($fifo, "|-")) # cookbok 16.11 open for r and w to ava +oid blocks { $fifo->autoflush(1); no warnings; foreach my $ky (sort keys %categories) { print $fifo "$categories{$ky}#"; } close $fifo or die $! ? "Syserr closing fifo writer: $!" : "Wait status $? from fifo writer"; } else # child { die "Cannot fork: $!" unless defined $pid; # copy from parent (now stdin) into the file # need to redirect st +din? #$fifofile->autoflush(1); while (<STDIN>) { $fifofile = $_; # print $fifofile; system "sqlldr control=atpctl.ctl data=atp_fifo.dat userid=someu +ser/pwd log=loader.log"; } exit; # Don't forget to make the fifo disappear. }
I can get the writer to print the line to stdout but sqlloader just hangs. im not wedded to this approach if it looks like a bad thing to do, but i have to parse 1000 files and read them in, so id rather do it in memory. thanks

Replies are listed 'Best First'.
Re: writing to and reading from fifo
by Anno (Deacon) on Mar 26, 2007 at 09:51 UTC
    Two things make me wonder. You write

    I can get the writer to print the line to stdout but sqlloader just hangs.

    Your code

    print $fifo "$categories{$ky}#";
    doesn't print lines (unless there are line feeds embedded in $categories{$ky}), but you are using line oriented <STDIN> to read the data. That may lead to unexpected blocking.

    Second, as far as I understand sqlldr, your command

    "sqlldr control=atpctl.ctl data=atp_fifo.dat userid=someu +ser/pwd log=loader.log"
    will try to read data from the disk file "atp_fifo.dat". I don't see how that file is connected to the pipe output.

    Anno

      ++Anno does speak wisdom on this subject.

      All the binaries in $ORACLE_HOME/bin (that I used, with Oracle 10G) refused to read/write STDIN/STDOUT they would tend to take their configuration from files on the disk...

      I ended up generating the config files with templates, and writing them in /tmp with a unique filename. I wish I'd used File::Temp

      @_=qw; ask f00li5h to appear and remain for a moment of pretend better than a lifetime;;s;;@_[map hex,split'',B204316D8C2A4516DE];;y/05/os/&print;
        yes this approach does work but I cant understand why i cant read the named pipe to sqlldr from within the program.. iam sure something is blocking somewhere ... back to the manuals i guess ;+)