我想在这里做一些有点奇怪的事情。 我需要从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; }
谢谢
“logcat”命令似乎是为了Android开发 – 这可能解释了命令的奇怪位置。
您必须解决的关键操作是确保关闭当前的标准输入(终端)并打开/dev/null/
输入设备:
close(0); if ((fd = open("/dev/null", O_RDONLY)) != 0) ...error - failed to open /dev/null!
这意味着你的守护进程的子进程将不会从终端读取任何东西。
我想你想要做的是:
/dev/null
。 logcat
写入当前的标准输出。 在程序的某个阶段,您可以正确地进行守护进程 (借用@ 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 */ ...