in reply to Broken Pipe error when talking to Festival server

Try checking to see what syswrite returns. Maybe your call is not writing all of buffer. If so syswrite will return how much it actually wrote. You could then used the offset parament of syswrite to continue to write the rest of the buffer. I have a similar app that writes data to a socket connection. Here is how I implement it...
# # Sub used to write data to FDMS. # Writing requires that the first 6 bytes are NBxxxx # where xxxx is the total number of bytes to write plus the NBxxxx. # sub write { my ($this, $buffer) = @_; my $thisSub = (caller(0))[3]; my $socket = $this->{socket}; my $select = $this->{select}; my $verbose = $this->{verbose}; my $timeout = $this->{writeTimeout}; $buffer = sprintf('NB%04d%s', length($buffer) + 6, $buffer); my $length = length($buffer); my $offset; my $bytes; while ($length > 0) { if ($select->can_write($timeout)) { $bytes = $socket->syswrite($buffer, $length, $offset); croak "Unable to write: $!" unless defined $bytes; $offset += $bytes; $length -= $bytes; print "$thisSub($bytes) = $buffer\n" if $verbose; } else { croak 'timeout on write'; } } }

UPDATE:
try putting in a signal handler for SIGPIPE to see if you can get around the problem.
Something like...
$SIG{PIPE} = sub { die "SIGPIPE\n"; };
...just to see if it is happening.

UPDATE:
See this post...
script dies with 'broken pipe'-message, even in eval

Replies are listed 'Best First'.
Re^2: Festival Module
by rsiedl (Friar) on Sep 24, 2004 at 11:12 UTC
    thanks for your input. I've tried the $SIG{PIPE} and it is dying so it is happening. I've tried to simplify it into the following:
    Module (Voice.pm):
    package Voice; use IO::Socket; sub new { shift; my $self = {}; bless($self); return $self; } # end-new sub talk { $handle = IO::Socket::INET->new(Proto => "tcp", PeerAdr => "localhost", PeerPort => 1314) || die($!); print $handle "(SayText \"Testing.\")" || die($!); } # end-talk 1;
    Script (test.cgi):
    #!/usr/bin/perl use CGI qw(:header); print header; use Voice; my $voice = new Voice; $voice->talk; exit;
    When I run test.cgi through a web browser I get nothing (even if the festival server is not running). When I run it from the command line, I get "broken pipe" regardless of whether the festival server is running or not.
    The following script works just fine:
    #!/usr/bin/perl use IO::Socket; $handle = IO::Socket::INET->new(Proto => "tcp", PeerAddr => "localhost", PeerPort => 1314) || die($!); print $handle "(SayText \"Testing.\")"; exit;
    Being a newbie at perl modules my guess is that I've done something wrong in writing the module but I really dont know.
      UPDATED from original post.

      I tried you're simpler test script with $voice->talk, and it wouldn't even work without cgi. If you find the answer, let us know. I'm interested in learning about using sockets in modules, and there seems to be a trick to it, which eludes me. Like you it works from a conventional script. I did get it working from a simple procedural style module, but as soon as I put the $socket into a $self->{CONN} form, it gives a broken pipe. It has to be they way the socket gets stored in the scalar. Either a reference to the scalar needs to be used, or the socket needs to be stored as a full fledged hash? I just started reading my Object Oriented Perl, but hav'nt got far enough yet. :-)

      package Voice2; use IO::Socket; $handle = IO::Socket::INET->new(Proto => "tcp", PeerAddr => "localhost", PeerPort => 1314) || die($!); sub talk { print $handle "(SayText \"Testing.\")"; } 1;
      Test script
      #!/usr/bin/perl use lib '.'; use Voice2; Voice2::talk; exit;

      I'm not really a human, but I play one on earth. flash japh