1. Introduction
2. Installing MacPorts
2.1. Install Xcode
2.2. Install MacPorts
2.3. Upgrade MacPorts
2.4. Uninstall MacPorts
2.5. MacPorts and the Shell
3. Using MacPorts
3.1. The port Command
3.2. Port Variants
3.3. Common Tasks
3.4. Port Binaries
4. Portfile Development
4.1. Portfile Introduction
4.2. Creating a Portfile
4.3. Example Portfiles
4.4. Port Variants
4.5. Patch Files
4.6. Local Portfile Repositories
4.7. Portfile Best Practices
4.8. MacPorts' buildbot
5. Portfile Reference
5.1. Global Keywords
5.2. Global Variables
5.3. Port Phases
5.4. Dependencies
5.5. Variants
5.6. Tcl Extensions & Useful Tcl Commands
5.7. StartupItems
5.8. Livecheck / Distcheck
5.9. PortGroups
6. MacPorts Internals
6.1. File Hierarchy
6.2. Configuration Files
6.3. Port Images
6.4. APIs and Libs
6.5. The MacPorts Registry
6.6. Tests
7. MacPorts Project
7.1. Using Trac for Tickets
7.2. Using Git and GitHub
7.3. Contributing to MacPorts
7.4. Port Update Policies
7.5. Updating Documentation
7.6. MacPorts Membership
7.7. The PortMgr Team
8. MacPorts Guide Glossary
Glossary

5.7. StartupItems

A StartupItem is a MacPorts facility to run daemons, a Unix term for programs that run continuously in the background, rather than under the direct control of a user; for example, mail servers, network listeners, etc. Ports that use StartupItem keywords create scripts for launchd, which is the Apple facility introduced with Mac OS X 10.4 to replace xinetd for starting and managing daemons. To support launchd, a program named daemondo is provided by MacPorts base that serves as an adapter between launchd and daemons (executable StartupItems) or traditional Unix startup scripts that start daemons (script StartupItems).

There are three categories of StartupItem keywords. Those that trigger StartupItem creation and logging, those that specify attributes of executable StartupItems, and those that specify attributes of script StartupItems.

Note

The variable startupitem_type in ${prefix}/etc/macports/macports.conf may be set to none to override the default value of the startupitem.type option in Portfiles; this prevents StartupItems from being created.

Additionally, the startupitem_install variable can be set to no in macports.conf to override the default value of the startupitem.install option, which will prevent links from being created under /Library. This is useful for MacPorts installations that are not used with root privileges.

5.7.1. StartupItem Attributes

The keywords in this section may be used with either executable or script StartupItems (see below).

startupitem.autostart

Whether to automatically load the StartupItem after activating the port.

  • Default: no

  • Example:

    startupitem.autostart      yes
startupitem.create

Trigger the creation of a StartupItem.

  • Default: no

  • Example:

    startupitem.create      yes
startupitem.custom_file

(Added: MacPorts 2.8) Path to a file to use as a StartupItem, instead of creating one.

  • Default: (empty)

  • Example:

    startupitem.custom_file      ${worksrcpath}/mydaemon.plist
startupitem.debug

Enable additional debug logging.

  • Default: no

  • Example:

    startupitem.debug      yes
startupitem.install

Whether to install a link to the StartupItem in the appropriate subdirectory of /Library (see startupitem.location) so that it can be launched automatically after rebooting.

  • Default: yes

  • Example:

    startupitem.install        no
startupitem.location

Chooses the subdirectory in which to install the StartupItem. Also affects how it will be loaded: LaunchDaemons must be loaded as root, and only one instance will run for the whole system. LaunchAgents are loaded as a normal user, and one instance per user can run.

  • Default: LaunchDaemons

  • Example:

    startupitem.location        LaunchAgents
startupitem.logfile

Path to a logfile for logging events about the lifetime of the StartupItem. Depending on the type of StartupItem, and the manner in which it is started, standard output from the daemon may also be directed to the logfile.

  • Default: /dev/null

  • Example:

    startupitem.logfile     ${prefix}/var/log/mydaemon.log
startupitem.logevents

Control whether or not to log events to the log file. If logevents is set, events with timestamps are logged to the logfile.

  • Default: no

  • Example:

    startupitem.logevents   yes
startupitem.name

Sets the name for the StartupItem. Defaults to the name of the port, so this keyword is usually unnecessary.

  • Default: ${name}

  • Example:

    startupitem.name        dhcpd
startupitem.netchange

Cause the daemon to be restarted when a change in network state is detected.

  • Default: no

  • Example:

    startupitem.netchange   yes
startupitem.type

The type of the StartupItem. Supported values are launchd for a macOS launchd .plist, or none for no StartupItem.

  • Default: launchd if on macOS and ${startupitem.create} is true, none otherwise

  • Example:

    startupitem.type   launchd
startupitem.user

(Added: MacPorts 2.7) Run the daemon via the specified user.

  • Default: none

  • Example:

    startupitem.user   my_daemon_user
startupitem.group

(Added: MacPorts 2.7) Run the daemon via the specified group.

  • Default: none

  • Example:

    startupitem.group   my_daemon_group
startupitems

Used when a port needs to install more than one StartupItem, this option consists of a list where alternating elements represent keys and values. Each key corresponds to one of the startupitem.* options, and the following value is associated with it. Each StartupItem defined in the list must specify at least a name. Each other key/value pair is associated with the StartupItem named most recently in the list. Any keys that are not defined for a given StartupItem will use the value of the corresponding startupitem.* option.

  • Default: none

  • Example:

    startupitems        name        myport-system \
                        location    LaunchDaemons \
                        executable  ${prefix}/sbin/myportd \
                        name        myport-session \
                        location    LaunchAgents \
                        executable  ${prefix}/bin/myport-agent

5.7.2. Executable StartupItems

Daemons run continuously, so monitoring the health of daemon processes and restarting them if they die is an important StartupItems' feature. Executable StartupItems are preferred over script StartupItems because daemondo launches the daemon directly, rather than indirectly via a script, and therefore it automatically knows how to monitor a daemon process and restart it if it dies. Daemons used with executable StartupItems may be programs or scripts (shell, perl, python, etc.) as long as the script itself is the daemon, rather than merely what launches the daemon. In the latter case script StartupItems are to be used.

Note

Since script and executable are mutually exclusive StartupItem types, the startupitem.executable keyword may not be used in a Portfile that uses any keywords listed in the Script StartupItems section.

startupitem.executable

Specifies the name of the daemon to be run. It may have multiple arguments, but they must be appropriate for a call to exec; arbitrary shell code may not be used.

Note

Some daemons daemonize by detaching themselves from the controlling tty before sending themselves to the background, thus making themselves a child of the original process. A daemon to be started with startupitem.executable must not be allowed to do this or daemondo will think the process has died and start multiple instances. Often daemons have a command switch to run in the foreground, and this method should be used for daemons that detach.

  • Default: none

  • Example:

    startupitem.executable  ${prefix}/sbin/vm-pop3d -d 10 -t 600

Note

Do not wrap values in quotes if passing arguments to the daemon; executable StartupItem elements must be tagged individually so the spaces between arguments serve as delimiters for string tags. For example, this startupitem key/value pair:

startupitem.executable    ${prefix}/sbin/vm-pop3d -d 10 -t 600

generates a .plist file with these tags:

<key>ProgramArguments</key>
<array>
    <string>/opt/local/bin/daemondo</string>
    <string>--label=vm-pop3d</string>
    <string>--start-cmd</string>
    <string>/opt/local/sbin/vm-pop3d</string>
    <string>-d</string>
    <string>10</string>
    <string>-t</string>
    <string>600</string>
    <string>;</string>
</array>

5.7.3. Script StartupItems

StartupItems of type script create a wrapper during port installation for daemondo that will be used to launch a daemon startup script present in an application's source distribution (MacPorts does not create daemon startup scripts) for daemons that require a script.

Note

Executable StartupItems are the preferred type since script StartupItems launch daemons indirectly, and this requires that port authors use the startupitem.pidfile keyword so that daemondo can check this pid file to see is a daemon process has died and restart it. Any time a script (or an executable) itself serves as a daemon, use the executable StartupItem type so daemondo will launch it directly and track its health automatically. Additionally, since script and executable are mutually exclusive StartupItem types, the startupitem.executable keyword may not be used in a Portfile that uses script StartupItem keywords.

A typical snippet of a startup script that may be used with a script StartupItem is shown below. Notice that the script is not a daemon; rather the script indirectly launches the vm-pop3d daemon.

#!/bin/sh

case "$1" in
    start)
        echo -n "Starting vm-pop3d: "
        /opt/local/sbin/vm-pop3d -d 10 -t 600

[... trimmed ...]
startupitem.start, startupitem.stop, startupitem.restart

Specify a shell script to start, stop, and restart the daemon. In the absence of startupitem.restart, the daemon will be restarted by taking the stop action, followed by the start action.

  • Default: none

  • Examples:

    startupitem.start       "${prefix}/share/mysql/mysql.server start"
    startupitem.stop        "${prefix}/share/mysql/mysql.server stop"
    startupitem.restart     "${prefix}/share/mysql/mysql.server restart"

Note

Wrap the stop, start, and restart values in quotes so they will be placed in the wrapper tagged as a single element.

startupitem.init

Shell code that will be executed prior to any of the options startupitem.start, startupitem.stop and startupitem.restart.

  • Default: none

  • Example:

    startupitem.init        BIN=${prefix}/sbin/bacula-fd
startupitem.pidfile

This keyword must be defined properly for daemondo to be able to monitor daemons launched via script StartupItems and restart them if they die. It specifies two things: a process id (PID) file handling method, and a pidfile name and path.

  • Default: none ${prefix}/var/run/${name}.pid

    Default: [none] | [${prefix}/var/run/${name}.pid]

  • Values [none auto manual clean] [/path/to/pidfile]

  • Example:

    startupitem.pidfile     auto ${prefix}/var/run/${name}.pidfile

PID file handling options:

  • none - daemondo will not create or track a PID file, so it won't know when a daemon dies.

  • auto - The started process is expected to create a PID file that contains the PID of the running daemon; daemondo then reads the PID from the file and tracks the process. The started process must delete the PID file if this is necessary.

  • clean - The started process is expected to create a PID file that contains the PID of the running daemon; daemondo then reads the PID from the file and tracks the process, and deletes the PID file if it detects the daemon has died.

  • manual - This option should only be used if an executable StartupItem could be used (daemondo launches a daemon directly) and a port author wants a PID file written for some special use. A PID file is not needed to detect process death for daemons launched directly by daemondo. As with executable StartupItems, daemondo remembers the PID of the launched process and tracks it automatically.

5.7.4. Loading / Unloading StartupItems into launchd

A port with a StartupItem places a link to a .plist file for the port's daemon within /Library/LaunchDaemons/. A .plist file is an XML file; MacPorts installs .plist files tagged as disabled for the sake of security. You may enable a startup script (tag the.plist file as enabled) and load it into launchd with a single command as shown.

%% sudo launchctl load -w /Library/LaunchDaemons/org.macports.mysql5.plist

You may stop a running startup script, disable it (tag the.plist file as disabled), and unload it from launchd with a single command as shown.

%% sudo launchctl unload -w /Library/LaunchDaemons/org.macports.mysql5.plist

5.7.5. StartupItem Internals

During port installation a MacPorts StartupItem creates a .plist file in ${prefix}/etc/LaunchDaemons/, and places a symbolic link to the .plist file within /Library/LaunchDaemons/ if ${startupitem.install} is true.

For example, the StartupItem for the mysql5 port is org.macports.mysql5.plist, and it is linked as shown.

%% ls -l /Library/LaunchDaemons
org.macports.mysql5.plist ->
/opt/local/etc/LaunchDaemons/org.macports.mysql5/org.macports.mysql5.plist

For script StartupItems, in addition to a .plist file, a wrapper is also created.

%% ls -l /opt/local/etc/LaunchDaemons/org.macports.mysql5/
-rwxr-xr-x   2 root  wheel  475 Aug  2 14:16 mysql5.wrapper
-rw-r--r--   2 root  wheel  975 Aug  2 14:16 org.macports.mysql5.plist

The wrapper manipulates the script as specified in the startupitem.start and startupitem.stop keywords. An example wrapper script snippet is shown below.

#!/bin/sh

# MacPorts generated daemondo support script

# Start
Start()
{
    /opt/local/share/mysql5/mysql/mysql.server start
}

# Stop
Stop()
{
    /opt/local/share/mysql5/mysql/mysql.server stop
}

[... trimmed ...]