[asterisk-users] broken pipe in perl agi

Steve Edwards asterisk.org at sedwards.com
Fri Jun 5 18:09:05 CDT 2009


On Fri, 5 Jun 2009, Danny Nicholas wrote:

> You're on the right track, Steve but that didn't do it either.  Here is 
> the Perl snippet:

> use strict;
> use warnings;
> my $towatch = $ARGV[0];
> my $a=0;
> my $retval=undef;
> # show hints will get hint information from the dialplan
> while ($a<1) {
>   my $cmda = '/usr/sbin/asterisk -rx "core show hints"|';
>   ####  Get Trunk Information ####
>   my %lines;
>   my $lineseq=0;
>   $SIG{'PIPE'} = 'IGNORE';
>   open (my $trunk_info,$cmda) or print STDOUT "Broken pipe\n";
>   if ($trunk_info) {
>      while (<$trunk_info>) {
>         if ($_ =~ /internal/) {
>            if ($_ =~ /$towatch/) {
>               $lines{$lineseq} = $_;
>               $lineseq++;
>               }
>            }
>         }
>      close $trunk_info;
>      }
>   sleep 2;
>
>   for (my $i=0;$i<=$lineseq;$i++) {
>      if ($lines{$i}) {
>         my $c = unpack("x74 a16", $lines{$i});
>         $c =~ s/\s//gx;
>         $retval=1;
>         print STDOUT "SET VARIABLE LINESTAT \"$c\" \r\n";
>         <STDIN>;
>         }
>      }
>   $a++;
>   }
> # if /var/run/asterisk.ctl is not mod 777, no result so we return a dummy
> Idle
> if (! $retval) {
>   my $c = "Idle";
>   print STDOUT "SET VARIABLE LINESTAT \"$c\" \r\n";
>   <STDIN>;
>   }
> exit;
>
> If there is an active call on the extension, it works.  If not, the 
> "broken pipe" message is returned.

I'm still thinking its a protocol issue.

I couldn't replicate the error on my 1.2 box. I don't use hints, so I read 
"hint data" from a file.

I noticed:

0) You don't use an AGI library

1) You don't turn off I/O buffering

2) You aren't reading the AGI environment

3) You have a "sleep" in between your 2 loops

4) You have a "while" loop on $a I don't think is needed

5) You could read Asterisk's output from "show hints" and process it in a 
single loop

6) "\r" is not needed

7) A space before the request terminator is not needed

I'm not much of a Perl weenie, but I made some changes you're welcome to 
use or discard :)

#!/usr/bin/perl

use     strict;
use     warnings;

# define variables
# show hints will get hint information from the dialplan
         my $cmda = '/usr/sbin/asterisk -rx "show hints"|';
# read hint data from a file for testing
#       my $cmda = 'cat /home/sedwards/hints|';
         my $towatch = $ARGV[0];

# turn off I/O buffering
         $| = 1;

# read the AGI environment
         while   (<STDIN>)
                 {
                 chomp($_);
                 last if 0 == length($_);
                 }

# assume idle
         print STDOUT "SET VARIABLE LINESTAT \"Idle\"\n";
         <STDIN>;

# get trunk information
         $SIG{'PIPE'} = 'IGNORE';
         open (my $trunk_info, $cmda) or exit;
         while   (<$trunk_info>)
                 {
                 if      (($_ =~ /internal/)
                 &&       ($_ =~ /$towatch/))
                         {
                         my $c = unpack("x74 a16", $_);
                         $c =~ s/\s//gx;
                         print STDOUT "SET VARIABLE LINESTAT \"$c\"\n";
                         <STDIN>;
                         }
                 }
         close $trunk_info;

# (end of hintcheck.agi)

OT, but I think I'm liking AMI more than "rx" in the new code I'm writing.

Thanks in advance,
------------------------------------------------------------------------
Steve Edwards      sedwards at sedwards.com      Voice: +1-760-468-3867 PST
Newline                                             Fax: +1-760-731-3000



More information about the asterisk-users mailing list