sub webPrint($ofh, @parts) { my $brokenpipe = 0; local $SIG{PIPE} = sub { $brokenpipe = 1;}; local $INPUT_RECORD_SEPARATOR = undef; binmode($ofh, ':bytes'); my $full; foreach my $npart (@parts) { if(!defined($npart)) { #print STDERR "Empty npart in Webprint!\n"; next; } if(is_utf8($npart)) { $full .= encode_utf8($npart); } else { $full .= $npart; } } my $shownlimitmessage = 0; my $timeoutthres = 20; # Need to be able to send at least one byte per 20 seconds # Output bandwidth-limited stuff, in as big chunks as possible if(!defined($full) || $full eq '') { return 1; } my $written = 0; my $timeout = time + $timeoutthres; $ERRNO = 0; my $needprintdone = 0; while(1) { eval { ## no critic (ErrorHandling::RequireCheckingReturnValueOfEval) $written = syswrite($ofh, $full); }; if($EVAL_ERROR) { print STDERR "Write error: $EVAL_ERROR\n"; return 0; } if(!defined($written)) { $written = 0; } last if($written == length($full)); #print STDERR "Sent $written bytes (", length($full) - $written, "remaining)\n"; if($!{EWOULDBLOCK} || $!{EAGAIN}) { ## no critic (Variables::ProhibitPunctuationVars) if(!$shownlimitmessage) { print STDERR "Rate limiting output\n"; $shownlimitmessage = 1; } $timeout = time + $timeoutthres; if(!$written) { sleep(0.01); } } elsif(0 && $brokenpipe) { print STDERR "webPrint write failure: SIGPIPE\n"; return 0; } elsif($ofh->error || $ERRNO ne '') { print STDERR "webPrint write failure: $ERRNO / ", $ofh->opened, " / ", $ofh->error, "\n"; return 0; } if($written) { $timeout = time + $timeoutthres; $full = substr($full, $written); $written = 0; next; } if($timeout < time) { print STDERR "***** webPrint TIMEOUT ****** $ERRNO\n"; return 0; } sleep(0.01); $needprintdone = 1; } if($needprintdone) { print STDERR "Webprint Done\n"; } return 1; }