Skip to content

Reopening STDOUT to in-memory scalar interferes with "-|" piping #21881

@jimav

Description

@jimav

If STDOUT is redirected to an in-memory scalar, then in a subsequent subprocess created with open(my $from_kid, "-|") STDOUT does not refer to the pipe, but to something with fileno==-1. Anything written to STDOUT in the child is lost.

The OS file descriptor 1 does seem to refer to the pipe: Output from an exec'd program gets through correctly.

#!/usr/bin/env perl
use strict; use warnings;

open my $orig_STDOUT, ">&", *STDOUT or die "dup STDOUT: $!";
my $buffer = "";

# Redirect STDOUT to a string
# --> COMMENT OUT THIS LINE AND THE PROBLEM DISAPPEARS
close STDOUT; open STDOUT, ">", \$buffer or die "redir to string failed; $!";

# Creatw piped subprocess
my $child_pid = open(my $from_kid, "-|") // die "Can't fork: $!";
if ($child_pid == 0) {
  # CHILD
  print STDOUT "Child: print to STDOUT *** THIS GETS LOST ***\n";
  STDOUT->flush();
  exec "date"; # output from external command works
  die "exec failed";
}
# PARENT
while (<$from_kid>) { print "GOT from kid: $_"; }

# Dump what was captured
close STDOUT;
open STDOUT, ">&", $orig_STDOUT or die "restore orig failed: $!";
print "Captured text:\n", $buffer, "<END>\n";
print "Done.\n";

perl 5.36.0 perl-V_output.txt

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions