用C在Linux的后台启动一个进程

我想在这里做一些有点奇怪的事情。 我需要从deamon开始一个进程logcat,它将在后台运行并打印到terminal,而不用控制stdin。 logcat是非常理想的logcat,它将打印日志消息,同时允许用户input标准命令并从shell初始化程序。 这里是我到目前为止的守护进程的代码。 程序,logcat,启动并显示日志消息,但我不能input任何命令到标准input,因为它似乎程序已经控制了标准input。

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; } 

谢谢

Solutions Collecting From Web of "用C在Linux的后台启动一个进程"

“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. 你可能也想单独留下标准错误。

在程序的某个阶段,您可以正确地进行守护进程 (借用@ bstpierre的答案中的链接),确保您连接的终端不是您的控制终端,以便发送给终端的中断和挂机不会影响你的守护进程 管道比你建立的管道简单 – 你应该处理标准输入,保持标准输出和标准错误不变(而不是改变输出和保持输入不变)。

现在,您可能需要输出到/dev/console ; 如果是的话,修改代码打开/dev/console是合理的。 但是,如果您无法打开/dev/console ,那么回到/dev/null是不合理的; 你的程序应该报告一个错误并且失败(因为把logcat写入/dev/null是没有意义的)。 确保使用O_NOCTTY标志打开控制台,使其不会成为守护进程的控制终端。

我最后的评论是:

  • 你确定你想要随机文本出现在你的终端或控制台,当它被用于其他的事情吗?

发生这种情况时,我不太喜欢它。


另见: SO 958249

如何在Linux中进行守护进程

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