-sub CLOSE {
- my $fh = delete($_[0]->{fh});
- my $ret = defined $fh ? close($fh) : '';
- my $pid = delete $_[0]->{pid};
- if (defined $pid) {
- waitpid($pid, 0);
- $ret = '' if $?;
+sub WRITE {
+ use bytes qw(length);
+ syswrite($_[0]->{fh}, $_[1], $_[2] // length($_[1]), $_[3] // 0);
+}
+
+sub PRINT {
+ my $self = shift;
+ print { $self->{fh} } @_;
+}
+
+sub FILENO { fileno($_[0]->{fh}) }
+
+sub _close ($;$) {
+ my ($self, $wait) = @_;
+ my ($fh, $pid) = delete(@$self{qw(fh pid)});
+ my $ret = defined($fh) ? close($fh) : '';
+ return $ret unless defined($pid) && $self->{ppid} == $$;
+ if ($wait) { # caller cares about the exit status:
+ # synchronous wait via defined(wantarray) on awaitpid:
+ defined(${$self->{pp_chld_err}}) or $wait = awaitpid($pid);
+ ($? = ${$self->{pp_chld_err}}) and $ret = '';
+ } else {
+ awaitpid($pid); # depends on $in_loop or not