Bradley,
> Yes. I have posted what I think is a single message's path through the
> logs. It does result in a bad file descriptor error. It is up at
> http://www.tux.org/~storm/files/amavisd.log.1
Thanks, the output from file(1) looks normal, yet your PerlIO or libc
returns incorrect status on reading the last line. I'm quite sure
it is related to the mentioned Perl I/O bug. It shows on some platforms,
and not on others. I'd suggest you try on a different OS platform,
perhaps as Gary suggests, or SUSE or whatever is supported by Zimbra.
As a quick-and-dirty workaround you may just comment out the
check for error status, although this way you'll never know
when a true error occurs. Just comment out the two lines:
defined $ln || $!==0 || $!==EAGAIN
or die "Error reading from file(1) utility: $!";
For experimenting, here is a small test program in Perl,
which mimics what amavisd does: forks a file(1) command
giving it some filename as argument, and reads output from
pipe line by line, printing each line, and checking status.
E.g.: $ ./this-prog some-file.txt
#!/usr/bin/perl
use strict;
use IO::File;
use POSIX;
my($cmd) = 'file';
my(@args) = shift;
my($pid); my($proc_fh) = IO::File->new;
$pid = $proc_fh->open('-|');
defined($pid) or die "run_command: can't fork: $!";
if (!$pid) { # child
open_on_specific_fd(0, '/dev/null', &POSIX::O_RDONLY,0);
open_on_specific_fd(2, '&1', &POSIX::O_WRONLY,0);
exec {$cmd} ($cmd,@args);
die "Exec failed: $!";
POSIX::_exit(8); # avoid END and destructor processing
}
binmode($proc_fh) or die "Can't set pipe to binmode: $!";
my($ln);
for ($! = 0; defined($ln=$proc_fh->getline); $! = 0) {
printf("result line from file(1): %s", $ln);
}
defined $ln || $!==0 || $!==EAGAIN
or die "Error reading from file(1) utility: $!";
sub open_on_specific_fd($$$$) {
my($fd_target,$fname,$flags,$mode) = @_; my($fd_got);
if ($fname =~ /^&=?(\d+)\z/) { $fd_got = $1 } # fd directly specified
if (!defined($fd_got) || $fd_got != $fd_target) {
POSIX::close($fd_target); # ignore error, we may have just closed a log
}
if (!defined($fd_got)) { # file name was given, not a descriptor
$fd_got = POSIX::open($fname,$flags,$mode);
defined $fd_got or die "Can't open $fname: $!";
$fd_got = 0 + $fd_got; # turn into numeric, avoid: "0 but true"
}
if ($fd_got != $fd_target) { # dup, ensuring we get a specified descriptor
defined POSIX::dup2($fd_got,$fd_target)
or "Can't dup2 from $fd_got to $fd_target: $!";
if ($fd_got > 2)
{ defined POSIX::close($fd_got) or die "Can't close: $!" }
}
}
Mark
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
AMaViS-user mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/amavis-user
AMaViS-FAQ:http://www.amavis.org/amavis-faq.php3
AMaViS-HowTos:http://www.amavis.org/howto/