簡體   English   中英

Linux守護程序和STDIN / STDOUT

[英]A Linux Daemon and the STDIN/STDOUT

我正在研究一個linux守護進程,並且在stdin / stdout上遇到了一些問題。 通常由於守護程序的性質,您沒有任何標准輸入或標准輸出。 但是,我的守護進程中確實有一個函數,當守護進程第一次運行時調用該函數來指定守護進程成功運行所需的不同參數。 當調用此函數時,終端變得如此遲緩,以至於我必須啟動一個單獨的shell並使用top殺死守護進程以獲得響應式提示。 現在我懷疑這與關閉stdin / stdout的分叉過程有關,但我不太確定如何解決這個問題。 如果你們能夠了解一下最值得贊賞的情況。 謝謝。

編輯:

int main(argc, char *argv[]) {

/* setup signal handling */

/* check command line arguments */

pid_t pid, sid;

pid = fork();

if (pid < 0) {
exit(EXIT_FAILURE);
}

if(pid > 0){
exit(EXIT_SUCCESS);
}

sid = setsid();

if(sid < 0) {
exit(EXIT_FAILURE);
}

umask(027);

/* set syslogging */

/* do some logic to determine wether we are running the daemon for the first time and if we are call the one time function which uses fgets() to recieve some input */

while(1) {

/* do required work */

}

/* do some clean up procedures and exit */

return 0;
}

你們提到使用配置文件。 這正是我用來存儲通過輸入接收的參數的方法。 但是我最初仍然需要通過stdin從用戶那里獲取這些內容。 確定我們是否第一次運行的邏輯是基於配置文件的存在。

通常,守護程序的標准輸入應連接到/dev/null ,這樣如果從標准輸入讀取任何內容,則會立即獲得EOF。 通常,標准輸出應連接到文件 - 日志文件或/dev/null 后者意味着所有寫入都將成功,但不會存儲任何信息。 同樣,標准錯誤應該連接到/dev/null或日志文件。

所有程序(包括守護進程)都有權假定stdin,stdout和stderr是適當打開的文件流。

守護進程通常適合控制其輸入來自何處以及輸出進入何處。 輸入很少來自/dev/null以外的其他輸入。 如果編寫的代碼在沒有標准輸出或標准錯誤的情況下生存(例如,它打開標准日志通道,或者可能使用syslog(3) ),那么關閉stdout和stderr可能是合適的。 否則,將消息重定向到/dev/null可能是合適的,同時仍將消息記錄到日志文件中。 或者,您可以將stdout和stderr重定向到日志文件 - 注意不斷增長的日志文件。

你的緩慢到不可能的響應時間可能是因為你的程序在一個讀取循環中沒有注意到EOF。 它可能會提示用戶輸入/ dev / null,並從/ dev / null讀取響應,而不是返回“y”或“n”,它會再次嘗試,這會嚴重損壞您的系統。 當然,代碼存在缺陷,因為它沒有處理EOF,並計算得到無效響應的次數,並在合理的嘗試次數后停止愚蠢(16,32,64)。 如果它希望得到有意義的輸入並且繼續沒有得到它,該程序應該安全地和安全地關閉商店。

你們提到使用配置文件。 這正是我用來存儲通過輸入接收的參數的方法。 但是我最初仍然需要通過stdin從用戶那里獲取這些內容。 確定我們是否第一次運行的邏輯是基於配置文件的存在。

而不是讀取標准輸入,讓用戶自己編寫配置文件; 分叉之前檢查它的存在,如果沒有,則退出並返回錯誤。 在守護程序的聯機幫助頁中包含示例配置文件,並在守護程序的聯機幫助頁中記錄其格式。 有一個手冊頁,是嗎? 你的配置文件文本的,是嗎?

此外,您的守護進程邏輯缺少關鍵步驟。 分叉后,但之前調用setsid ,你需要關閉FDS 0,1,2,並將其重新打開來/dev/null不要試圖用做這個fclosefopen )。 這應該可以解決你遲緩的終端問題。

如果要運行程序分離,請使用shell(setsid <command> &) 不要在程序中使用fork() ,這會導致系統管理員的噩夢

不要使用syslog()也不要重定向stdoutstderr

更好的是,使用守護程序管理器(例如守護程序工具,runit,OpenRC和systemd)來為您守護程序。

你的設計是錯的。 守護進程不應通過stdin獲取輸入或將輸出傳遞給stdout / stderr。 作為守護階段的一部分,您將關閉這些描述符。 守護進程應該從命令行,配置文件或兩者中獲取配置參數。 如果需要運行時輸入,則必須讀取文件,打開套接字等,但守護程序的目的是它應該能夠在沒有用戶出現在控制台的情況下運行並執行其操作。

使用配置文件。 不要將STDIN或STDOUT與守護進程一起使用。 守護進程旨在在后台運行而無需用戶交互。

如果你堅持使用stdin / keyboard輸入來啟動守護進程(例如,獲取一些你不想存儲在文件中的魔術密碼),那么在fork() 之前處理所有I / O.

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM