- public_inbox_fork_exec($in, $out, $err, $f, $cmd, \@env);
+ my $pid = public_inbox_fork_exec($in, $out, $err, $f, $cmd, \@env);
+ $pid < 0 ? undef : $pid;
+}
+
+sub popen_rd {
+ my ($cmd, $env, $opts) = @_;
+ pipe(my ($r, $w)) or die "pipe: $!\n";
+ $opts ||= {};
+ my $blocking = $opts->{Blocking};
+ IO::Handle::blocking($r, $blocking) if defined $blocking;
+ $opts->{1} = fileno($w);
+ my $pid = spawn($cmd, $env, $opts);
+ return unless defined $pid;
+ return ($r, $pid) if wantarray;
+ my $ret = gensym;
+ tie *$ret, 'PublicInbox::ProcessPipe', $pid, $r;
+ $ret;