< Previous PageNext Page > Hide TOC

Guidelines for Creating and Launching Daemons

Mac OS X comes with several daemons that provide most of the basic system services. Examples of these services include handling network lookup requests, serving web pages, monitoring hardware devices, and gathering metadata from the file system. The clients of these services may be the operating system, client applications, or both. An example of a daemon used by the system is the mds daemon, which monitors the file system and initiates the gathering of metadata. The system gathers the metadata and puts it in a central repository, which client applications can then access.

Although the general steps for how to create a new daemon are beyond the scope of this document, there are some things that daemon writers need to understand before writing daemons for Mac OS X.

Contents:

When Is a Custom Daemon Appropriate?
Launching Daemons


When Is a Custom Daemon Appropriate?

Most application developers will never need to create a daemon directly. Even those developers that need some sort of background server may not find a daemon to be the best choice in all cases.

Daemons run in the root context, which means they are unaware of the users logged on to the system. A daemon cannot initiate contact with a user process directly, although it can respond to requests made by user processes. Because they have no knowledge of users, daemons also have no access to the window server, and thus no ability to post a visual interface. Daemons are strictly background processes that respond to low-level requests.

If you need to provide user-specific services, you should create an agent instead of a daemon. An agent is essentially the same thing as a daemon, except that it runs in the context of a user session. Agents can communicate with other processes in the same user session and with system-wide daemons in the root context. Because they have access to the window server, agents can also post a user interface, although they should do so sparingly, if at all. Like daemons, agents should be launched automatically.

The only difference between a daemon and an agent is location: daemons are installed in /Library/LaunchDaemons, while agents are installed in /Library/LaunchAgents or in the LaunchAgents subdirectory of an individual user’s Library directory.

If you find that your code provides both user-specific and user-independent services, you might want to create both a daemon and an agent. Your daemon would run in the root context and provide the user-independent services while a copy of your agent would run in each user session. The agents would then coordinate with the daemon to provide the services to each user.

For more information about the root context and user sessions, see Multiple User Environments.

Launching Daemons

Mac OS X provides two methods for launching daemons: startup items and launchd daemons. Which one you use depends largely on the versions of Mac OS X that the daemon must support.

Of course, you do not necessarily have to choose one or the other. For optimal compatibility and performance, you could use both. The key is to add a command-line argument or arguments to enable or disable launchd-compliant behavior, such as launch-on-demand support.

Once you have the ability to launch your daemon in either form, you can install both a launchd property list and a startup item. To avoid launching your daemon twice, be sure to add code to the startup item to disable it in Mac OS X v10.4 or later. For example, the following will print “10.3 or earlier” if it is running on a version of Mac OS X prior to v10.4:

Listing 1  Conditional Startup Item Execution

#!/bin/sh
 
OSVERSION="$(sw_vers -productVersion)"
MAJOR="$(echo $OSVERSION | sed 's/\..*//')"
MINOR="$(echo $OSVERSION | sed -E 's/[0-9]+\.([0-9]+)\..*/\1/')"
PATCH="$(echo $OSVERSION | sed -E 's/[0-9]+\.[0-9]+\.([0-9]+).*/\1/')"
 
echo "MAJOR: $MAJOR"
echo "MINOR: $MINOR"
echo "PATCH: $PATCH"
 
if [ $MAJOR -eq 10 ] ; then
        if [ $MINOR -le 3 ] ; then
                echo "10.3 or earlier";
        fi
fi

For more information about shell scripting, read Shell Scripting Primer.

Launching Custom Daemons Using launchd

With the introduction of launchd in Mac OS X v10.4, an effort was made to improve the steps needed to launch and maintain daemons. Prior to 10.4, if you wanted to launch a custom daemon, you had to create a startup item to do so. During boot up, the system would execute your startup item, allowing you to run a script that launched your daemon. Once launched, your daemon would continue running (and continue holding on to memory and resources) until the computer was shut down or restarted, the daemon was manually shut down, or the daemon itself crashed.

What launchd does is provide a harness for launching and relaunching your daemon as needed. To client programs, the port representing your daemon’s service is always available and ready to handle requests. In reality, the daemon may or may not be running. So, when a client sends a request to the port, launchd may have to launch the daemon so that it can handle the request. Once launched, the daemon can continue running or shut itself down to free up the memory and resources it holds. If a daemon shuts itself down, launchd once again relaunches it as needed to process requests.

In addition to the launch-on-demand feature, launchd provides the following benefits to daemon developers:

For more information on how to create a launch-on-demand daemon, see “Creating launchd Daemons and Agents.”

Launching Daemons with Startup Items

If your software includes a custom daemon and must support versions of Mac OS X prior to 10.4, use a startup item to launch the daemon. A startup item is a bundled shell script or executable binary that runs once when the computer first boots (see “The Boot Process”).

If you have custom startup items, you should install them in the /Library/StartupItems directory. Apple startup items are located in the /System/Library/StartupItems directory, although most of them have been stubbed out in Mac OS X v10.4 and later and replaced by launchd-compliant versions. The stubbed out versions remain for the benefit of other startup items that have dependencies on them.

For information on how to create a startup item, see “Creating a Startup Item.”



< Previous PageNext Page > Hide TOC


© 2003, 2008 Apple Inc. All Rights Reserved. (Last updated: 2008-11-19)


Did this document help you?
Yes: Tell us what works for you.
It’s good, but: Report typos, inaccuracies, and so forth.
It wasn’t helpful: Tell us what would have helped.