2010-08-04 101 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