X-Git-Url: https://git.saurik.com/apple/launchd.git/blobdiff_plain/e91b9f68c8f72465f3a6a45ce0aa2ad44c776f32..ab36757d38bc3680d699f3d9d5c21650195fc635:/launchd/doc/HOWTO.html diff --git a/launchd/doc/HOWTO.html b/launchd/doc/HOWTO.html new file mode 100644 index 0000000..a166903 --- /dev/null +++ b/launchd/doc/HOWTO.html @@ -0,0 +1,270 @@ + +
+Launchd is rather simple actually. Far simpler than you might think.
+ +Launchd, in an effort to be consistent with other Apple software, uses the +Property List file format for storing configuration information. Apple's +Property List APIs provide for three different file formats for storing a +property list to disk. A plain text option, a binary option, and an XML text +option. For the remainder of this HOWTO, we will use the XML varient to show +what a configuration file looks like.
+ +For the simplest of scenarios, launchd just keeps a process alive. A simple "hello +world" example of that would be:
+ ++ ++<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>Label</key> + <string>com.example.sleep</string> + <key>ProgramArguments</key> + <array> + <string>sleep</string> + <string>100</string> + </array> + <key>OnDemand</key> + <false/> +</dict> +</plist> +
In the above example, we have three keys to our top level dictionary. The first
+is the Label
which is what is used to uniquely identify jobs when interacting
+with launchd. The second is ProgramArguments
which for its value, we have an
+array of strings which represent the tokenized arguments and the program to
+run. The third and final key is OnDemand
which overrides the default value of
+true with false thereby instructing launchd to always try and keep this job
+running. That's it! A Label
, some ProgramArguments
and OnDemand
set to false is all
+you need to keep a daemon alive with launchd!
Now if you've ever written a daemon before, you've either called the
+daemon()
function or written one yourself. With launchd, that is
+not only unnecessary, but unsupported. If you try and run a daemon you didn't
+write under launchd, you must, at the very least, find a configuration option to
+keep the daemon from daemonizing itself so that launchd can monitor it.
There are many optional keys available and documented in the launchd.plist +man page, so we'll only give a few optional, but common examples:
+ ++ ++<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>Label</key> + <string>com.example.sleep</string> + <key>ProgramArguments</key> + <array> + <string>sleep</string> + <string>100</string> + </array> + <key>OnDemand</key> + <false/> + <key>UserName</key> + <string>daemon</string> + <key>GroupName</key> + <string>daemon</string> + <key>EnvironmentVariables</key> + <dict> + <key>FOO</key> + <string>bar</string> + </dict> +</dict> +</plist> +
In the above example, we see that the job is run as a certain user and group, and additionally has an extra environment variable set.
+ +The following example will enable core dumps, set standard out and error to +go to a log file and to instruct launchd to temporarily bump up the debug level +of launchd's loggging while acting on behave of your job (remember to adjust +your syslog.conf accordingly):
+ ++ ++<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>Label</key> + <string>com.example.sleep</string> + <key>ProgramArguments</key> + <array> + <string>sleep</string> + <string>100</string> + </array> + <key>OnDemand</key> + <false/> + <key>StandardOutPath</key> + <string>/var/log/myjob.log</string> + <key>StandardErrorPath</key> + <string>/var/log/myjob.log</string> + <key>Debug</key> + <true/> + <key>SoftResourceLimits</key> + <dict> + <key>Core</key> + <integer>9223372036854775807</integer> + </dict> + <key>HardResourceLimits</key> + <dict> + <key>Core</key> + <integer>9223372036854775807</integer> + </dict> +</dict> +</plist> +
Launchd provides a multitude of different criteria that can be used to specify +when a job should be started. It is important to note that launchd will only +run one instance of your job though. Therefore, if your on demand job +malfunctions, you are guaranteed that launchd will not spawn additional copies +when your criteria is satisfied once more in the future.
+ +Here is an example on how to have a job start every five minutes (300 seconds):
+ ++ ++<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>Label</key> + <string>com.example.touchsomefile</string> + <key>ProgramArguments</key> + <array> + <string>touch</string> + <string>/tmp/helloworld</string> + </array> + <key>StartInterval</key> + <integer>300</integer> +</dict> +</plist> +
Sometimes you want a job started on a calendar based interval. The following example will start the job on the 11th minute of the 11th hour every day (using a 24 hour clock system) on the 11th day of the month. Like the Unix cron subsystem, any missing key of the StartCalendarInterval
dictionary is treated as a wildcard:
+ ++<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>Label</key> + <string>com.example.touchsomefile</string> + <key>ProgramArguments</key> + <array> + <string>touch</string> + <string>/tmp/helloworld</string> + </array> + <key>StartCalendarInterval</key> + <dict> + <key>Minute</key> + <integer>11</integer> + <key>Hour</key> + <integer>11</integer> + <key>Day</key> + <integer>11</integer> + </dict> +</dict> +
The following example will start the job whenever any of the paths being watched change for whatever reason:
+ ++ ++<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>Label</key> + <string>com.example.watchetchostconfig</string> + <key>ProgramArguments</key> + <array> + <string>syslog</string> + <string>-s</string> + <string>-l</string> + <string>notice</string> + <string>somebody touched /etc/hostconfig</string> + </array> + <key>WatchPaths</key> + <array> + <string>/etc/hostconfig</string> + </array> +</dict> +
An additional file system trigger is the notion of a queue directory. Launchd will star your job whenever +the given directories are non-empty and will keep your job running as long as those directories are not empty:
+ ++ ++<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>Label</key> + <string>com.example.mailpush</string> + <key>ProgramArguments</key> + <array> + <string>my_custom_mail_push_tool</string> + </array> + <key>QueueDirectories</key> + <array> + <string>/var/spool/mymailqdir</string> + </array> +</dict> +
Launchd will happily emulate inetd style daemon semantics:
+ ++ ++<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>Label</key> + <string>com.example.telnetd</string> + <key>ProgramArguments</key> + <array> + <string>/usr/libexec/telnetd</string> + </array> + <key>inetdCompatibility</key> + <dict> + <key>Wait</key> + <false/> + </dict> + <key>Sockets</key> + <dict> + <key>Listeners</key> + <dict> + <key>SockServiceName</key> + <string>telnet</string> + <key>SockType</key> + <string>stream</string> + </dict> + </dict> +</dict> +