The most obvious change to the program is the addition of the setup_daemon() function which is called as the first statement of main(). There are no surprises about what the function does but the way it is coded is different from the conceptual method we looked at earlier.
The first task is to close all the file descriptors. This is done regardless of whether or not they are open. Then, there follows a section which disassociates the daemon from its controlling terminal, session and process group, and stops it from reacquiring another terminal in the future. This is done with the usual fork(), setsid(), fork() sequence but embedded in a pair of switch() constructs to make it easier to deal with any possible errors from the fork() calls. Remember that forkO returns three different values: -1 on error, 0 to the child process and a non-zero value, dealt with by the default: case, to the parent process. Finally, in the second child process, a call is made to umask() to set the file creation mask to 0. This is because the daemon may need to create the file ERROR.LOG if any serious errors occur, and without this call the current umask() value may be unsuitable.