summaryrefslogtreecommitdiff
path: root/docs/daemon/linux-daemon-howto.html
blob: 7514e4bb826c5819e92977cd5ff7e0ade0281d85 (plain)
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 &lt; 0) {
                exit(EXIT_FAILURE);
        }
        /* If we got a good PID, then
           we can exit the parent process. */
        if (pid &gt; 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 &lt; 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 &gt; 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 &lt; 0) {
                exit(EXIT_FAILURE);
        }
        /* If we got a good PID, then
           we can exit the parent process. */
        if (pid &gt; 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 &lt; 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 &lt; 0) {
                exit(EXIT_FAILURE);
        }
        /* If we got a good PID, then
           we can exit the parent process. */
        if (pid &gt; 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 &lt; 0) {
                /* Log any failure here */
                exit(EXIT_FAILURE);
        }
        
        /* Change the current working directory */
        if ((chdir("/")) &lt; 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 &lt; 0) {
                exit(EXIT_FAILURE);
        }
        /* If we got a good PID, then
           we can exit the parent process. */
        if (pid &gt; 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 &lt; 0) {
                /* Log any failure here */
                exit(EXIT_FAILURE);
        }
        
        /* Change the current working directory */
        if ((chdir("/")) &lt; 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 &lt; 0) {
                exit(EXIT_FAILURE);
        }
        /* If we got a good PID, then
           we can exit the parent process. */
        if (pid &gt; 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 &lt; 0) {
                /* Log any failures here */
                exit(EXIT_FAILURE);
        }
        
        
        /* Change the current working directory */
        if ((chdir("/")) &lt; 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 &lt;sys/types.h&gt;
#include &lt;sys/stat.h&gt;
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;fcntl.h&gt;
#include &lt;errno.h&gt;
#include &lt;unistd.h&gt;
#include &lt;syslog.h&gt;
#include &lt;string.h&gt;

int main(void) {
        
        /* Our process ID and Session ID */
        pid_t pid, sid;
        
        /* Fork off the parent process */
        pid = fork();
        if (pid &lt; 0) {
                exit(EXIT_FAILURE);
        }
        /* If we got a good PID, then
           we can exit the parent process. */
        if (pid &gt; 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 &lt; 0) {
                /* Log the failure */
                exit(EXIT_FAILURE);
        }
        

        
        /* Change the current working directory */
        if ((chdir("/")) &lt; 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>