---
name: "fork"
section: "3bobcat"
platform: "linux"
package: "libbobcat-dev"
version: "6.07.01-2"
release: "Debian 13 (Trixie)"
platforms: ["linux"]
url: "https://new.carta.tech/fork/3bobcat"
---

# fork(3bobcat)

Implements fork(2) using the Template Design Pattern

## NAME

FBB::Fork - Implements [**fork**(2)](/fork/2.md) using the Template Design Pattern

## SYNOPSIS

**#include \<bobcat/fork\>**\
 Linking option: *-lbobcat*

## DESCRIPTION

**FBB::Fork** objects may be used to implement the [**fork**(2)](/fork/2.md) call as part of the Template Algorithm Design Pattern. The class was designed as a virtual base class for classes implementing the essential parts of the forking process. The class is a virtual base class. Derived classes *must* implement the members *childProcess* and *parentProcess* as part of the \`Template Method Design Pattern’ (see Gamma *et al.*, 1995).

Terminating child processes send *SIGCHLD* signals to their parents. The **C** library offers the following *macros* to analyze the *status* values received by the parent process using a [**wait**(2)](/wait/2.md) or [**waitpid**(2)](/waitpid/2.md) system call:

- o

  **int WIFEXITED(int status)**:\
   This macro returns a nonzero value if the child process terminated normally with \`exit’ or \`\_exit’.

- o

  **int WEXITSTATUS(int status)**:\
   If \`WIFEXITED’ is true of \`*status*’, this macro returns the low-order 8 bits of the exit status value from the child process.

- o

  **int WIFSIGNALED(int status)**:\
   This macro returns a nonzero value if the child process terminated because it received a signal that was not handled.

- o

  **int WTERMSIG(int status)**:\
   If \`WIFSIGNALED’ is true of \`*status*’, this macro returns the signal number of the signal that terminated the child process.

- o

  **int WCOREDUMP(int status)**:\
   This macro returns a nonzero value if the child process terminated and produced a core dump.

- o

  **int WIFSTOPPED(int status)**:\
   This macro returns a nonzero value if the child process is stopped.

- o

  **int WSTOPSIG(int status)**:\
   If \`WIFSTOPPED’ is true of \`*status*’, this macro returns the signal number of the signal that caused the child process to stop.

## NAMESPACE

**FBB**\
 All constructors, members, operators and manipulators, mentioned in this man-page, are defined in the namespace **FBB**.

## INHERITS FROM

\-

## CONSTRUCTORS

Only the default constructor is available.

## DESTRUCTOR

- o

  **virtual ~Fork()**:\
   Derived classes may define their own destructor, which is called when the *Fork* destructor is activated.

## MEMBER FUNCTIONS

- o

  **void fork()**:\
   Performs the actual forking. It is implemented in such a way that the corresponding parent- and child- processes are activated from virtual members of **Fork**. If the forking operation fails, an *FBB::Exception* exception is thrown.

## PROTECTED MEMBER FUNCTIONS

- o

  **int endChild() const**:\
   This member may be called by *parentProcess* to end the child process. To end the child process a *SIGTERM* is sent to the child process, followed by a *SIGKILL* (cf. [**signal**(7)](/signal/7.md)). If the child process has already ended then the child process’s exit value is returned, otherwise the child process’s end is forced (by calling *kill*) and -2 is returned. This member also calls *waitForChild* (see below).

-

  - o

  **pid\_t pid() const**:\
   Returns the child’s process id in the parent’s code (i.e., in the **parent-**members below), and 0 in the child’s code (i.e., in the **child-**members below). The *pid* member returns -1 when called *before* the member *fork* has been called.

-

  - o

  **void prepareDaemon() const**:\
   Prepares for a daemon childprocess. This function may (should) be called from *childProcess* to ensure that the child process changes its current working directory to the root (/) directory, thus freeing up mount points; that the child process starts a new session/process group to allow the parent (group leader) to kill all its processes without terminating the daemon; and makes sure that the child process closes and reopens the standard streams by associating them with */dev/null* to prevent ghost input and output actions from interfering with the daemon’s actions. An *FBB::Exception* is thrown if changing directory to the root directory fails.

-

  - o

  **void prepareDaemon(std::string const &out, std::string const &err,** **mode\_t mode = 0600) const**:\
   Prepares for a daemon childprocess like the previous member function, but allows redirection of the standard output (*out*) and standard error (*err*) streams to files. Specify empty strings to redirect these streams to */dev/null*. With non-empty strings the specified files are opened in append-mode (and created if not yet existing), by default using mode 0600 (read/write mode for the user only). An *FBB::Exception* is thrown if changing directory to the root directory or if using the specified **s** fails.

-

  - o

  **int waitForChild() const**:\
   This member may be called by *parentProcess* to wait for the completion of the child-process. The return value (exit-code) of the child process is returned as a value between 0 and 255. If the child process terminates before the completion of the parent process, then *waitForChild* should be called to prevent *zombies* from occurring. Alternatively, the parent process may terminate (e.g., using [**exit**(2)](/exit/2.md)) while the child process is still alive. This is the normal way to create a *daemon* process.

## PRIVATE (VIRTUAL) MEMBER FUNCTIONS

- o

  **virtual void childProcess() = 0**:\
   This member *must* be implemented by derived classes. It defines the actions that are performed by the child process, following the [**fork**(2)](/fork/2.md) system call. Just before *childProcess* is called, *childRedirections* (see below) has been executed. The *childProcess()* function should terminate the child process. A good way to do this is to throw an exception which is caught by *main()*’s function try block. Terminating a process using [**exit**(2)](/exit/2.md) is deprecated in **C++**.

-

  - o

  **virtual void childRedirections()**:\
   This function *may* be redefined in derived classes to set up the redirections that are necessary to communicate with the parent process. See also the classes [**redirector**(3bobcat)](/redirector/3bobcat.md) and [**pipe**(3bobcat)](/pipe/3bobcat.md). By default, *childRedirections* does nothing.

-

  - o

  **virtual void parentProcess() = 0**:\
   This member *must* be implemented by derived classes. It defines the actions that are performed by the parent process, following the [**fork**(2)](/fork/2.md) system call. Just before *parentProcess* is called, *parentRedirections* (see below) has been executed.

-

  When deriving classes from *Fork* their *parentProcess* implementation preferably handles all actions to perform by the parent process. If the child process remains active when the parent process decides that the program has performed its duties (e.g., the child process is replaced by a program started by an *exec..* function, continuously producing output, interpreted by the parent process) then the parent process can call *endChild* to end the child process before ending the *parentProcess* function.

-

  - o

  **virtual void parentRedirections()**:\
   This function *may* be redefined in derived classes to set up the redirections that are necessary to communicate with, e.g., the parent. See, e.g., the classes [**redirector**(3bobcat)](/redirector/3bobcat.md) and [**pipe**(3bobcat)](/pipe/3bobcat.md). By default, *parentRedirections* does nothing.

## EXAMPLES

```
#include <iostream>
#include <unistd.h>
#include <bobcat/fork>
using namespace std;
using namespace FBB;
class Background: public Fork
{
    public:
        void childProcess()     override;
        void parentProcess()    override;
};
void Background::childProcess()
{
    for (int idx = 0; idx < 3; ++idx)
    {
        cout << "Hello world # " << idx << endl;
        sleep(1);
    }
    throw 0;    // caught in main()
}
void Background::parentProcess()
{
    cout << "Waiting for the child process to end...\n"
            "The child returns value " << waitForChild() << endl;
}
int main()
try
{
    Background bg;
    bg.fork();
    cout << "This is from the parent\n";
}
catch(int x)
{
    cout << "The child terminates with: " << x << endl;
    return x;
}
```

Here’s a more extensive example:

```
#include <iostream>
#include <string>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <bobcat/pipe>
#include <bobcat/ofdstream>
#include <bobcat/ifdstream>
#include <bobcat/process>
#include <bobcat/fork>
class ChildIO: public FBB::Fork
{
    FBB::Pipe childInput;   // child reads this
    FBB::Pipe childOutput;   // child writes this
    public:
        void childRedirections()    override;
        void childProcess()         override;
        void parentProcess()        override;
};
using namespace std;
using namespace FBB;
void ChildIO::childRedirections()
{
    childInput.readFrom(Redirector::STDIN);
    childOutput.writtenBy(Redirector::STDOUT);
}
void ChildIO::childProcess()
{
        // The /bin/cat program replaces the
        // child process started by Fork::fork()
    Process process(Process::DIRECT, "/bin/cat");
    process.start();
    // this point is never reached
}
void ChildIO::parentProcess()
{
        // Set up the parent’s sides of the pipes
    IFdStream fromChild(childOutput.readOnly());
    OFdStream toChild(childInput.writeOnly());
        // write lines to the child, read its output
    string line;
    while (true)
    {
        cout << "? ";
        line.clear();
        getline(cin, line);
        if (line.empty())
        {
            kill(pid(), SIGTERM);
            break;
        }
        toChild << line << endl;
        getline(fromChild, line);
        cout << "Got: " << line << endl;
    }
    cout << "The child returns value " << waitForChild() << endl;
}
int main()
try
{
    ChildIO io;
    io.fork();
    return 0;
}
catch(exception const &exc)
{
    cerr << "Exception: " << exc.what() << endl;
}
catch(int x)
{
    cout << "The child terminates with: " << x << endl;
    return x;
}
```

## FILES

*bobcat/fork* - defines the class interface

## SEE ALSO

[**bobcat**(7)](/bobcat/7.md), [**cerrextractor**(3bobcat)](/cerrextractor/3bobcat.md), [**cininserter**(3bobcat)](/cininserter/3bobcat.md), [**coutextractor**(3bobcat)](/coutextractor/3bobcat.md), [**exec**(3)](/exec/3.md), [**exec**(3bobcat)](/exec/3bobcat.md), [**fork**(2)](/fork/2.md), [**kill**(2)](/kill/2.md), [**pipe**(3bobcat)](/pipe/3bobcat.md), [**redirector**(3bobcat)](/redirector/3bobcat.md), [**stdextractor**(3bobcat)](/stdextractor/3bobcat.md), [**wait**(2)](/wait/2.md), [**waitpid**(2)](/waitpid/2.md).

## BUGS

None Reported.

## BOBCAT PROJECT FILES

- o

  *https://fbb-git.gitlab.io/bobcat/*: gitlab project page;

Debian Bobcat project files:

- o

  *libbobcat6*: debian package containing the shared library, changelog and copyright note;

- o

  *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**).
