4

このサブルーチンを使用してファイルにログインする Perl (リビジョン 5.0 バージョン 8 サブバージョン 0) の TCP サーバーがあります。

sub logger {
  return if ($LOGFILE eq "") ;
  my ($idt, $str) = @_ ;
  unless( defined($str) ) {
    $str = $idt ;
    $idt = '' ;
  }
  my ($s,$m,$h,$J,$M,$A) = localtime(time()) ;
  if(!open(OUT,">>$LOGFILE")) {
    warn "logger:error open [$LOGFILE]:[$!]\n";
    return;
  }
  if (!printf OUT "%4.4d/%2.2d/%2.2d %2.2d:%2.2d:%2.2d %s %s -> %s\n",
          $A+1900, $M+1, $J, $h, $m, $s, $idt, $HOSTNAME, $str) {
    warn "logger:error print [$LOGFILE]:[$!]\n";
    return;
  }
  if (!close(OUT)) {
    warn "logger:error close [$LOGFILE]:[$!]\n";
    return;
  }
}

したがって、このログ ファイルには同時書き込みがあります。 例外的に、STDERR に次のエラーがあります。

閉じたファイルハンドルに対する printf()

logger :error print [/my/path/logFile.LOG]:[Bad File Descriptor]

オープン時にエラーなし!

この問題を解決するにはどうすればよいですか?

4

1 に答える 1

3

OUTパッケージグローバルです。Log4perl などの実際のロギング システムへのアップグレードが問題外であると仮定すると、次のようなレキシカル ファイル ハンドルを使用できます$OUT

sub logger {
    $LOGFILE or return;
    my ($idt, $str) = @_ ;

    unless( defined($str) ) {
        $str = $idt ;
        $idt = '' ;
    }

    my ($s,$m,$h,$J,$M,$A) = localtime(time()) ;

    my $OUT;

    unless (open $OUT, '>>', $LOGFILE) {
        warn "logger:error open [$LOGFILE]:[$!]\n";
        return;
    }

    unless (printf $OUT 
        "%4.4d/%2.2d/%2.2d %2.2d:%2.2d:%2.2d %s %s -> %s\n",
        $A+1900, $M+1, $J, $h, $m, $s, $idt, $HOSTNAME, $str
    ) {
        warn "logger:error print [$LOGFILE]:[$!]\n";
        return;
    }

    unless (close $OUT) {
        warn "logger:error close [$LOGFILE]:[$!]\n";
        return;
    }

    return 1;
}
于 2012-05-07T00:53:52.080 に答える