HostedDB - Dedicated UNIX Servers

-->
Internet Security Professional Reference:Understanding and creating
Previous Table of Contents Next


Creating Daemons with the Bourne Shell

If you are a system administrator, you probably have no problems thinking up countless programs you would like to have. You also probably know of a number of tasks you wish were simpler.

In many cases, a daemon can be written to do the job for you. To help you understand how to write a daemon using the Bourne or Korn shells, suppose you want to build a monitor program.

For a system administrator, one of the most precious resources is disk space. If a root file system is filled, it can result in a severe failure or yet another minor annoyance. Fortunately, you can build a monitor program that runs a daemon to monitor and report on available disk space.

Before you dig in working with code, plan on setting some parameters for the program:

  It must be able to read a configuration file.
  It must be able to handle System V and BSD versions of df.
  It must be able to function with or without the Unix syslog facility.

With these requirements in mind, consider how this daemon will be implemented in the Bourne shell. The purpose of this exercise is not to teach programming in the Bourne shell, but to identify issues you need to consider when writing a daemon, such as handling input and output, and signals.

Handling Input and Output

The daemon process often is not associated with any specific terminal, so it must be able to write messages to a screen somewhere if desired. Assume that this program will be operating as the root user, and therefore will be able to access the system console.

Remember that three file descriptors are opened for each shell: standard input, which is normally the keyboard; standard output, which is normally the monitor; and standard error, which is used for error messages and is also directed to the monitor.

0    standard input
1    standard output
2    standard error

To send a message to standard error, you indicate the file descriptor that the message is to be sent to by using the following notation:

    echo "error!" >&2

This example prints “error!” on the standard error device.

This daemon will not need access to standard input for any reason, so you can close standard input, and still keep standard output and standard error available if required. By closing standard input you save a file descriptor that would otherwise be taken in the open file table; you also prevent users from being able to thwart the daemon by attempting to interact with it.

To close file descriptors use the notation:

    exec >&-

This closes the standard output file. To close standard input, use the notation:

    exec <&-

Handling Messages

You now need to consider where messages will be sent when the program generates them. One setup is to specify a device in the program where messages will be sent, such as /dev/console. The following syntax redirects both standard error and standard output to /dev/console:

    exec >/dev/console

or

    exec 2>&1 >/dev/console

Handling Signals

Handling signals is also important because you want to prevent the program from terminating for any reason other than a system shutdown. To do this, you must use the kill command to trap signals that can be sent to the script.

Programmers often use signals as a mechanism of communicating with the program. The program’s response to the signal can be to ignore the request, perform the default action, or to perform some other action. The command to trap signals is trap:

    trap "" signal numbers

This sample command executes the command between the quotes when the specified signal number is received. Because the command list is empty, the signal is ignored. Table 2.4 lists different signals.

Table 2.4
Standard Unix Signals

Name Number Description

SIGHUP 1 Hangup
SIGINT 2 Interrupt
SIGQUIT 3 Quit
SIGILL 4 Illegal instruction
SIGTRAP 5 Trace trap
SIGABRT 6 Abort
SIGEMT 7 Emulator trap
SIGFPE 8 Arithmetic exception
SIGKILL 9 Kill (cannot be caught, blocked, or ignored)
SIGBUS 10 Bus error
SIGSEGV 11 Segmentation violation
SIGSYS 12 Bad argument to system call
SIGPIPE 13 Write on a pipe or other socket with no one to read it
SIGALRM 14 Alarm clock
SIGTERM 15 Software termination signal
SIGURG 16 Urgent condition present on socket
SIGSTOP 17 Stop (cannot be caught, blocked, or ignored)
SIGTSTP 18 Stop signal generated from keyboard
SIGCONT 19 Continue after stop
SIGCHLD 20 Child status has changed
SIGTTIN 21 Background read attempted from control terminal
SIGTTOU 22 Background write attempted to control terminal
SIGIO 23 I/O is possible on a descriptor
SIGXCPU 24 Cpu time limit exceeded
SIGXFSZ 25 File size limit exceeded
SIGVTALRM 26 Virtual time alarm
SIGPROF 27 Profiling timer alarm
SIGWINCH 28 Window changed
SIGLOST 29 Resource lost
SIGUSR1 30 User-defined signal 1
SIGUSR2 31 User-defined signal 2

This list may not include all the available signals for your implementation of Unix. To see a definitive list of all the signals in use by your system, check the file /usr/include/signal.h or use the man command to read the online manual page for the signal library function.


Previous Table of Contents Next