File: daemon.pp

package info (click to toggle)
fpc 3.2.0%2Bdfsg-12
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, bullseye-backports
  • size: 338,552 kB
  • sloc: pascal: 3,794,737; xml: 191,997; ansic: 9,637; asm: 8,482; java: 5,346; sh: 4,664; yacc: 3,751; makefile: 2,688; lex: 2,538; javascript: 2,375; sql: 929; php: 473; cpp: 145; perl: 134; sed: 132; csh: 34; tcl: 7
file content (141 lines) | stat: -rw-r--r-- 4,163 bytes parent folder | download | duplicates (13)
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
{---------------------------------------------------------------------------
                                 CncWare
                           (c) Copyright 2000
 ---------------------------------------------------------------------------
  Filename..: daemon.pp
  Programmer: Ken J. Wright
  Date......: 03/21/2000

  Purpose - Program to demonstrate construction of a Linux daemon.

  Usage:
    1) Compile this program.
    2) Run it. You will be immediately returned to a command prompt.
    3) Issue the command: ps ax|grep daemon. This will show you the process
       id of the program "daemon" that you just ran.
    4) Issue the command: tail -f daemon.log. This let's you watch the log file
       being filled with the message in the code below. Press Ctrl/c to break
       out of the tail command.
    5) Issue the command: kill -HUP pid. pid is the process number you saw with
       the ps command above. You will see that a new log file has been created.
    6) Issue the command: kill -TERM pid. This will stop the daemon. Issuing the
       ps command above, you will see that the daemon is no longer running.

-------------------------------<< REVISIONS >>--------------------------------
  Ver  |    Date    | Prog | Decription
-------+------------+------+--------------------------------------------------
  1.00 | 03/21/2000 | kjw  | Initial release.
  1.01 | 03/21/2000 | kjw  | Forgot to close input, output, & stderr.
------------------------------------------------------------------------------
}
Program Daemon;
uses SysUtils,BaseUnix;
Var
   { vars for daemonizing }
   bHup,
   bTerm : boolean;
   fLog : text;
   logname : string;
   aOld,
   aTerm,
   aHup : pSigActionRec;
   ps1  : psigset;
   sSet : cardinal;
   pid  : pid_t;
   secs : longint;
   zerosigs : sigset_t;
   hr,mn,sc,sc100 : word;

{ handle SIGHUP & SIGTERM }
procedure DoSig(sig : longint);cdecl;
begin
   case sig of
      SIGHUP : bHup := true;
      SIGTERM : bTerm := true;
   end;
end;

{ open the log file }
Procedure NewLog;
Begin
   Assign(fLog,logname);
   Rewrite(fLog);
   Writeln(flog,'Log created at ',formatdatetime('hh:nn:ss',now));
   Close(fLog);
End;

Begin
   logname := 'daemon.log';
   secs := 10;
   fpsigemptyset(zerosigs);

   { set global daemon booleans }
   bHup := true; { to open log file }
   bTerm := false;

   { block all signals except -HUP & -TERM }
   sSet := $ffffbffe;
   ps1 := @sSet;
   fpsigprocmask(sig_block,ps1,nil);

   { setup the signal handlers }
   new(aOld);
   new(aHup);
   new(aTerm);
   aTerm^.sa_handler{.sh} := SigactionHandler(@DoSig);

   aTerm^.sa_mask := zerosigs;
   aTerm^.sa_flags := 0;
   {$ifndef BSD}                {Linux'ism}
    aTerm^.sa_restorer := nil;
   {$endif}
   aHup^.sa_handler := SigactionHandler(@DoSig);
   aHup^.sa_mask := zerosigs;
   aHup^.sa_flags := 0;
   {$ifndef BSD}                {Linux'ism}
    aHup^.sa_restorer := nil;
   {$endif}
   fpSigAction(SIGTERM,aTerm,aOld);
   fpSigAction(SIGHUP,aHup,aOld);

   { daemonize }
   pid := fpFork;
   Case pid of
      0 : Begin { we are in the child }
         Close(input);  { close standard in }
         Close(output); { close standard out }
         Assign(output,'/dev/null');
         ReWrite(output);
         Close(stderr); { close standard error }
         Assign(stderr,'/dev/null');
         ReWrite(stderr);
      End;
      -1 : secs := 0;     { forking error, so run as non-daemon }
      Else Halt;          { successful fork, so parent dies }
   End;

   { begin processing loop }
   Repeat
      If bHup Then Begin
         {$I-}
         Close(fLog);
         {$I+}
         IOResult;
         NewLog;
         bHup := false;
      End;
      {----------------------}
      { Do your daemon stuff }
      Append(flog);
      Writeln(flog,'daemon code activated at ',formatdatetime('hh:nn:ss',now));
      Close(fLog);
      { the following output goes to the bit bucket }
      Writeln('daemon code activated at ',hr:0,':',mn:0,':',sc:0);
      {----------------------}
      If bTerm Then
         BREAK
      Else
         { wait a while }
         fpSelect(0,nil,nil,nil,secs*1000);
   Until bTerm;
End.