]> git.saurik.com Git - apple/launchd.git/blob - launchd/doc/HOWTO.html
launchd-328.tar.gz
[apple/launchd.git] / launchd / doc / HOWTO.html
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
10 Property List file format for storing configuration information. Apple's
11 Property List APIs provide for three different file formats for storing a
12 property list to disk. A plain text option, a binary option, and an XML text
13 option. For the remainder of this HOWTO, we will use the XML varient to show
14 what 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
19 world" 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
40 is the <code>Label</code> which is what is used to uniquely identify jobs when interacting
41 with launchd. The second is <code>ProgramArguments</code> which for its value, we have an
42 array of strings which represent the tokenized arguments and the program to
43 run. The third and final key is <code>OnDemand</code> which overrides the default value of
44 true with false thereby instructing launchd to always try and keep this job
45 running. That's it! A <code>Label</code>, some <code>ProgramArguments</code> and <code>OnDemand</code> set to false is all
46 you 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
50 not only unnecessary, but unsupported. If you try and run a daemon you didn't
51 write under launchd, you must, at the very least, find a configuration option to
52 keep 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
57 man 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
91 go to a log file and to instruct launchd to temporarily bump up the debug level
92 of launchd's loggging while acting on behave of your job (remember to adjust
93 your 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
134 when a job should be started. It is important to note that launchd will only
135 run one instance of your job though. Therefore, if your on demand job
136 malfunctions, you are guaranteed that launchd will not spawn additional copies
137 when 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
214 the 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>