Language review completed, by keeling@spots.ab.ca. Minor changes only. Nice HOWTO.

This commit is contained in:
keeling 2004-06-07 20:17:50 +00:00
parent 3b0eeddf87
commit 0b72c6c3f2
1 changed files with 26 additions and 28 deletions

View File

@ -14,17 +14,17 @@ This HOWTO is Copyright by Devin Watson, under the terms of the BSD License.
<toc>
<sect>Introduction: What is a Daemon?
<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
<p>A daemon (or service) is a background process is designed to run
autonomously,with little or no 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
listening on specific ports and serves up pages, or processes scripts, based on
the type of request.
<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
Linux, but can also operate with calls to the kernel. 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
controller boards, printers, and PDAs. They are one of the fundamental building
blocks in Linux that give it incredible flexibility and power.
<p>Throughout this HOWTO, a very simple daemon will be built in C. As we go
@ -50,16 +50,15 @@ what version of GCC you have installed, use:
</verb>
</tscreen>
<sect>Planning Your Daemon
<sect1>What Is It Going To Do?
<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.
writing a report and calling sendmail to mail it out.
<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>In any case, you should have a good plan as to what the daemon should do.
If it is going to interoperate with other daemons (which you may or may not
be writing), this is something else to consider as well.
<sect1>How Much Interaction?
<p>Daemons should never have direct communication with a user through a
@ -75,7 +74,7 @@ ready for its real job. This involves a few steps:
<itemize>
<item>Fork off the parent process
<item>Change file mode mask (umask)
<item>Open any logs for writing
<item>Open logs for writing
<item>Create a unique Session ID (SID)
<item>Change the current working directory to a safe place
<item>Close standard file descriptors
@ -114,9 +113,10 @@ checking.
process (not equal to zero), or -1 on failure. If the process cannot fork a
child, then the daemon should terminate right here.
<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>If <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.
<sect1>Changing The File Mode Mask (Umask)
<p>In order to write to any files (including logs) created by the daemon, the
@ -200,7 +200,7 @@ the function created the SID for the child process.
<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
guaranteed to be there is the root directory (/). We can do this using the
<em>chdir()</em> function:
<tscreen>
@ -245,8 +245,8 @@ after changing to the root directory within the daemon.
<sect1>Closing Standard File Descriptors
<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.
descriptors (STDIN, STDOUT, STDERR). Since a daemon must not use the terminal,
these file descriptors are both redundant and a potential security hazard.
<p>The <em>close()</em> function can handle this for us:
@ -299,15 +299,15 @@ for the greatest portability between system versions.
<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.
here to set up your daemon's task, I won't go too deep into them here.
<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
<p>The big point here is, when initializing anything in a daemon, the same
defensive coding guidelines apply. 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.
<sect1>The Big Loop
<p>A daemon's main code is typically inside of an infinite loop. Technically,
<p>A daemon's main code is typically inside an infinite loop. Technically,
it isn't an infinite loop, but it is structured as one:
<tscreen>
@ -374,8 +374,8 @@ necessary for setup and execution. To run this, simply compile using gcc, and
start execution from the command line. To terminate, use the <it>kill</it>
command after finding its PID.
<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
<p>I've also put in the include statements for interfacing with the syslog,
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.
@ -419,8 +419,6 @@ int main(void) {
exit(EXIT_FAILURE);
}
/* Change the current working directory */
if ((chdir("/")) < 0) {
/* Log the failure */
@ -440,12 +438,12 @@ int main(void) {
sleep(30); /* wait 30 seconds */
}
exit(EXIT_SUCCESS);
exit(EXIT_SUCCESS);
}
</verb>
</tscreen>
<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,
<p>From here, you should be able to use this skeleton to write your own daemons. Be sure to
add in your own logging (or use the syslog facility). Finally, code defensively,
code defensively, code defensively!
</article>