Some basic rules to coding a daemon prevent unwanted interactions from happening. We state these rules and then show a function, daemonize, that implements them.
編寫一個沒有交互功能的守護進程是有一定的步驟的。我們列出相關(guān)的步驟,并且給出一個函數(shù)daemonize,用于展示。
1. The first thing to do is call umask to set the file mode creation mask to 0. The file mode creation mask that's inherited could be set to deny certain permissions. If the daemon process is going to create files, it may want to set specific permissions. For example, if it specifically creates files with group-read and group-write enabled, a file mode creation mask that turns off either of these permissions would undo its efforts.
第一步是使用umask函數(shù),把所有的文件屏蔽字置0。文件屏蔽字是可以繼承的,當你有相關(guān)操作時,如果你要創(chuàng)建一個文件,繼承過來的屏蔽字可能阻止你創(chuàng)建相關(guān)屬性的文件。比如:如果你明確的創(chuàng)建一個文件為組可讀,組可寫。如果你沒有把屏蔽字清零,那么繼承過來的屏蔽字可能不允許你添加這兩個屬性。
2. Call fork and have the parent exit. This does several things. First, if the daemon was started as a simple shell command, having the parent terminate makes the shell think that the command is done. Second, the child inherits the process group ID of the parent but gets a new process ID, so we're guaranteed that the child is not a process group leader. This is a prerequisite for the call to setsid that is done next.
第二步,創(chuàng)建一個子進程,并且令父進程退出。這樣做有以下幾個好處:一,如果守護進程是一個簡單的shell命令啟動的,那么父進程的終止可以使shell認為這個命令已經(jīng)執(zhí)行結(jié)束了。二,子進程繼承了父進程的組ID,但又有自己的進程ID,所以我們可以保證目前的子進程不是進程組長。這一步也是我們接下來要用到的setid函數(shù)之前的必要條件。
3. Call setsid to create a new session. The three steps listed in Section 9.5 occur. The process (a) becomes a session leader of a new session, (b) becomes the process group leader of a new process group, and (c) has no controlling terminal.
Under System Vbased systems, some people recommend calling fork again at this point and having the parent terminate. The second child continues as the daemon. This guarantees that the daemon is not a session leader, which prevents it from acquiring a controlling terminal under the System V rules (Section 9.6). Alternatively, to avoid acquiring a controlling terminal, be sure to specify O_NOCTTY whenever opening a terminal device.
使用setsid函數(shù)創(chuàng)建一個新的對會話。這樣做可以分三個步驟(第一步:把冰箱門打開………):首先,該進程變?yōu)橐粋€新的會話組的會話頭。其次,成為了新的進程組的組長。最后該進程不再控制終端。
在system V 下,一些人建議在此時重新fork一次,并且令父進程退出。第二個子進程仍然是一個守護進程。這樣做可以保證當前進程不是一個會話組的組長,這樣就可以防止他獲得控制終端的能力。作為選擇,為了防止獲得終端的控制權(quán),確定打開終端驅(qū)動時明確設(shè)置O_NOCTTY。
4. Change the current working directory to the root directory. The current working directory inherited from the parent could be on a mounted file system. Since daemons normally exist until the system is rebooted, if the daemon stays on a mounted file system, that file system cannot be unmounted.
把當前工作目錄變?yōu)楦夸洝.斍暗墓ぷ髂夸浭抢^承父進程的。守護進程是一直存在的,除非你重啟計算機。如果你的守護進程是掛載到文件系統(tǒng)上的,那這個文件系統(tǒng)就不能卸載掉。
Alternatively, some daemons might change the current working directory to some specific location, where they will do all their work. For example, line printer spooling daemons often change to their spool directory.
可以根據(jù)你的選擇,一些守護進程也許把當前目錄改變到一些特殊的目錄下,同樣也能完成所有工作。
5. Unneeded file descriptors should be closed. This prevents the daemon from holding open any descriptors that it may have inherited from its parent (which could be a shell or some other process). We can use our open_max function (Figure 2.16) or the getrlimit function (Section 7.11) to determine the highest descriptor and close all descriptors up to that value.
不需要的文件描述符應(yīng)當關(guān)掉。這樣可以防止守護進程持有從父進程繼承過來的文件描述符。我們可以獲取最大的文件描述符,或者使用getrlimit函數(shù)來決定最大的文件描述符的值。并且全部關(guān)閉。
6. Some daemons open file descriptors 0, 1, and 2 to /dev/null so that any library routines that try to read from standard input or write to standard output or standard error will have no effect. Since the daemon is not associated with a terminal device, there is nowhere for output to be displayed; nor is there anywhere to receive input from an interactive user. Even if the daemon was started from an interactive session, the daemon runs in the background, and the login session can terminate without affecting the daemon. If other users log in on the same terminal device, we wouldn't want output from the daemon showing up on the terminal, and the users wouldn't expect their input to be read by the daemon.
一些守護進程把0,1,2這三個文件描述符指向/dev/null,這樣的話,當庫函數(shù)試圖通過標準輸入輸出,標準錯誤時是沒有效果的。當一個守護進程脫離了終端時,就沒有地方打印信息;也沒有地方接收來自用戶的交互式輸入。甚至當一個守護進程從一個交互式的會話開始,守護進程在后臺運行,登陸會話關(guān)閉也不會影響到守護進程。如果其他用戶用同樣的終端登陸,我們不用設(shè)想從守護進程打印信息到終端,也別指望用戶讀取守護進程。
posted on 2010-09-04 14:35
老馬驛站 閱讀(633)
評論(0) 編輯 收藏 引用 所屬分類:
linux