1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html><head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<!-- base href="http://www.linuxprofilm.com/articles/linux-daemon-howto.html" -->
<meta name="GENERATOR" content="LinuxDoc-Tools 0.9.20"><title>Linux
Daemon Writing HOWTO</title></head><body
background="linux-daemon-howto_files/linux-daemon-howto.html">
<h1>Linux Daemon Writing HOWTO</h1>
<h2>
<a href="mailto:dmwatson@comcast.net">Devin Watson</a></h2>v1.0, May
2004
<hr>
<em>This document shows how to write a daemon in Linux using GCC.
Knowledge
of Linux and a familiarity with C are necessary to use this document.
This HOWTO is Copyright by Devin Watson, under the terms of the BSD
License.</em>
<hr>
<p>
</p><h2><a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html"
name="toc1">1.</a> <a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html#s1">Introduction:
What is a Daemon?</a></h2>
<p>
</p><h2><a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html"
name="toc2">2.</a> <a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html#s2">Getting
Started</a></h2>
<p>
</p><h2><a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html"
name="toc3">3.</a> <a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html#s3">Planning
Your Daemon</a></h2>
<ul>
<li><a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html"
name="toc3.1">3.1</a> <a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html#ss3.1">What
Is It Going To Do?</a>
</li><li><a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html"
name="toc3.2">3.2</a> <a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html#ss3.2">How
Much Interaction?</a>
</li></ul>
<p>
</p><h2><a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html"
name="toc4">4.</a> <a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html#s4">Basic
Daemon Structure</a></h2>
<ul>
<li><a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html"
name="toc4.1">4.1</a> <a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html#ss4.1">Forking
The Parent Process</a>
</li><li><a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html"
name="toc4.2">4.2</a> <a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html#ss4.2">Changing
The File Mode Mask (Umask)</a>
</li><li><a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html"
name="toc4.3">4.3</a> <a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html#ss4.3">Opening
Logs For Writing</a>
</li><li><a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html"
name="toc4.4">4.4</a> <a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html#ss4.4">Creating
a Unique Session ID (SID)</a>
</li><li><a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html"
name="toc4.5">4.5</a> <a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html#ss4.5">Changing
The Working Directory</a>
</li><li><a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html"
name="toc4.6">4.6</a> <a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html#ss4.6">Closing
Standard File Descriptors</a>
</li></ul>
<p>
</p><h2><a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html"
name="toc5">5.</a> <a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html#s5">Writing
the Daemon Code</a></h2>
<ul>
<li><a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html"
name="toc5.1">5.1</a> <a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html#ss5.1">Initialization</a>
</li><li><a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html"
name="toc5.2">5.2</a> <a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html#ss5.2">The
Big Loop</a>
</li></ul>
<p>
</p><h2><a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html"
name="toc6">6.</a> <a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html#s6">Putting
It All Together</a></h2>
<ul>
<li><a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html"
name="toc6.1">6.1</a> <a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html#ss6.1">Complete
Sample</a>
</li></ul>
<hr>
<h2><a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html"
name="s1">1.</a> <a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html#toc1">Introduction:
What is a Daemon?</a></h2>
<p>A daemon (or service) is a background process that is designed to run
autonomously,with little or not user intervention. The Apache web server
http
daemon (httpd) is one such example of a daemon. It waits in the
background
listening on specific ports, and serves up pages or processes scripts,
based on
the type of request.</p>
<p>Creating a daemon in Linux uses a specific set of rules in a given
order.
Knowing how they work will help you understand how daemons operate in
userland
Linux, but can operate with calls to the kernel also. In fact, a few
daemons
interface with kernel modules that work with hardware devices, such as
external
controller boards, printers,and PDAs. They are one of the fundamental
building
blocks in Linux that give it incredible flexibility and power.</p>
<p>Throughout this HOWTO, a very simple daemon will be built in C. As we
go
along, more code will be added, showing the proper order of execution
required
to get a daemon up and running.</p>
<h2><a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html"
name="s2">2.</a> <a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html#toc2">Getting
Started</a></h2>
<p>First off, you'll need the following packages installed on your Linux
machine
to develop daemons, specifically: </p>
<p>
</p><ul>
<li><code>GCC 3.2.2 or higher</code></li>
<li><code>Linux Development headers and libraries</code></li>
</ul>
<p></p>
<p>If your system does not already have these installed (not likely, but
check
anyway), you'll need them to develop the examples in this HOWTO. To find
out
what version of GCC you have installed, use:</p>
<p>
</p><blockquote><code>
</code><pre> gcc --version
</pre>
</blockquote>
<p></p>
<h2><a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html"
name="s3">3.</a> <a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html#toc3">Planning
Your Daemon</a></h2>
<h2><a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html"
name="ss3.1">3.1</a> <a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html#toc3.1">What
Is It Going To Do?</a>
</h2>
<p>A daemon should do one thing, and do it well. That one thing may be
as
complex as managing hundreds of mailboxes on multiple domains, or as
simple as
writing a report and calling sendmail to mail it out to an admin.</p>
<p>In any case, you should have a good plan going in what the daemon
should do.
If it is going to interoperate with some other daemons that you may or
may not
be writing, this is something else to consider as well.</p>
<h2><a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html"
name="ss3.2">3.2</a> <a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html#toc3.2">How
Much Interaction?</a>
</h2>
<p>Daemons should never have direct communication with a user through a
terminal. In fact, a daemon shouldn't communicate directly with a user
at all.
All communication should pass through some sort of interface (which you
may or
may not have to write), which can be as complex as a GTK+ GUI, or as
simple as a
signal set.</p>
<h2><a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html"
name="s4">4.</a> <a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html#toc4">Basic
Daemon Structure</a></h2>
<p>When a daemon starts up, it has to do some low-level housework to get
itself
ready for its real job. This involves a few steps:</p>
<p>
</p><ul>
<li>Fork off the parent process</li>
<li>Change file mode mask (umask)</li>
<li>Open any logs for writing </li>
<li>Create a unique Session ID (SID)</li>
<li>Change the current working directory to a safe place</li>
<li>Close standard file descriptors</li>
<li>Enter actual daemon code</li>
</ul>
<p></p>
<h2><a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html"
name="ss4.1">4.1</a> <a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html#toc4.1">Forking
The Parent Process</a>
</h2>
<p>A daemon is started either by the system itself or a user in a
terminal or
script. When it does start, the process is just like any other
executable on the
system. To make it truly autonomous, a <i>child process</i> must be
created
where the actual code is executed. This is known as forking, and it uses
the
<em>fork()</em> function:
</p><blockquote><code>
</code><pre> pid_t pid;
/* Fork off the parent process */
pid = fork();
if (pid < 0) {
exit(EXIT_FAILURE);
}
/* If we got a good PID, then
we can exit the parent process. */
if (pid > 0) {
exit(EXIT_SUCCESS);
}
</pre>
</blockquote>
<p></p>
<p>Notice the error check right after the call to <em>fork()</em>. When
writing
a daemon, you will have to code as defensively as possible. In fact, a
good
percentage of the total code in a daemon consists of nothing but error
checking. </p>
<p>The <em>fork()</em> function returns either the process id (PID) of
the child
process (not equal to zero), or -1 on failure. If the process cannot
fork a
child, then the daemon should terminate right here.</p>
<p>If the PID returned from <em>fork()</em> did succeed, the parent
process must
exit gracefully. This may seem strange to anyone who hasn't seen it, but
by
forking, the child process continues the execution from here on out in
the code.</p>
<h2><a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html"
name="ss4.2">4.2</a> <a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html#toc4.2">Changing
The File Mode Mask (Umask)</a>
</h2>
<p>In order to write to any files (including logs) created by the
daemon, the
file mode mask (umask) must be changed to ensure that they can be
written to or
read from properly. This is similar to running umask from the command
line, but
we do it programmatically here. We can use the <em>umask()</em> function
to
accomplish this:</p>
<p>
</p><blockquote><code>
</code><pre> pid_t pid, sid;
/* Fork off the parent process */
pid = fork();
if (pid < 0) {
/* Log failure (use syslog if possible) */
exit(EXIT_FAILURE);
}
/* If we got a good PID, then
we can exit the parent process. */
if (pid > 0) {
exit(EXIT_SUCCESS);
}
/* Change the file mode mask */
umask(0);
</pre>
</blockquote>
<p></p>
<p>By setting the umask to 0, we will have full access to the files
generated by
the daemon. Even if you aren't planning on using any files, it is a good
idea to
set the umask here anyway, just in case you will be accessing files on
the
filesystem.</p>
<h2><a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html"
name="ss4.3">4.3</a> <a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html#toc4.3">Opening
Logs For Writing</a>
</h2>
<p>This part is optional, but it is recommended that you open a log file
somewhere in the system for writing. This may be the only place you can
look for
debug information about your daemon.</p>
<h2><a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html"
name="ss4.4">4.4</a> <a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html#toc4.4">Creating
a Unique Session ID (SID)</a>
</h2>
<p>From here, the child process must get a unique SID from the kernel in
order
to operate. Otherwise, the child process becomes an orphan in the
system. The
pid_t type, declared in the previous section, is also used to create a
new
SID for the child process:
</p><blockquote><code>
</code><pre> pid_t pid, sid;
/* Fork off the parent process */
pid = fork();
if (pid < 0) {
exit(EXIT_FAILURE);
}
/* If we got a good PID, then
we can exit the parent process. */
if (pid > 0) {
exit(EXIT_SUCCESS);
}
/* Change the file mode mask */
umask(0);
/* Open any logs here */
/* Create a new SID for the child process */
sid = setsid();
if (sid < 0) {
/* Log any failure */
exit(EXIT_FAILURE);
}
</pre>
</blockquote>
<p></p>
<p>Again, the <em>setsid()</em> function has the same return type
as <em>fork()</em>. We can apply the same error-checking routine here to
see if
the function created the SID for the child process.</p>
<h2><a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html"
name="ss4.5">4.5</a> <a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html#toc4.5">Changing
The Working Directory</a>
</h2>
<p>The current working directory should be changed to some place that is
guaranteed to always be there. Since many Linux distributions do not
completely
follow the Linux Filesystem Hierarchy standard, the only directory that
is
guaranteed to be there is the root (/). We can do this using the
<em>chdir()</em> function:</p>
<p>
</p><blockquote><code>
</code><pre> pid_t pid, sid;
/* Fork off the parent process */
pid = fork();
if (pid < 0) {
exit(EXIT_FAILURE);
}
/* If we got a good PID, then
we can exit the parent process. */
if (pid > 0) {
exit(EXIT_SUCCESS);
}
/* Change the file mode mask */
umask(0);
/* Open any logs here */
/* Create a new SID for the child process */
sid = setsid();
if (sid < 0) {
/* Log any failure here */
exit(EXIT_FAILURE);
}
/* Change the current working directory */
if ((chdir("/")) < 0) {
/* Log any failure here */
exit(EXIT_FAILURE);
}
</pre>
</blockquote>
<p></p>
<p>Once again, you can see the defensive coding taking place. The
<em>chdir()</em> function returns -1 on failure, so be sure to check for
that
after changing to the root directory within the daemon.</p>
<h2><a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html"
name="ss4.6">4.6</a> <a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html#toc4.6">Closing
Standard File Descriptors</a>
</h2>
<p>One of the last steps in setting up a daemon is closing out the
standard file
descriptors (STDIN, STDOUT, STDERR). Since a daemon cannot use the
terminal,
these file descriptors are redundant and a potential security hazard.</p>
<p>The <em>close()</em> function can handle this for us:</p>
<p>
</p><blockquote><code>
</code><pre> pid_t pid, sid;
/* Fork off the parent process */
pid = fork();
if (pid < 0) {
exit(EXIT_FAILURE);
}
/* If we got a good PID, then
we can exit the parent process. */
if (pid > 0) {
exit(EXIT_SUCCESS);
}
/* Change the file mode mask */
umask(0);
/* Open any logs here */
/* Create a new SID for the child process */
sid = setsid();
if (sid < 0) {
/* Log any failure here */
exit(EXIT_FAILURE);
}
/* Change the current working directory */
if ((chdir("/")) < 0) {
/* Log any failure here */
exit(EXIT_FAILURE);
}
/* Close out the standard file descriptors */
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
</pre>
</blockquote>
<p></p>
<p>It's a good idea to stick with the constants defined for the file
descriptors,
for the greatest portability between system versions.</p>
<h2><a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html"
name="s5">5.</a> <a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html#toc5">Writing
the Daemon Code</a></h2>
<h2><a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html"
name="ss5.1">5.1</a> <a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html#toc5.1">Initialization</a>
</h2>
<p>At this point, you have basically told Linux that you're a daemon, so
now
it's time to write the actual daemon code. Initialization is the first
step
here. Since there can be a multitude of different functions that can be
called
here to set up your daemon's task, I won't go too deep into here.</p>
<p>The big point here is that, when initializing anything in a daemon,
the same
defensive coding guidelines apply here. Be as verbose as possible when
writing
either to the syslog or your own logs. Debugging a daemon can be quite
difficult
when there isn't enough information available as to the status of the
daemon.</p>
<h2><a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html"
name="ss5.2">5.2</a> <a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html#toc5.2">The
Big Loop</a>
</h2>
<p>A daemon's main code is typically inside of an infinite loop.
Technically,
it isn't an infinite loop, but it is structured as one:</p>
<p>
</p><blockquote><code>
</code><pre> pid_t pid, sid;
/* Fork off the parent process */
pid = fork();
if (pid < 0) {
exit(EXIT_FAILURE);
}
/* If we got a good PID, then
we can exit the parent process. */
if (pid > 0) {
exit(EXIT_SUCCESS);
}
/* Change the file mode mask */
umask(0);
/* Open any logs here */
/* Create a new SID for the child process */
sid = setsid();
if (sid < 0) {
/* Log any failures here */
exit(EXIT_FAILURE);
}
/* Change the current working directory */
if ((chdir("/")) < 0) {
/* Log any failures here */
exit(EXIT_FAILURE);
}
/* Close out the standard file descriptors */
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
/* Daemon-specific initialization goes here */
/* The Big Loop */
while (1) {
/* Do some task here ... */
sleep(30); /* wait 30 seconds */
}
</pre>
</blockquote>
<p></p>
<p>This typical loop is usually a <em>while</em> loop that has an
infinite
terminating condition, with a call to <em>sleep</em> in there to make it
run at
specified intervals. </p>
<p>Think of it like a heartbeat: when your heart beats, it
performs a few tasks, then waits until the next beat takes place. Many
daemons
follow this same methodology.</p>
<h2><a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html"
name="s6">6.</a> <a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html#toc6">Putting
It All Together</a></h2>
<h2><a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html"
name="ss6.1">6.1</a> <a
href="http://web.archive.org/web/20060603181849/http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/articles/linux-daemon-howto.html#toc6.1">Complete
Sample</a>
</h2>
<p>Listed below is a complete sample daemon that shows all of the steps
necessary for setup and execution. To run this, simply compile using
gcc, and
start execution from the command line. To terminate, use the <i>kill</i>
command after finding its PID.</p>
<p>I've also put in the correct include statements for interfacing with
the syslog,
which is recommended at the very least for sending start/stop/pause/die
log statements, in
addition to using your own logs with the <em>fopen()</em>/<em>fwrite()</em>/<em>fclose()</em>
function calls.</p>
<p>
</p><blockquote><code>
</code><pre>#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <syslog.h>
#include <string.h>
int main(void) {
/* Our process ID and Session ID */
pid_t pid, sid;
/* Fork off the parent process */
pid = fork();
if (pid < 0) {
exit(EXIT_FAILURE);
}
/* If we got a good PID, then
we can exit the parent process. */
if (pid > 0) {
exit(EXIT_SUCCESS);
}
/* Change the file mode mask */
umask(0);
/* Open any logs here */
/* Create a new SID for the child process */
sid = setsid();
if (sid < 0) {
/* Log the failure */
exit(EXIT_FAILURE);
}
/* Change the current working directory */
if ((chdir("/")) < 0) {
/* Log the failure */
exit(EXIT_FAILURE);
}
/* Close out the standard file descriptors */
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
/* Daemon-specific initialization goes here */
/* The Big Loop */
while (1) {
/* Do some task here ... */
sleep(30); /* wait 30 seconds */
}
exit(EXIT_SUCCESS);
}
</pre>
</blockquote>
<p></p>
<p>From here, you can use this skeleton to write your own daemons. Be
sure to
add in your own logging (or use the syslog facility), and code
defensively,
code defensively, code defensively!</p>
<script language="Javascript">
<!--
// FILE ARCHIVED ON 20060603181849 AND RETRIEVED FROM THE
// INTERNET ARCHIVE ON 20070529120944.
// JAVASCRIPT APPENDED BY WAYBACK MACHINE, COPYRIGHT INTERNET ARCHIVE.
// ALL OTHER CONTENT MAY ALSO BE PROTECTED BY COPYRIGHT (17 U.S.C.
// SECTION 108(a)(3)).
var sWayBackCGI = "http://web.archive.org/web/20060603181849/";
function xResolveUrl(url) {
var image = new Image();
image.src = url;
return image.src;
}
function xLateUrl(aCollection, sProp) {
var i = 0;
for(i = 0; i < aCollection.length; i++) {
if (typeof(aCollection[i][sProp]) == "string") {
if (aCollection[i][sProp].indexOf("mailto:") == -1 &&
aCollection[i][sProp].indexOf("javascript:") == -1) {
if(aCollection[i][sProp].indexOf("http") == 0) {
aCollection[i][sProp] = sWayBackCGI + aCollection[i][sProp];
} else {
aCollection[i][sProp] = sWayBackCGI + xResolveUrl(aCollection[i][sProp]);
}
}
}
}
}
xLateUrl(document.getElementsByTagName("IMG"),"src");
xLateUrl(document.getElementsByTagName("A"),"href");
xLateUrl(document.getElementsByTagName("AREA"),"href");
xLateUrl(document.getElementsByTagName("OBJECT"),"codebase");
xLateUrl(document.getElementsByTagName("OBJECT"),"data");
xLateUrl(document.getElementsByTagName("APPLET"),"codebase");
xLateUrl(document.getElementsByTagName("APPLET"),"archive");
xLateUrl(document.getElementsByTagName("EMBED"),"src");
xLateUrl(document.getElementsByTagName("BODY"),"background");
var forms = document.getElementsByTagName("FORM");
if (forms) {
var j = 0;
for (j = 0; j < forms.length; j++) {
f = forms[j];
if (typeof(f.action) == "string") {
if(typeof(f.method) == "string") {
if(typeof(f.method) != "post") {
f.action = sWayBackCGI + f.action;
}
}
}
}
}
//-->
</script>
</body></html>
|