includefile(include/header)

COMMENT(manpage, section, releasedate, archive, short name)
manpage(FBB::Proc)(3bobcat)(_CurYrs_)(libbobcat-dev__CurVers_)
                    (Running Child Processes)

manpagename(FBB::Proc)(Runs external programs)

manpagesynopsis()
    bf(#include <bobcat/proc>)nl()
    Linking option: tt(-lbobcat)

manpagedescription()
    The bf(FBB::Proc) offers an alternative to the bf(FBB::Process)
class. bf(FBB::Proc) offers an extensive interface to calling external
programs and/or scripts from a bf(C++) program (so-called
em(child-processes)). The class offers an easy to use, stream-based interface
to communicate with the standard input, output and error streams of child
processes.

    Objects of the tt(class Proc) use standard process-executing functions,
like members of the bf(execl)(2) family or bf(sh)(1) to execute child
processes. Thus, child processes can be executable programs or
em(shell-scripts).

The standard input, output and error streams of child processes may be accessed
through their tt(Proc) parent objects. Input expected by child processes can
be inserted into tt(Proc) objects. standard output and standard error
generated by child processes are inserted into and further handled by
tt(std::ostream) objects, by default tt(std::cout) and tt(std::cerr).

When using (output) redirection when executing child processes using the
tt(USE_SHELL) path specification (see below for the path and IOMode
specifications), the tt(IGNORE_COUT IOMode) (and possibly tt(IGNORE_CERR))
should normally be specified (cf. section bf(ENUMERATIONS) for a description
of the tt(IOMode) enumeration).

tt(Proc) objects may repeatedly be used to execute the same or different child
processes. Before the next child process is started, the tt(Proc) object
ensures that its currently active child process ends. Alternatively, a
currently active child process ends if the tt(Proc) object goes out of scope,
if the allotted execution time of the child process has passed, if a new
process is started using tt(Proc's) assignment operator, or if its tt(stop)
member is called. Otherwise child processes continue until completion when
calling tt(finish) or, if the child process reads its standard input stream,
when the tt(eoi) manipulator is inserted into the tt(Proc) object.

Programs called as child processes may be specified when constructing a
tt(Proc) object or by using tt(Proc's setCommand) member. tt(Proc)
constructors (or tt(Proc's setCommand)-member) don't start child
processes. To start child processes the tt(start) members or the assignment
operator must be used.

Child processes may receive information at their standard input streams through
information inserted into tt(Proc) objects. In those cases tt(Proc) objects
must inform their child processes that they have received all input. For this
the tt(eoi) manipulator can be inserted into tt(Proc) objects, or tt(Proc's
finish) member can be called.

If information sent to the child is not fully be processedd by the child
process then the operating system issues a tt(Broken pipe) message, indicating
that information in a pipe was lost, ending the program. The tt(Proc) class's
member tt(pipeSignal) can be used to suppress the tt(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. In addition unquoted
escape-sequences may be specified: those escape sequences are evaluated and
replaced by their intended characters (e.g., tt(\100) is converted to tt(@)).

A full command specification may also be surrounded by backtics
(tt(`)-characters). These backtick characters are removed by the tt(Proc)
object when the command starts.

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 still running after the
specified number of seconds, is ended by sending it a tt(SIGTERM) signal,
followed by a tt(SIGKILL) signal (cf. bf(signal)(7)).

By default the standard input, output and error streams of child processes are
handled by their tt(Proc) parent processes: information inserted into
the tt(Proc) object is forwarded to the child process's standard input
stream, information sent by the child process to its standard output and error
streams are either forwarded to the corresponding streams of the parent
process, or they can be processed by streams, configured by the tt(Proc)
object. 

Multiple tt(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)
tt(Proc) object is used as the standard input stream of the right-hand side
(rhs) tt(Proc) object. Since the tt(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
tt(Proc) object may also read its input (using the pipe operator) from an
tt(istream) object or from a file whose name (path) is specified as the most
lhs argument of a pipe expression. Likewise, the rightmost tt(Proc) object may
pipe its standard output to an existing tt(ostream) object or to a file whose
name (path) is specified as the most rhs argument of a pipe expression.

tt(Proc) objects use tt(Pipe) objects (cf. bf(pipe)(3bobcat)) for
communication with their child processes. To ensure that these pipes are
properly closed the members tt(waitForChild, stop) or the tt(eoi) manipulator
should be used. Once a tt(Proc) object ceases to exist pipes to its child
process are also closed.

includefile(include/namespace)

manpagesection(INHERITS FROM)
    bf(FBB::Fork)(3bobcat) (private), nl()
    bf(std::ostream)

manpagesection(ENUMERATIONS)

    The following enumerations are defined by the tt(Proc) class:

    bf(enum ProcType):nl()

    The bf(enum ProcType) defines how a child proc is started or
located. Its values are specified at constructor-time or through the
tt(setProcType) member. This enumeration defines the following symbolic
constants:
        itemization(
        itb(NO_PATH)
           The program specified as child proc is started as specified,
            without searching the elements of the tt(PATH) environment
            variable.
        itb(USE_PATH)
           The elements of the tt(PATH) environment variable are used when
            locating the program specified as child proc.
        itb(USE_SHELL)
           The program specified as child proc is called using tt(/bin/sh
            -c). When (output) redirection is used with the specified command
            the tt(IGNORE_COUT IOMode) (and possibly also the tt(IGNORE_CERR
            IOMode)) should be specified.
        )

    bf(enum IOMode):nl()

       Values of the tt(enum IOMode) are used to define which of the child
proc's standard streams can be accessed through the tt(Proc) object. Its
symbolic constants may be combined using the tt(bit_or) operator. By default
tt(CIN | COUT | CERR) is used (see below).

    tt(IOMode) arguments may be combined using bit-or operators.

    The following symbolic constants are available:
        itemization(
        itb(ALL)
           Shortcut for bf(CIN | COUT | CERR).
        itb(CIN)
           Information inserted into the tt(Proc) object is forwarded to
            its child proc.  If this is not required then tt(CIN) should
            not be specified.
        itb(CERR)
           Information written by the child process to its standard error
            stream is made available as tt(Proc's) standard error stream.  If
            this is not required then tt(CERR) should not be specified.
        itb(COUT)
           Information written by the child process to its standard output
            stream is made available as tt(Proc's) standard output stream.  If
            this is not required then tt(CERR) should not be specified.
        itb(IGNORE_CERR)
           Information written by the child proc to its standard error stream
            is ignored (i.e., not made available). An
            tt(std::invalid_argument) exception is thrown if this mode is
            specified in combination with bf(CERR, MERGE_COUT_CERR,) and/or
            bf(REPLACE).
        itb(IGNORE_COUT)
           Information written by the child proc to its standard output stream
            is ignored. An tt(std::invalid_argument) exception is thrown if
            this mode is specified in combination with bf(COUT,
            MERGE_COUT_CERR) and/or bf(REPLACE).
        itb(IGNORE_COUT_CERR)
           Shortcut for tt(IGNORE_CERR | IGNORE_COUT).
        itb(MERGE_COUT_CERR)
           Information written by the child process to its standard output and
            standard error streams is made available at the tt(Proc) object's
            standard output stream.  An tt(std::invalid_argument) exception is
            thrown if this mode is specified in combination with bf(COUT,
            CERR, IGNORE_COUT, IGNORE_CERR) or tt(REPLACE).
        itb(NONE)
           The tt(Proc) object 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 the tt(Proc) object. Instead, the child process
            processes its standard streams by itself. When this mode is
            specified in combination with other tt(IOMode) values it is
            silently ignored.
        itb(REPLACE)
           When starting a child proc (see below at the member tt(start))
            the current process (i.e., the program defining the tt(Proc)
            object) 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 other tt(IOMode) (except for
            tt(NONE), see below) an tt(std::invalid_argument) exception is
            thrown.
        )

manpagesection(CONSTRUCTOR)

    Note that child processes are em(not) started automatically following the
construction of t(Proc) objects. A tt(start) member or the assignment operator
(see below) is used to start child processes.

    Once a tt(Proc) object has been constructed its parameters can be changed
using tt(set)-member functions or tt(start) members.

    itemization(
    itb(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 parameter tt(bufSize) defines the size of the tt(streambuf) buffers
        used by the tt(Proc) object. The tt(timeLimit) specifies the maximum
        execution time of a child process in seconds; when tt(timeLimit == 0)
        no execution time limit is used. When tt(pipeSignal == true)
        incomplete processing of information sent to or read from the child
        process results in a tt(Broken pipe) exception, terminating the
        program. When specifying tt(false) the tt(Broken pipe) exception is
        suppressed, and the input and/or output streams do not have to be
        completely processed (see also tt(pipeSignal's) description).
    )

    Copy and move constructors (and assignment operators) are not available.

manpagesection(OVERLOADED OPERATORS)

    itemization(
    itb(Proc &operator<<(Type value))
       This operator inserts tt(value) into the child's standard input
        stream. I.e., the child proc reads tt(value) from its standard
        input. A value of any type that can be inserted into an tt(ostream)
        can be inserted into a tt(Proc) object. Nothing happens if the member
        is used when the child proc has terminated. Manipulators like
        tt(std::endl) are also supported.  The behavior of this operator is
        undefined when tt(IOMode CIN) has not been specified.

    itb(Proc &operator+=(std::string const &))
      This operator adds the provided tt(std::string) object to the currently
        defined command specification of a tt(Proc) object. The member
        tt(operator+=) does not add a separating blank space between the
        currently stored command specification and the text to append.  It
        merely adds its right-hand side string to the command stored so
        far. It does not affect a currently running child process.

    itb(int operator=(std::string const &cmd))
      The tt(operator=) member defines tt(cmd) as the stored command in a
        tt(Proc) object, and thereupon starts `tt(cmd)' as its child process.

       Before starting the child process a possibly active child process is
        first stopped by calling tt(stop). It returns tt(stop)'s return
        value. Immediately after calling tt(stop) the new command (tt(cmd)) is
        started. If ending and restarting another command should be separate
        actions then use tt(finish) or tt(stop) followed by tt(setCommand),
        followed by calling an appropriate overloaded version of the member
        tt(start).

    itb(Return operator|(Proc &lhs, Proc &rhs))
       This operator implements em(piping). Information sent by tt(lhs) to its
        standard output is used as the standard input of the tt(rhs)'s child
        process. The tt(Return) value is tt(rhs) if the expression is followed
        by another pipe-operator or it is tt(void).

    itb(Return operator|(std::istream &in, Proc &proc))
       This operator implements em(piping). Information read from tt(in) is
        read by tt(proc's) child process. The tt(Return) value is tt(proc) if
        the expression is followed by another pipe-operator or it is tt(void).

    itb(Return operator|(std::string const &fname, Proc &proc))
       This operator implements em(piping). information in the file whose file
        (path) name is tt(fname) is read by tt(proc's) child process. The
        tt(Return) value is tt(proc) if the expression is followed by another
        pipe-operator or it is tt(void).

    itb(void operator|(Proc &proc, std::ostream &out))
       This operator implements em(piping). Information sent by tt(proc's)
        child process to its standard output stream is written to tt(out).

    itb(void operator|(Proc &proc, std::string &fname)) This operator
        implements em(piping). Information sent by tt(proc's) child process to
        its standard output stream is written to the file whose file (path)
        name is tt(fname).)

    The pipe (|) operator mimics the pipe-operator supported by most
command-shell programs and should not be confused with the tt(bit-or)
operator. The pipe operator allows constructions like
        verb(
    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 tt(Proc) objects reading input automatically
specify their tt(CIN) modes, while tt(Proc) objects writing their standard
output automatically specify their tt(COUT) modes. Following the
pipe-expression the tt(IOMode) specifications which were specified before the
pipe-expression are restored.

manpagesection(MEMBERS)

    itemization(
    itb(bool active())
       If the child proc is currently running tt(true) is returned and and
        tt(false) if not.

    itb(void cerrMode(char const *lab) const)
       The label tt(lab), followed by the a textual representation of the
        currently configured tt(IOMode) is inserted into tt(std::cerr).

    itb(void cerrPipes(char const *lab) const)
       The text tt(Proc), followed by the tt(Proc's) id, followed by label
        tt(lab), followed by the currently active read and write file
        descriptors of the pipes currently used by the tt(Proc) object are
        inserted into tt(std::cerr).

    itb(std::string const &cmd() const)
       The currently specified child-process starting command is returned.

    itb(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 -1 is
        returned. 

    itb(int finish())
       Waits until a currently active child process has ended and returns its
        exit status. If the child process isn't currently running -1 is
        returned.

    itb(IOMode ioMode() const)
       The tt(IOMode) currently used by the tt(Proc) object is returned. 

    itb(std::string mode() const)
       The tt(IOMode) currently used by the tt(Proc) object is returned as a
        text-string. 

    itb(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. 

    itb(void pipeSignal(bool on))
       When incompletely forwarding information to a child process or
        incompletely reading information from a child process a tt(Broken
        pipe) may result, ending the currently running program. To avoid this,
        tt(pipeSignal(false)) can be called. To reactivate recognizing broken
        pipes tt(pipeSignal(true)) can be called. After using
        tt(pipeSignal(false)) failing insertions into a tt(Proc) object result
        in its member tt(good) returning tt(false), and its members tt(bad)
        and tt(fail) returning tt(true).

    itb(size_t procIdx() const)
       Every constructed tt(Proc) object receives its own construction-order
        index. The first tt(Proc) object constructed in a program gets index
        value 0.

    itb(ProcType procType() const) 
       The tt(ProcType) used when starting child processes is returned.

    itb(void setBufSize(size_t bufSize))
       The stream buffer size in bytes used by streams communicating with
        child processes is set to tt(bufSize). A zero byte buffer size is
        silently changed into one.

    itb(void setCommand(std::string const &cmd))
       The (initial part of a) child process command specification is set to
        tt(cmd). After calling this member tt(operator+=) can be used to
        append additional text to the command specification. 

    itb(void setIOMode(IOMode mode))
       The tt(IOMode) used when calling child processes is set to tt(mode). 
        Note that pipe-expressions may modify the tt(mode) of tt(Proc) objects
        while the pipe-expression is executed. For details see the end of the
        bf(OVERLOADED OPERATORS) section.

    itb(void setProcType(ProcType type)) 
       The tt(ProcType) used when starting child processes is set to tt(type).

    itb(void setTimeLimit(size_t timeLimit)) The execution time limit of child
        processes is set to tt(timeLimit) (in seconds). No time limit is used
        when tt(timeLimit 0) is specified. The time limit set by
        tt(setTimeLimit) is used when starting the next child process. When
        calling tt(setTimeLimit) then tt(pipeSignal(timeLimit == 0)) is
        automatically called. If that's not intended, then explicitly call
        tt(pipeSignal) after calling tt(setTimeLimit).

     itb(void start(size_t timeLimit, IOMode mode = ALL,
                   ProcType type = NO_PATH, size_t bufSize = 200))
       The currently specified command is started using the specified
        tt(timeLimit, IOMode, ProcType) and tt(bufSize) arguments. The
        tt(start) members do not alter the currently configured default values
        of their arguments.

       If a child process is still active when tt(start) is called it first
        calls tt(stop) to end the currently running child process

     itb(void start(IOMode mode, ProcType type = NO_PATH, 
                    size_t bufSize = 200))
       Same as the previous tt(start) member, but using the currently
        configured tt(timeLimit) and requiring the specification of the
        tt(IOMode) to use.

    itb(void start())
       Same as the first tt(start) member, but using the currently configured
        tt(timeLimit, IOMode, ProcType) and tt(bufSize) values.

    itb(int stop())
       A currently active child process is ended by calling
        tt(Fork::endChild) (see also bf(fork)(3bobcat)).

    itb(void system(size_t timeLimit, IOMode mode = ALL, 
                    size_t bufSize = 200))
       The currently stored command is executed as a command of
        bf(sh)(1), using the specified process-arguments.

    itb(void system(IOMode mode = ALL, size_t bufSize = 200))
       Same as the previous tt(system) command, but using the default
        tt(timeLimit) specification.

    itb(size_t timeLimit() const)
       The currently configured execution time limit of tt(Proc's) child
        process is returned. The return value zero indicates that no time
        limit is used.

    itb(void useErr(std::ostream &out))
       The standard error output produced by the child process is sent to
        tt(out). If the tt(Proc) object had specified tt(IGNORE_CERR) then
        that tt(IOMode) is unset, and the tt(CERR) mode is set.

    itb(void useErr(std::string const &fname))
       Same as the previous member, but the child's standard error output is
        written to the file (path) tt(fname).

    itb(void useMerge(std::ostream &out))
       The standard output and standard error output produced by the child
        process is sent to tt(out). If the tt(Proc) object had specified
        tt(CERR, COUT, IGNORE_CERR), or tt(IGNORE_COUT) then those tt(IOModes)
        are unset, and the tt(MERGE_COUT_CERR) mode is set.

    itb(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) tt(fname).

    itb(void useOut(std::ostream &out))
       The standard output produced by the child process is sent to
        tt(out). If the tt(Proc) object had specified tt(IGNORE_COUT) then
        that tt(IOMode) is unset, and the tt(COUT) mode is set.

    itb(void useOut(std::string const &fname))
       Same as the previous member, but the child's standard output is written
        to the file (path) tt(fname).

    itb(int waitForChild())
       This member calls the identically named member from the class
        tt(FBB::Fork), waiting for a child process to end. When calling
        tt(finish) or using pipe-expressions tt(waitForChild) is automatically
        called.
    )

manpagesection(EXAMPLES)

    All examples should start with:
        verb(
    #include <iostream>
    #include <bobcat/proc>
    
    using namespace std;
    using namespace FBB;
        )

    The first example illustrates how a program only producing output can be
called. Its child proc simply is tt(/bin/ls):
        verbinsert(//CODE ../../proc/driver/ls.cc)

    The next example illustrates a child program that's given a limited amount
of execution time: lines entered at the keyboard are echoed to the standard
output stream for at most 5 seconds:
        verbinsert(//CODE ../../proc/driver/limit.cc)

    Piping is illustrated next: information at the program's standard input is
piped to a second tt(Proc) object, writing its standard output to the
program's standard output stream:
        verbinsert(//CODE ../../proc/driver/pipe.cc)

manpagefiles()
    em(bobcat/proc) - defines the class interface

manpageseealso()
    bf(bobcat)(7), bf(execle)(3), bf(fork)(3bobcat), bf(process)(3bobcat),
    bf(ostream)(3fork), bf(sh)(1)

manpagebugs()

includefile(include/trailer)
