2010-08-04 44 views
8

我想在這裏做一些有點奇怪的事情。我需要從deamon開始一個進程logcat,它將在後臺運行並打印到終端,而不用控制stdin。 Logcat可以非常理想地記錄日誌信息,同時還允許用戶輸入標準命令並從shell初始化程序。這是我迄今爲止的守護進程的代碼。程序logcat啓動並顯示日誌消息,但我無法向stdin輸入任何命令,因爲程序看起來已經控制了stdin。在Linux的後臺啓動一個進程C :)

int main (int argc, char** argv, char** env) 
{ 
    int fd; 
    if ((fd = open("/dev/console", O_RDWR)) < 0) { 
     fd = open("/dev/null", O_RDWR); 
    } 
    printf("THIS IS A TEST\n"); 
    dup2(1, fd); 
    dup2(2, fd); 

    pid_t childpid = fork(); 

    if(childpid == -1) { 
     perror("Failed to fork, logcat not starting"); 
     return 1; 
    } 

    if(childpid == 0) { 
     //this is the child, exec logcat 
     setsid(); 
     int execReturn = execl("/system/bin/logcat", "logcat", (char *) 0); 
    } else { 
     //this is the parent do nothing 
     close(fd); 
     return 0; 
    } 
    close(fd); 
    return 0; 
} 

感謝

回答

4

'logcat'命令似乎是Android開發 - 這或許可以解釋命令的奇位置。

,你必須解決的關鍵操作,以確保您關閉當前的標準輸入(終端)和開放/dev/null/的輸入設備:

close(0); 
if ((fd = open("/dev/null", O_RDONLY)) != 0) 
    ...error - failed to open /dev/null! 

這意味着你的守護進程的子進程不會閱讀任何東西從終端。


我想你想要做的是:

  1. 在命令行中,這將有標準輸入,標準輸出和連接到「終端」標準錯誤運行你的啓動程序。
  2. 在你的程序中,你想要替換標準輸入,所以它來自/dev/null
  3. 您希望僅保留標準輸出 - 您希望logcat可以寫入當前標準輸出。
  4. 您可能也想單獨留下標準錯誤。

在訴訟程序的某些時候,你做你的daemonization正確(借用@ bstpierre的答案的鏈接),確保您連接到終端是不是你的控制終端,使中斷和掛斷發送到終端不會影響你的守護進程。管道比您設置的要簡單 - 您應該處理標準輸入並保持標準輸出和標準錯誤不變(而不是改變輸出並保持輸入不變)。

現在,您可能需要輸出到/dev/console;如果是這樣,那麼修改代碼以打開/dev/console是合理的。但是,如果您無法打開/dev/console,則回到/dev/null是不合理的;你的程序應該報告錯誤並且失敗(因爲logcat寫入/dev/null沒有意義!)。確保使用O_NOCTTY標誌打開控制檯,以便它不會成爲守護進程的控制終端。

最後的評論我要提出的是:你想隨機文本出現在你的終端或控制檯時,它是在使用其他的東西

  • 你確定嗎?

我不太喜歡它,當發生這種情況。


參見:SO 958249

+0

謝謝sooooo爲您的深入解答。問題在於你提到的stdin。我不得不從logcat重定向到stdin,以及一些其他的東西,比如守護進程。這爲我節省了很多壓力和擔憂。再次感謝,我真的很感激。 – Mike 2010-08-04 16:54:20

4
+0

這有助於一噸。謝謝。 – Mike 2010-08-04 16:55:03

+0

@Mike - 有很多東西你可能會錯誤的...我之前沒有看到過,所以這篇文章是記住所有作品的一個很好的起點。 – bstpierre 2010-08-04 17:22:10

+2

該鏈接似乎已經死亡。 – Bharat 2014-07-09 17:24:59

0

有glibc中這個特殊的功能,望目:

#include <unistd.h> 

... 
/* We are in the parent, yet */ 
daemon(0,0); 
/* Now we are in the child */ 
... 

更多詳細的http://linux.die.net/man/3/daemon