FBB::Proc(3bobcat)
πΈ FBB::Proc(3bobcat) β running child processes π
ok bestie, welcome to FBB::Proc, a page from the 3bobcat manual, and honestly? she's that girl. this is the class that runs external programs for you from C++, and she does it with an extensive interface. let's get into it β¨
π NAME π
FBB::Proc β runs external programs. that's it, that's the job. iconic behavior fr fr.
β¨ SYNOPSIS β¨
#include <bobcat/proc>
Linking option: -lbobcat
like, don't forget that link flag, it's giving "mandatory" π
π DESCRIPTION π
okay so. FBB::Proc is an alternative to the FBB::Process class. she offers an extensive interface for calling external programs and/or scripts from a C++ program β the so-called child processes. the whole vibe is an easy-to-use, stream-based interface so you can talk to a child process's standard input, output and error streams like it's nothing. obsessed.
objects of the class Proc use standard process-executing functions, like the members of the execl(2) family or sh(1), to execute child processes. so a child process can literally be an executable program or a shell script. no cap.
the standard input, output and error streams of child processes may be accessed through their Proc parent objects. input that the child process expects can be inserted into Proc objects. standard output and standard error generated by the child process are inserted into β and further handled by β std::ostream objects, by default std::cout and std::cerr.
when you're using (output) redirection while executing child processes with theUSE_SHELLpath specification (peep below for the path andIOModespecs), you should normally specify theIGNORE_COUTIOMode(and possiblyIGNORE_CERRtoo). check the ENUMERATIONS section for what theIOModeenumeration actually means π«Ά
Proc objects can be reused over and over to run the same or different child processes. before the next child process starts, the Proc object makes sure its currently active child process is done. alternatively, a currently active child process ends if:
- the
Procobject goes out of scope, - the allotted execution time of the child process has passed,
- a new process is started using
Proc's assignment operator, or - its
stopmember is called.
otherwise, child processes just keep going until completion when you call finish, or β if the child process reads its standard input stream β when the eoi manipulator is inserted into the Proc object.
programs called as child processes may be specified when constructing a Proc object, or by using Proc's setCommand member. heads up bestie: Proc constructors (and the setCommand member) don't start child processes. to actually start them you must use the start members or the assignment operator. periodt.
child processes may receive info at their standard input streams through information inserted into Proc objects. in those cases, Proc objects have to inform their child processes that they've received all input. for this, the eoi manipulator can be inserted into Proc objects, or Proc's finish member can be called β¨
if information sent to the child isn't fully processed by the child process, then the operating system issues a Broken pipe message, indicating that information in a pipe was lost β which ends the program π. the Proc class's member pipeSignal can be used to suppress that Broken pipe message.
arguments passed to child processes may be surrounded by double or single quotes:
- arguments surrounded by double quotes have their double quotes removed, while interpreting any escape-sequences that may have been used within.
- arguments surrounded by single quotes have their single quotes removed, while accepting their content as-is.
- plus, unquoted escape-sequences may be specified: those escape sequences are evaluated and replaced by their intended characters (e.g.,
\100is converted to@).
a full command specification may also be surrounded by backtics (`-characters). these backtick characters are removed by the Proc object when the command starts. (` as punctuation, we love to see it π¦)
child processes may be allotted a limited amount of time (in seconds) to complete. by default no time limit is imposed upon child processes. if a time limit is specified, then the child process β if it's still running after the specified number of seconds β is ended by sending it a SIGTERM signal, followed by a SIGKILL signal (cf. signal(7)). yeah, she doesn't play. π
by default, the standard input, output and error streams of child processes are handled by their Proc parent processes: info inserted into the Proc object is forwarded to the child process's standard input stream, and info sent by the child process to its standard output and error streams is either forwarded to the corresponding streams of the parent process, or processed by streams configured by the Proc object.
multiple Proc processes can be combined using the pipe operator (i.e., the | operator). when used, the standard output stream of the left-hand side (lhs) Proc object becomes the standard input stream of the right-hand side (rhs) Proc object. since the Proc objects start their own child processes, this effectively boils down to the output of the lhs's child process being used as the input of the rhs's child process. the leftmost Proc object may also read its input (using the pipe operator) from an istream object, or from a file whose name (path) is specified as the most lhs argument of a pipe expression. likewise, the rightmost Proc object may pipe its standard output to an existing ostream object, or to a file whose name (path) is specified as the most rhs argument of a pipe expression. it's giving pipelines and honestly? slay π
Proc objects use Pipe objects (cf. pipe(3bobcat)) for communication with their child processes. to make sure those pipes are properly closed, you should use the members waitForChild, stop, or the eoi manipulator. once a Proc object ceases to exist, pipes to its child process are also closed.
π§ NAMESPACE π§
FBB
all constructors, members, operators and manipulators mentioned in this man-page are defined in the namespace FBB. iykyk π
π INHERITS FROM π
FBB::Fork(3bobcat)(private)std::ostream
π ENUMERATIONS π
the following enumerations are defined by the Proc class:
enum ProcType
the enum ProcType defines how a child proc is started or located. its values are specified at constructor-time or through the setProcType member. this enumeration defines the following symbolic constants:
NO_PATH: the program specified as child proc is started as specified, without searching the elements of thePATHenvironment variable.USE_PATH: the elements of thePATHenvironment variable are used when locating the program specified as child proc.USE_SHELL: the program specified as child proc is called using/bin/sh -c. when (output) redirection is used with the specified command, theIGNORE_COUTIOMode(and possibly also theIGNORE_CERRIOMode) should be specified.
enum IOMode
values of the enum IOMode are used to define which of the child proc's standard streams can be accessed through the Proc object. its symbolic constants may be combined using the bit_or operator. by default CIN | COUT | CERR is used (see below).
IOMode arguments may be combined using bit-or operators.
the following symbolic constants are available:
ALL: shortcut forCIN | COUT | CERR.CIN: information inserted into theProcobject is forwarded to its child proc. if this is not required thenCINshould not be specified.CERR: information written by the child process to its standard error stream is made available asProc's standard error stream. if this is not required thenCERRshould not be specified.COUT: information written by the child process to its standard output stream is made available asProc's standard output stream. if this is not required thenCERRshould not be specified.IGNORE_CERR: information written by the child proc to its standard error stream is ignored (i.e., not made available). anstd::invalid_argumentexception is thrown if this mode is specified in combination withCERR,MERGE_COUT_CERR, and/orREPLACE.IGNORE_COUT: information written by the child proc to its standard output stream is ignored. anstd::invalid_argumentexception is thrown if this mode is specified in combination withCOUT,MERGE_COUT_CERRand/orREPLACE.IGNORE_COUT_CERR: shortcut forIGNORE_CERR | IGNORE_COUT.MERGE_COUT_CERR: information written by the child process to its standard output and standard error streams is made available at theProcobject's standard output stream. anstd::invalid_argumentexception is thrown if this mode is specified in combination withCOUT,CERR,IGNORE_COUT,IGNORE_CERRorREPLACE.NONE: theProcobject does not insert information into the standard input streams of its child process, and information written by the child process to its standard output or error streams is not forwarded to theProcobject. instead, the child process processes its standard streams by itself. when this mode is specified in combination with otherIOModevalues it is silently ignored.REPLACE: when starting a child proc (see below at the memberstart) the current process (i.e., the program defining theProcobject) is replaced by the child process, inheriting the current process's standard input and output streams. if this mode is specified in combination with any otherIOMode(except forNONE, see below) anstd::invalid_argumentexception is thrown.
okay so those std::invalid_argument combos? not a vibe. don't do them. π
πΈ CONSTRUCTOR πΈ
note that child processes are not started automatically following the construction of Proc objects. a start member or the assignment operator (see below) is used to start child processes.
once a Proc object has been constructed, its parameters can be changed using set-member functions or start members.
explicit Proc(std::string const &command = "", IOMode mode = ALL, ProcType type = NO_PATH, size_t bufSize = 200, size_t timeLimit = 0, bool pipeSignal = true): the parameterbufSizedefines the size of thestreambufbuffers used by theProcobject. thetimeLimitspecifies the maximum execution time of a child process in seconds; whentimeLimit == 0no execution time limit is used. whenpipeSignal == true, incomplete processing of information sent to or read from the child process results in a Broken pipe exception, terminating the program. when specifyingfalsethe Broken pipe exception is suppressed, and the input and/or output streams do not have to be completely processed (see alsopipeSignal's description).
copy and move constructors (and assignment operators) are not available. she's exclusive like that π
bestie, that's not even all of it β more of this page is coming right up, don't go anywhere π¦
π OVERLOADED OPERATORS π
okay bestie, this is where the Proc girlies shine β the operators. buckle up π
Proc &operator<<(Type value)β this one insertsvalueright into the child's standard input stream. so like, the childprocreadsvaluefrom its own stdin, periodt. literally any type that can be inserted into anostreamcan be inserted into aProcobject. if the childprochas already terminated? nothing happens, it's giving ghosted π». manipulators likestd::endlare supported too, slay. β οΈ the behavior of this operator is undefined when IOModeCINhas not been specified β so don't do that, iykyk.Proc &operator+=(std::string const &)β this adds thestd::stringyou hand it to the currently defined command specification of theProcobject. and bestie, hear me: the memberoperator+=does not sneak a separating blank space between the currently stored command specification and the text you're appending. it merely adds its right-hand side string to the command stored so far. it does not affect a currently running child process either. no cap. πint operator=(std::string const &cmd)β this definescmdas the stored command in aProcobject, and thereupon startscmdas its child process. but first β before starting the child process β a possibly active child process is first stopped by callingstop. it returnsstop's return value. and immediately after callingstop, the new command (cmd) is started. if ending and restarting another command should be separate actions, then usefinishorstop, followed bysetCommand, followed by calling an appropriate overloaded version of the memberstart. β¨Return operator|(Proc &lhs, Proc &rhs)β the piping operator, she's iconic. information sent bylhsto its standard output is used as the standard input of therhs's child process. theReturnvalue isrhsif the expression is followed by another pipe-operator, or it isvoid.Return operator|(std::istream &in, Proc &proc)β more piping. information read frominis read byproc's child process. theReturnvalue isprocif the expression is followed by another pipe-operator, or it isvoid.Return operator|(std::string const &fname, Proc &proc)β piping again π¦. information in the file whose file (path) name isfnameis read byproc's child process. theReturnvalue isprocif the expression is followed by another pipe-operator, or it isvoid.void operator|(Proc &proc, std::ostream &out)β piping, the sequel π. information sent byproc's child process to its standard output stream is written toout.void operator|(Proc &proc, std::string &fname)β piping one last time. information sent byproc's child process to its standard output stream is written to the file whose file (path) name isfname.
the pipe (|) operator mimics the pipe-operator supported by most command-shell programs, and bestie, do not confuse it with the bit-or operator, that's a different vibe entirely π. the pipe operator allows constructions like
p1 | p2 | p3 // piping 3 Proc objects
cin | p1 | p2 | cout // p1 reads cin, p2 writes cout
inName | p1 | outName // inName: file name of the file
// read by p1, outName: file name
// of the file written by p1
when using the pipe operator, Proc objects reading input automatically specify their CIN modes, while Proc objects writing their standard output automatically specify their COUT modes. and following the pipe-expression, the IOMode specifications which were specified before the pipe-expression are restored. the way that works is lowkey so satisfying π«Ά
πΈ MEMBERS πΈ
bool active()β if the childprocis currently running,trueis returned, andfalseif not. simple as.void cerrMode(char const *lab) constβ the labellab, followed by a textual representation of the currently configuredIOMode, is inserted intostd::cerr.void cerrPipes(char const *lab) constβ the textProc, followed by theProc's id, followed by labellab, followed by the currently active read and write file descriptors of the pipes currently used by theProcobject, are inserted intostd::cerr. it's giving diagnostics πstd::string const &cmd() constβ the currently specified child-process starting command is returned.int exitStatus() constβ the last child-process's exit-status is returned. if a child process is currently running, or if no child process has yet been started,-1is returned.int finish()β waits until a currently active child process has ended, and returns its exit status. if the child process isn't currently running,-1is returned. bye bestie, see you when you're done πIOMode ioMode() constβ theIOModecurrently used by theProcobject is returned.std::string mode() constβ theIOModecurrently used by theProcobject is returned as a text-string.int pid() constβ the child process's process-id is returned. β οΈ the returned value is undefined if no child process has yet been started. if the child process has already completed, the last child process's id is returned.void pipeSignal(bool on)β when incompletely forwarding information to a child process or incompletely reading information from a child process, a Broken pipe may result, ending the currently running program. to avoid this,pipeSignal(false)can be called. to reactivate recognizing broken pipes,pipeSignal(true)can be called. after usingpipeSignal(false), failing insertions into aProcobject result in its membergoodreturningfalse, and its membersbadandfailreturningtrue. π¨size_t procIdx() constβ every constructedProcobject receives its own construction-order index. the firstProcobject constructed in a program gets index value0. main character energy, obviously πProcType procType() constβ theProcTypeused when starting child processes is returned.void setBufSize(size_t bufSize)β the stream buffer size in bytes used by streams communicating with child processes is set tobufSize. a zero byte buffer size is silently changed into one.void setCommand(std::string const &cmd)β the (initial part of a) child process command specification is set tocmd. after calling this, memberoperator+=can be used to append additional text to the command specification.void setIOMode(IOMode mode)β theIOModeused when calling child processes is set tomode. note that pipe-expressions may modify the mode ofProcobjects while the pipe-expression is executed. for details, see the end of theOVERLOADED OPERATORSsection β¨void setProcType(ProcType type)β theProcTypeused when starting child processes is set totype.void setTimeLimit(size_t timeLimit)β the execution time limit of child processes is set totimeLimit(in seconds). no time limit is used whentimeLimit0is specified. the time limit set bysetTimeLimitis used when starting the next child process. when callingsetTimeLimit, thenpipeSignal(timeLimit == 0)is automatically called. if that's not intended, then explicitly callpipeSignalafter callingsetTimeLimit. sneaky little side effect, highkey π³void start(size_t timeLimit, IOMode mode = ALL, ProcType type = NO_PATH, size_t bufSize = 200)β the currently specified command is started using the specifiedtimeLimit,IOMode,ProcTypeandbufSizearguments. thestartmembers do not alter the currently configured default values of their arguments.
if a child process is still active when start is called, it first calls stop to end the currently running child process.
void start(IOMode mode, ProcType type = NO_PATH, size_t bufSize = 200)β same as the previousstartmember, but using the currently configuredtimeLimitand requiring the specification of theIOModeto use.void start()β same as the firststartmember, but using the currently configuredtimeLimit,IOMode,ProcTypeandbufSizevalues. it just knows what you want πint stop()β a currently active child process is ended by callingFork::endChild(see alsofork(3bobcat)).void system(size_t timeLimit, IOMode mode = ALL, size_t bufSize = 200)β the currently stored command is executed as a command ofsh(1), using the specified process-arguments.void system(IOMode mode = ALL, size_t bufSize = 200)β same as the previoussystemcommand, but using the defaulttimeLimitspecification.size_t timeLimit() constβ the currently configured execution time limit ofProc's child process is returned. the return value zero indicates that no time limit is used.void useErr(std::ostream &out)β the standard error output produced by the child process is sent toout. if theProcobject had specifiedIGNORE_CERR, then thatIOModeis unset, and theCERRmode is set.void useErr(std::string const &fname)β same as the previous member, but the child's standard error output is written to the file (path)fname.void useMerge(std::ostream &out)β the standard output and standard error output produced by the child process is sent toout. if theProcobject had specifiedCERR,COUT,IGNORE_CERR, orIGNORE_COUT, then thoseIOModesare unset, and theMERGE_COUT_CERRmode is set. two streams, one vibe πvoid useMerge(std::string const &fname)β same as the previous member, but the child's standard output and standard error output is written to the file (path)fname.void useOut(std::ostream &out)β the standard output produced by the child process is sent toout. if theProcobject had specifiedIGNORE_COUT, then thatIOModeis unset, and theCOUTmode is set.void useOut(std::string const &fname)β same as the previous member, but the child's standard output is written to the file (path)fname.int waitForChild()β this member calls the identically named member from the classFBB::Fork, waiting for a child process to end. when callingfinishor using pipe-expressions,waitForChildis automatically called. no need to chase it down yourself, bestie π«Ά
π EXAMPLES π
okay bestie, every single one of these starts with the same lil preamble, no exceptions:
#include <iostream>
#include <bobcat/proc>
using namespace std;
using namespace FBB;
β¨ Example one β a child program that only produces output. Its child proc is literally just /bin/ls:
int main()
{
Proc proc("/bin/ls -Fla", Proc::COUT);
proc.start();
}
β¨ Example two β a child program that gets a limited amount of execution time. Lines you type at the keyboard get echoed to the standard output stream for at most 5 seconds:
int main()
{
Proc proc("/bin/cat", Proc::CIN | Proc::COUT);
proc.setTimeLimit(5);
proc.start();
while (true)
{
cout << "? ";
string line;
if (not getline(cin, line))
return 0;
proc << line << endl; // to /bin/cat
if (not proc.good())
{
cout << "child time limit exceeded\n";
break;
}
}
cout << "/bin/cat time limit of 5 seconds reached: child proc ended\n";
}
β¨ Example three β piping, the moment you've all been waiting for. Info sitting at the program's standard input gets piped to a second Proc object, and that one writes its standard output to the program's standard output stream:
int main()
{
Proc proc1{ "/bin/cat" };
Proc proc2{ "/bin/cat" };
cin | proc1 | proc2; // By default piping to cout. To do that
// explicitly use β... | proc2 | coutβ
}
(yeah, by default it pipes to cout. if you wanna say that out loud, go β... | proc2 | coutβ π
)
π FILES π
bobcat/procβ defines the class interface
π SEE ALSO π
bobcat(7), execle(3), fork(3bobcat), process(3bobcat), ostream(3fork), sh(1)
π BUGS π
(empty. truly nothing to report. the bugs section said nothing and honestly? iconic of it.)
π¦ BOBCAT PROJECT FILES π¦
- https://fbb-git.gitlab.io/bobcat/ β gitlab project page;
Debian Bobcat project files:
libbobcat6β debian package containing the shared library, changelog and copyright note;libbobcat-devβ debian package containing the static library, headers, manual pages, and developer info;
π BOBCAT π
Bobcat is an acronym of `Brokkenβs Own Base Classes And Templatesβ. π¦
πΈ COPYRIGHT πΈ
This is free software, distributed under the terms of the GNU General Public License (GPL).
π«Ά AUTHOR π«Ά
Frank B. Brokken (f.b.brokken@rug.nl).
k that's the whole page bestie, you're officially a FBB::Proc girlie now π
β¨ it's from libbobcat-dev_6.15.01, dated 2005-2026, and yeah β that footer is literally the cover of the book, periodt π go forth and fork responsibly π
π¦ where this page comes from
- ubuntu stonking: libbobcat-dev 6.15.01-1 Β· GPL-3.0-or-later WITH OpenSSL exception
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms