Name daemon library Purpose The daemon library is a set of functions to allow simple C programs to become TCP server daemons while having a number of features that are typical only of larger more complex servers. These features include: 1. Automatically entering the background with isolation from the controlling tty. 2. Keeping the foreground process running until completed successful startup has been confirmed, while outputting to the tty inherited from the shell any messages (especially error messages) which the program may output to confirm or describe startup, or explain a failure. 3. Fork a new worker process for each new TCP connection, passing to that process the new connection as stdin and stdout. 4. Track the number of workers currently running, suspending accepting new connections when a maximum number of workers has been reached. 5. A master monitoring process that monitors the server process, which respawns the server when it exits with a zero error code. 6. Handling of signals to take certain actions such as: HUP Sends HUP to workers, waits for them to finish, and then exits with a code of 0 to get a respawn. USR1 Sends TERM to workers then immediately exits with a code of 0 to get a quick respawn. USR2 Sends USR2 to workers, waits for them to finish, and then exits with a code of 1 to get a gracefull shutdown. INT Sends INT to workers then immediately exits with a code of 1 to get a quick shutdown. TERM Sends TERM to workers then immediately exits with a code of 1 to get a quick shutdown. QUIT Sends QUIT to workers then immediately exits with a code of 1 to get a quick shutdown. 7. Returns back to the calling C program in each new process stage so that the C program can customize the setup and actions at each level of the server. The final level is where the return to the C program is done in the worker process so the code in the C program can fulfill the intended services function for each client. Usage A small server can be written entirely in one C program file, or can be organized into separately called functions, however the programmer prefers to implement it. In addition to several functions intended to set certain customizing parameters, a basic server will perform these calls to the daemon library to engage the server. daemon_start() daemon_master() daemon_success() daemon_server() When the program is invoked from a shell, it inherits the controlling tty and stdin/stdout/stderr. The call to daemon_start() starts a new process called the master process. The return back to the program is done in the master process, while the original process invoked by the shell, called the startup process, remains running in a loop in that function to pass messages from other processes and to exit when the proper time comes (usually very soon). The program is now running in the master process and next calls the daemon_master() function. This function creates another process each time it is to respawn a server. It therefore returns back to the C program repeatedly each time a new server process is started. The original master process remains running a loop in that function to monitor the server process, to pass signals to it, and to respawn or exit as appropriate when the server exits. The program is now running in an instance of a server process and next calls the daemon_server() function to listen on one or more sockets for new connections. The daemon_server() returns back to the calling program in a forked worker process for each new connection. These returns may be many running in parallel for multiple connections at the same time. The calling program must initially set up one or more listening sockets on which connections will be listened for. This can be done at any time up to calling daemon_server(). The list of socket file descriptors is passed to daemon_server(). The recommend place to set this up is between daemon_start() and daemon_master(). The calling program must call daemon_success() after the return from daemon_master() to indicate that the startup is successful. Otherwise it should exit with a non-zero exit code if there is any failure, after possibly outputting a message to stderr describing the problem. The standard I/O library may be used to output the error message. Other functions that exist to customize the daemon operation are: daemon_set_program_name() daemon_set_start_timeout() daemon_set_restart_count_max() daemon_set_server_fast_time() daemon_set_server_fast_max() daemon_set_server_tick() daemon_set_worker_count_max() A logger process function is also being developed which will include the following functions: daemon_enable_logger() daemon_set_logger_name_format() daemon_set_logger_prefix_format() daemon_set_logger_fast_time() daemon_set_server_fast_max() daemon_logger() The following advanced functions also exist to change the default of exiting for certain errors to returning to the calling program with custmized return values. Due to the complexity imposed on a calling program, such returns are not the default, but some applications may need to do some graceful cleanups even when errors happen. daemon_set_start_return_fatal() daemon_set_master_return_fatal() daemon_set_logger_return_fatal() daemon_set_server_return_fatal() Additionally, the following utility function exists to mass close all file descriptors above a certain number. daemon_clean_fd()