in reply to question on getting SIGPIPE in close

Windows does not actually have signals. There is no SIGPIPE on Windows, so Perl is emulating it somehow. My guess is that close attempts to flush buffers, which are empty at that point in your program, so flushing them is a no-op on *nix, (only an actual write triggers SIGPIPE — flushing an empty buffer does not count) but Perl emulates SIGPIPE on Windows by asking the OS if the pipe is still connected. It is not, so "SIGPIPE" is raised.

Replies are listed 'Best First'.
Re^2: question on getting SIGPIPE in close
by perl-diddler (Chaplain) on Apr 30, 2020 at 19:50 UTC
    Sounds good, but so far, not sure how to avoid the message since it isn't in my code.

    I.e. it appears perl is checking the value of close and putting out the error whether I want it or not. Trying to stop the error with a 'no warnings' just before the final close doesn't silence the message. Only by disabling STDERR and redirecting to to /dev/null (cygwin) then restoring it do I effectively silence the message.

    While I don't disagree with the idea of checking 'close' for errors (and usually do so). It would be nice to be able to tell perl not to warn me about problems there.

      Does {local $SIG{PIPE} = sub {}; close($pipe)} work? My guess is that perl is checking the status of the pipe and emulating SIGPIPE when you close it.

        Does it work 'where'? I had it bracketing the write call and added bracketing for the close statement:
        sub close_child_io () { Debug "SigCHLD: close iopair[1]"; local * pipe_catch = sub ($) { Debug "Child already closed"; $iopair[1] = $iopair[0] = undef; }; my $tmp = $PathTree::iopair[1]; $PathTree::iopair[1] = undef; $SIG{PIPE}=\&pipe_catch; close($tmp); $SIG{PIPE}='DEFAULT'; };
        Only the "using-TNT-to-kill-a-fly" idea of redirecting STDERR to /dev/null before every write through perl seems to shut it up:
        |2588 local * write_child = sub ($) { |2589 my $out=$_[0]; |2590 return unless $iopair[1] and ref $iopair[1] and -w $iopair +[1]; |2591 |2592 local * pipe_catch = sub ($) { Debug "Child closed"; |2593 $iopair[1] = $iopair[0] = undef; }; |2594 |2595 $SIG{PIPE}=\&pipe_catch; |2596 no warnings; |2597 open (OLDERR, ">&", \*STDERR) or die "Can't dup STDERR: $! +"; |2598 open (STDERR, ">", "/dev/null") or die "Can't redirect STD +ERR to /dev/null: $!"; |2599 select STDERR; $|=1; |2600 P $iopair[1], $out."\n" ; |2601 open(STDERR, ">&OLDERR") or die "Can't restore stderr: $!" +; |2602 $SIG{PIPE}='DEFAULT'; |2603 };