# Ch13 Daemon Processes
>###### tags: `APUE`
>致謝
>W. Richard Stevens
>*Advanced Programming in the UNIX Environment III*
>Michael Kerrisk
>*The Linux Programming Interface*
>CSDN : linux下/dev/tty, /dev/tty0, /dev/console 區別
## 先備知識
終端是一種字元裝置(Char Device),它有多種類型,我們通常使用tty(Teletype)來簡稱它。如果當前進程有控制終端(Controlling Terminal),那麼/dev/tty就是當前進程的控制終端的設備特殊文件。對於你登錄的shell,/dev/tty就是你使用的終端。
>#ps –ax
>查看進程與哪個控制終端相連
>#tty
>查看shell具體對應哪個實際終端設備

## Daemon Characteristics
A daemon is a process with the following characteristics:
1. Long-lived, a daemon is **created at system startup and runs until the system is shut down**.
2. It runs in the background and has no controlling terminal.
The lack of a controlling terminal ensures that the kernel never automatically generates any job-control or terminal-related signals (such as SIGINT, SIGTSTP, and SIGHUP) for a daemon.
It is a convention (not universally observed) that daemons have names ending with the letter d.
* cron: a daemon that executes commands at a scheduled time
* inetd: the Internet superserver daemon, which listens for incoming network connections on specified TCP/IP ports
>#ps –axj
>-x 顯示沒有controlling terminal的行程,TTY為?。

## Creating a Daemon
To become a daemon, a program performs the following steps:
1. Perform a fork(), after which the parent exits and the child continues.
As a consequence, the daemon becomes a child of the init process.The parent’s termination is noticed by the shell, which then leaves the child to continue in the background.
The child process is guaranteed not to be a process group leader, since it inherited its process group ID from its parent and obtained its own unique process ID.
2. The child process calls setsid() to start a new session and free itself of any association with a controlling terminal.
If the daemon never opens any terminal devices thereafter, then we don’t need to worry about the daemon reacquiring a controlling terminal.
If the daemon might later open a terminal device, then we must take steps to ensure that the device does not become the controlling terminal.
3. Get rid of the controlling terminal association in two ways :
* Specify the O_NOCTTY flag on any open() that may apply to a terminal device.
* Alternatively, and more simply, perform a second fork() after the setsid() call, and again have the parent exit and the (grand)child continue.
The second one ensures that the child is not the session leader, and thus, according to the System V convention, the process can never reacquire a controlling terminal.
4. Clear the process umask, to ensure when the daemon creates files and directories, they have the requested permissions.
5. Change the process’s current working directory, typically to the root directory(/).
The current working directory should be changed to some place guaranteed to always be there.
6. Close all open file descriptors that the daemon has inherited from its parent.(optional)
Since the daemon has lost its controlling terminal and is running in the background, it makes no sense for the daemon to keep file descriptors 0, 1, and 2 open if these refer to the terminal.
7. After having closed file descriptors 0, 1, and 2, a daemon normally opens /dev/null and uses dup() to make all those descriptors refer to this device.
>Code Reference
>https://man7.org/tlpi/code/online/diff/daemons/become_daemon.c.html#becomeDaemon
```c=
//main.c
#include <stdio.h>
#include <unistd.h>
int main(int argc, char ** argv ){
become_daemon(0);
sleep(10);
return 0;
}
```
