---
name: "rc.subr"
section: "8"
platform: "openbsd"
package: "man"
version: "8.0-current-20261101"
release: "OpenBSD 8.0-current (2026-11-01)"
platforms: ["freebsd", "openbsd"]
url: "https://new.carta.tech/rc.subr"
---

# rc.subr(8)

daemon control scripts routines

## NAME

**rc.subr** – daemon control scripts routines

## SYNOPSIS

**daemon**=*path\_to\_executable*

**.** */etc/rc.d/rc.subr*

**rc\_cmd** *action*

## DESCRIPTION

Apart from a few notable exceptions, rc scripts must follow this naming policy:

1. When possible, use the same name as the **daemon** it is referring to.

2. It must follow [ksh(1)](/ksh/1.md) variable naming: begin with an alphabetic or underscore character, followed by one or more alphanumeric or underscore characters. Dashes (‘-’) have to be converted to underscores (‘\_’).

Every script under */etc/rc.d* follows this pattern:

1. Define the *daemon* variable.

2. Define service-specific defaults for one or more *daemon\_\** variables (optional).

3. Source **rc.subr**, which defines default shell functions and variable values.

4. Override the *pexp* variable or any of the **rc\_\*** functions and set the *rc\_bg* or *rc\_reload* variables, if needed.

5. Define an **rc\_pre** and/or **rc\_post** function, if needed.

6. Call the **rc\_cmd** function as “rc\_cmd $1”.

The following shell functions are defined by **rc.subr**:

- **rc\_check**

  Search for processes of the service with [pgrep(1)](/pgrep/1.md) using the regular expression given in the *pexp* variable.

- **rc\_cmd** *action*

  Run the *action* for the current **rc.d** script, based on the settings of various shell variables. **rc\_cmd** is extremely flexible, and allows fully functional **rc.d** scripts to be implemented in a small amount of shell code. For a given *action*, if the **rc\_${action}** function is not defined, then a default function is provided by **rc.subr**. In addition actions can be disabled by setting the *rc\_${action}* variable to “NO”. For example, if “rc\_reload=NO” is set in the **rc.d** script, and **rc\_cmd** is called for the reload action, an error will be raised. Similarly, the special variable *rc\_usercheck* must be set to “NO” if the **check** *action* requires root privileges.

  The *action* argument can be **start**, **stop**, **reload**, **restart**, or **check**:

  - **check**

    Call **rc\_check**. Return 0 if the daemon is running or 1 if it is not.

  - **start**

    Check that the service is running by calling **rc\_check**. If it's not running, call **rc\_pre** if it exists, then **rc\_start**.

  - **stop**

    Check that the service is running by calling **rc\_check**. If it is running, call **rc\_stop** and wait up to 30 seconds for the daemon to properly shutdown. If successful, run **rc\_post** if it exists.

  - **restart**

    Run the *action* argument **stop**, then if successful run **start**.

  - **reload**

    Check that the service is running by calling **rc\_check**. If it is running, call **rc\_reload**.

- **rc\_configtest**

  Check daemon configuration before running **start**, **reload** and **restart** if implemented by the [rc.d(8)](/rc.d/8.md) script.

- **rc\_exec**

  Execute argument using [su(1)](/su/1.md) according to *daemon\_class*, *daemon\_execdir*, *daemon\_user*, *daemon\_rtable* and *daemon\_logger* values.

- **rc\_post**

  This function is run after **stop** if implemented by the [rc.d(8)](/rc.d/8.md) script.

- **rc\_pre**

  This function is run before **start** if implemented by the [rc.d(8)](/rc.d/8.md) script.

- **rc\_reload**

  Send the *rc\_reload\_signal* using [pkill(1)](/pkill/1.md) on the regular expression given in the *pexp* variable. One has to make sure that sending SIGHUP to a daemon will have the desired effect, i.e. that it will reload its configuration.

- **rc\_start**

  Start the daemon. Defaults to:

  ```
  rc_exec "${daemon} ${daemon_flags}"
  ```

- **rc\_stop**

  Stop the daemon. Send the *rc\_stop\_signal* using [pkill(1)](/pkill/1.md) on the regular expression given in the *pexp* variable.

## ENVIRONMENT

**rc\_cmd** uses the following shell variables to control its behaviour.

- *daemon*

  The path to the daemon, optionally followed by one or more whitespace separated arguments. Arguments included here are always used, even if *daemon\_flags* is empty. This variable is required. It is an error to source **rc.subr** without defining *daemon* first.

- *daemon\_class*

  Login class to run the daemon with, using [su(1)](/su/1.md). This is a read only variable that gets set by **rc.subr** itself. It searches [login.conf(5)](/login.conf/5.md) for a login class that has the same name as the **rc.d** script itself and uses that. If no such login class exists then “daemon” will be used.

- *daemon\_execdir*

  Change to this directory before running **rc\_exec**.

- *daemon\_flags*

  Arguments to call the daemon with.

- *daemon\_logger*

  Redirect standard output and error to [logger(1)](/logger/1.md) using the configured priority (e.g. "daemon.info").

- *daemon\_rtable*

  Routing table to run the daemon under, using [route(8)](/route/8.md).

- *daemon\_timeout*

  Maximum time in seconds to wait for the **start**, **stop** and **reload** actions to return. This is only guaranteed with the default **rc\_start**, **rc\_stop** and **rc\_reload** functions.

- *daemon\_user*

  User to run the daemon as, using [su(1)](/su/1.md).

- *pexp*

  A regular expression to be passed to [pgrep(1)](/pgrep/1.md) in order to find the desired process or to be passed to [pkill(1)](/pkill/1.md) to stop it. By default this variable contains the *daemon* and *daemon\_flags* variables. To override the default value, an **rc.d** script has to redefine this variable *after* sourcing **rc.subr**.

- *rc\_bg*

  Can be set to **YES** in an **rc.d** script to force starting the daemon in background when using the default **rc\_start**.

- *rc\_reload*

  Can be set to “NO” in an **rc.d** script to disable the reload action if the respective daemon does not support reloading its configuration. *The* *same* *is* *possible,* *but* *almost* *never* *useful,* *for* *other* *actions.*

- *rc\_reload\_signal*

  Signal sent to the daemon process (*pexp*) by the default **rc\_reload**() function. Defaults to *HUP*.

- *rc\_stop\_signal*

  Signal sent to the daemon process (*pexp*) by the default **rc\_stop**() function. Default to *TERM*.

- *rc\_usercheck*

  Can be set to “NO” in an **rc.d** script, if the **check** action needs root privileges.

All *daemon\_\** variables are set in the following ways:

1. Global defaults are provided by **rc.subr**:

   ```
   daemon_class=daemon
   daemon_execdir=
   daemon_flags=
   daemon_logger=
   daemon_rtable=0
   daemon_timeout=30
   daemon_user=root
   ```

2. Service-specific defaults may be provided in the respective **rc.d** script *before* sourcing **rc.subr**, thus overriding the global defaults.

3. As noted in [rc.d(8)](/rc.d/8.md), site-specific values provided in rc.conf.local(8) for *daemon\_execdir*, *daemon\_flags*, *daemon\_logger*, *daemon\_rtable*, *daemon\_timeout*, and *daemon\_user* will override those defaults.

## FILES

- */etc/rc.d/*

  Directory containing daemon control scripts.

- */etc/rc.d/rc.subr*

  Functions and variables used by **rc.d** scripts.

- */usr/ports/infrastructure/templates/rc.template*

  A sample **rc.d** script.

## SEE ALSO

[rc(8)](/rc/8.md), [rc.conf(8)](/rc.conf/8.md), [rc.d(8)](/rc.d/8.md)

## HISTORY

The **rc.subr** framework first appeared in OpenBSD 4.9.

## AUTHORS

The **rc.subr** framework was written by Robert Nagy ⟨*robert@openbsd.org*⟩, Antoine Jacoutot ⟨*ajacoutot@openbsd.org*⟩, and Ingo Schwarze ⟨*schwarze@openbsd.org*⟩.
