1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
|
#include "process.ih"
// See ../README.process-pipe for an explanation of the inner workings of
// operator|
namespace FBB
{
Process &operator|(Process &lhs, Process &rhs)
{
// make sure output is available
if (not (lhs.d_mode & Process::MERGE_COUT_CERR))
{
lhs.d_mode |= Process::COUT;
lhs.d_setMode |= Process::COUT;
}
// all but the first process has IN_PIPE set
if
(
(lhs.d_setMode & Process::CIN)
&&
not (lhs.d_setMode & Process::IN_PIPE)
)
lhs.d_setMode |= Process::CLOSE_ON_EXEC;
// This is the output end of the pipe
lhs.d_setMode |= Process::PIPES_OK | Process::OUT_PIPE;
rhs.d_setMode |= Process::PIPES_OK;
lhs.start(); // forking() does the real work
#ifdef BOBCAT_DIY_CLOEXEC_
rhs.d_closedByChild = lhs.d_closedByChild; // children close the initial
// writing ends of the pipes
// to the 1st process
#endif
rhs.d_oChildInPipe.swap(lhs.d_iChildOutPipe);
// copy the input fm the lhs's child to the rhs's
// output. lhs.iChildOutPipe only has an open
// read-pipe and will be available to the rhs's
// child process to read via its stdin, thus
// connecting lhs's output to the rhs's input
if (lhs.d_oChildIn.rdbuf() != 0)
{
lhs.d_oChildIn.rdbuf(0);
rhs.d_oChildInbuf.reset(lhs.d_oChildInbuf.fd(), 200);
rhs.d_oChildIn.rdbuf(&rhs.d_oChildInbuf);
}
// this is the input end of the pipe
rhs.d_setMode |= Process::CIN | Process::IN_PIPE;
rhs.d_mode |= Process::CIN;
return rhs; // to start do, e.g., (p1|p2).start()
}
}
|