]> git.saurik.com Git - apple/launchd.git/blame - launchd/doc/HOWTO.html
launchd-152.tar.gz
[apple/launchd.git] / launchd / doc / HOWTO.html
CommitLineData
ab36757d
A
1<html>
2<body>
3<h1>Getting Started With Launchd</h1>
4
5<p>Launchd is rather simple actually. Far simpler than you might think.</p>
6
7<h2>Before We Get Started</h2>
8
9<p>Launchd, in an effort to be consistent with other Apple software, uses the
10Property List file format for storing configuration information. Apple's
11Property List APIs provide for three different file formats for storing a
12property list to disk. A plain text option, a binary option, and an XML text
13option. For the remainder of this HOWTO, we will use the XML varient to show
14what a configuration file looks like.</p>
15
16<h3>The basics:</h3>
17
18<p>For the simplest of scenarios, launchd just keeps a process alive. A simple "hello
19world" example of that would be:</p>
20
21<blockquote><pre>
22&lt;?xml version="1.0" encoding="UTF-8"?&gt;
23&lt;!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"&gt;
24&lt;plist version="1.0"&gt;
25&lt;dict&gt;
26 &lt;key&gt;Label&lt;/key&gt;
27 &lt;string&gt;com.example.sleep&lt;/string&gt;
28 &lt;key&gt;ProgramArguments&lt;/key&gt;
29 &lt;array&gt;
30 &lt;string&gt;sleep&lt;/string&gt;
31 &lt;string&gt;100&lt;/string&gt;
32 &lt;/array&gt;
33 &lt;key&gt;OnDemand&lt;/key&gt;
34 &lt;false/&gt;
35&lt;/dict&gt;
36&lt;/plist&gt;
37</pre></blockquote>
38
39<p>In the above example, we have three keys to our top level dictionary. The first
40is the <code>Label</code> which is what is used to uniquely identify jobs when interacting
41with launchd. The second is <code>ProgramArguments</code> which for its value, we have an
42array of strings which represent the tokenized arguments and the program to
43run. The third and final key is <code>OnDemand</code> which overrides the default value of
44true with false thereby instructing launchd to always try and keep this job
45running. That's it! A <code>Label</code>, some <code>ProgramArguments</code> and <code>OnDemand</code> set to false is all
46you need to keep a daemon alive with launchd!</p>
47
48<p>Now if you've ever written a daemon before, you've either called the
49<code>daemon()</code> function or written one yourself. With launchd, that is
50not only unnecessary, but unsupported. If you try and run a daemon you didn't
51write under launchd, you must, at the very least, find a configuration option to
52keep the daemon from daemonizing itself so that launchd can monitor it.</p>
53
54<h3>Going beyond the basics with optional keys:</h3>
55
56<p>There are many optional keys available and documented in the launchd.plist
57man page, so we'll only give a few optional, but common examples:</p>
58
59<blockquote><pre>
60&lt;?xml version="1.0" encoding="UTF-8"?&gt;
61&lt;!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"&gt;
62&lt;plist version="1.0"&gt;
63&lt;dict&gt;
64 &lt;key&gt;Label&lt;/key&gt;
65 &lt;string&gt;com.example.sleep&lt;/string&gt;
66 &lt;key&gt;ProgramArguments&lt;/key&gt;
67 &lt;array&gt;
68 &lt;string&gt;sleep&lt;/string&gt;
69 &lt;string&gt;100&lt;/string&gt;
70 &lt;/array&gt;
71 &lt;key&gt;OnDemand&lt;/key&gt;
72 &lt;false/&gt;
73 &lt;key&gt;UserName&lt;/key&gt;
74 &lt;string&gt;daemon&lt;/string&gt;
75 &lt;key&gt;GroupName&lt;/key&gt;
76 &lt;string&gt;daemon&lt;/string&gt;
77 &lt;key&gt;EnvironmentVariables&lt;/key&gt;
78 &lt;dict&gt;
79 &lt;key&gt;FOO&lt;/key&gt;
80 &lt;string&gt;bar&lt;/string&gt;
81 &lt;/dict&gt;
82&lt;/dict&gt;
83&lt;/plist&gt;
84</pre></blockquote>
85
86<p>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.</p>
87
88<h3>Debugging tricks:</h3>
89
90<p>The following example will enable core dumps, set standard out and error to
91go to a log file and to instruct launchd to temporarily bump up the debug level
92of launchd's loggging while acting on behave of your job (remember to adjust
93your syslog.conf accordingly):</p>
94
95<blockquote><pre>
96&lt;?xml version="1.0" encoding="UTF-8"?&gt;
97&lt;!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"&gt;
98&lt;plist version="1.0"&gt;
99&lt;dict&gt;
100 &lt;key&gt;Label&lt;/key&gt;
101 &lt;string&gt;com.example.sleep&lt;/string&gt;
102 &lt;key&gt;ProgramArguments&lt;/key&gt;
103 &lt;array&gt;
104 &lt;string&gt;sleep&lt;/string&gt;
105 &lt;string&gt;100&lt;/string&gt;
106 &lt;/array&gt;
107 &lt;key&gt;OnDemand&lt;/key&gt;
108 &lt;false/&gt;
109 &lt;key&gt;StandardOutPath&lt;/key&gt;
110 &lt;string&gt;/var/log/myjob.log&lt;/string&gt;
111 &lt;key&gt;StandardErrorPath&lt;/key&gt;
112 &lt;string&gt;/var/log/myjob.log&lt;/string&gt;
113 &lt;key&gt;Debug&lt;/key&gt;
114 &lt;true/&gt;
115 &lt;key&gt;SoftResourceLimits&lt;/key&gt;
116 &lt;dict&gt;
117 &lt;key&gt;Core&lt;/key&gt;
118 &lt;integer&gt;9223372036854775807&lt;/integer&gt;
119 &lt;/dict&gt;
120 &lt;key&gt;HardResourceLimits&lt;/key&gt;
121 &lt;dict&gt;
122 &lt;key&gt;Core&lt;/key&gt;
123 &lt;integer&gt;9223372036854775807&lt;/integer&gt;
124 &lt;/dict&gt;
125&lt;/dict&gt;
126&lt;/plist&gt;
127</pre></blockquote>
128
129<h2>But what if I don't want or expect my job to run continuously?</h2>
130
131<h3>The basics of on demand launching:</h3>
132
133<p>Launchd provides a multitude of different criteria that can be used to specify
134when a job should be started. It is important to note that launchd will only
135run one instance of your job though. Therefore, if your on demand job
136malfunctions, you are guaranteed that launchd will not spawn additional copies
137when your criteria is satisfied once more in the future.</p>
138
139<h3>Starting a job periodically:</h3>
140
141<p>Here is an example on how to have a job start every five minutes (300 seconds):</p>
142
143<blockquote><pre>
144&lt;?xml version="1.0" encoding="UTF-8"?&gt;
145&lt;!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"&gt;
146&lt;plist version="1.0"&gt;
147&lt;dict&gt;
148 &lt;key&gt;Label&lt;/key&gt;
149 &lt;string&gt;com.example.touchsomefile&lt;/string&gt;
150 &lt;key&gt;ProgramArguments&lt;/key&gt;
151 &lt;array&gt;
152 &lt;string&gt;touch&lt;/string&gt;
153 &lt;string&gt;/tmp/helloworld&lt;/string&gt;
154 &lt;/array&gt;
155 &lt;key&gt;StartInterval&lt;/key&gt;
156 &lt;integer&gt;300&lt;/integer&gt;
157&lt;/dict&gt;
158&lt;/plist&gt;
159</pre></blockquote>
160
161<p>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 <code>StartCalendarInterval</code> dictionary is treated as a wildcard:</p>
162
163<blockquote><pre>
164&lt;?xml version="1.0" encoding="UTF-8"?&gt;
165&lt;!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"&gt;
166&lt;plist version="1.0"&gt;
167&lt;dict&gt;
168 &lt;key&gt;Label&lt;/key&gt;
169 &lt;string&gt;com.example.touchsomefile&lt;/string&gt;
170 &lt;key&gt;ProgramArguments&lt;/key&gt;
171 &lt;array&gt;
172 &lt;string&gt;touch&lt;/string&gt;
173 &lt;string&gt;/tmp/helloworld&lt;/string&gt;
174 &lt;/array&gt;
175 &lt;key&gt;StartCalendarInterval&lt;/key&gt;
176 &lt;dict&gt;
177 &lt;key&gt;Minute&lt;/key&gt;
178 &lt;integer&gt;11&lt;/integer&gt;
179 &lt;key&gt;Hour&lt;/key&gt;
180 &lt;integer&gt;11&lt;/integer&gt;
181 &lt;key&gt;Day&lt;/key&gt;
182 &lt;integer&gt;11&lt;/integer&gt;
183 &lt;/dict&gt;
184&lt;/dict&gt;
185</pre></blockquote>
186
187<h3>Starting a job based on file system activity:</h3>
188
189<p>The following example will start the job whenever any of the paths being watched change for whatever reason:</p>
190
191<blockquote><pre>
192&lt;?xml version="1.0" encoding="UTF-8"?&gt;
193&lt;!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"&gt;
194&lt;plist version="1.0"&gt;
195&lt;dict&gt;
196 &lt;key&gt;Label&lt;/key&gt;
197 &lt;string&gt;com.example.watchetchostconfig&lt;/string&gt;
198 &lt;key&gt;ProgramArguments&lt;/key&gt;
199 &lt;array&gt;
200 &lt;string&gt;syslog&lt;/string&gt;
201 &lt;string&gt;-s&lt;/string&gt;
202 &lt;string&gt;-l&lt;/string&gt;
203 &lt;string&gt;notice&lt;/string&gt;
204 &lt;string&gt;somebody touched /etc/hostconfig&lt;/string&gt;
205 &lt;/array&gt;
206 &lt;key&gt;WatchPaths&lt;/key&gt;
207 &lt;array&gt;
208 &lt;string&gt;/etc/hostconfig&lt;/string&gt;
209 &lt;/array&gt;
210&lt;/dict&gt;
211</pre></blockquote>
212
213<p>An additional file system trigger is the notion of a queue directory. Launchd will star your job whenever
214the given directories are non-empty and will keep your job running as long as those directories are not empty:</p>
215
216<blockquote><pre>
217&lt;?xml version="1.0" encoding="UTF-8"?&gt;
218&lt;!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"&gt;
219&lt;plist version="1.0"&gt;
220&lt;dict&gt;
221 &lt;key&gt;Label&lt;/key&gt;
222 &lt;string&gt;com.example.mailpush&lt;/string&gt;
223 &lt;key&gt;ProgramArguments&lt;/key&gt;
224 &lt;array&gt;
225 &lt;string&gt;my_custom_mail_push_tool&lt;/string&gt;
226 &lt;/array&gt;
227 &lt;key&gt;QueueDirectories&lt;/key&gt;
228 &lt;array&gt;
229 &lt;string&gt;/var/spool/mymailqdir&lt;/string&gt;
230 &lt;/array&gt;
231&lt;/dict&gt;
232</pre></blockquote>
233
234<h3>Inetd Emulation</h3>
235
236<p>Launchd will happily emulate inetd style daemon semantics:</p>
237
238<blockquote><pre>
239&lt;?xml version="1.0" encoding="UTF-8"?&gt;
240&lt;!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"&gt;
241&lt;plist version="1.0"&gt;
242&lt;dict&gt;
243 &lt;key&gt;Label&lt;/key&gt;
244 &lt;string&gt;com.example.telnetd&lt;/string&gt;
245 &lt;key&gt;ProgramArguments&lt;/key&gt;
246 &lt;array&gt;
247 &lt;string&gt;/usr/libexec/telnetd&lt;/string&gt;
248 &lt;/array&gt;
249 &lt;key&gt;inetdCompatibility&lt;/key&gt;
250 &lt;dict&gt;
251 &lt;key&gt;Wait&lt;/key&gt;
252 &lt;false/&gt;
253 &lt;/dict&gt;
254 &lt;key&gt;Sockets&lt;/key&gt;
255 &lt;dict&gt;
256 &lt;key&gt;Listeners&lt;/key&gt;
257 &lt;dict&gt;
258 &lt;key&gt;SockServiceName&lt;/key&gt;
259 &lt;string&gt;telnet&lt;/string&gt;
260 &lt;key&gt;SockType&lt;/key&gt;
261 &lt;string&gt;stream&lt;/string&gt;
262 &lt;/dict&gt;
263 &lt;/dict&gt;
264&lt;/dict&gt;
265</pre></blockquote>
266
267<h1>TBD</h1>
268
269</body>
270</html>