Linux守护程序和STDIN/STDOUT

Err*_*f1f 9 c linux bash

我正在研究一个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;
}
Run Code Online (Sandbox Code Playgroud)

你们提到使用配置文件.这正是我用来存储通过输入接收的参数的方法.但是我最初仍然需要通过stdin从用户那里获取这些内容.确定我们是否第一次运行的逻辑是基于配置文件的存在.

Jon*_*ler 14

通常,应该连接守护程序的标准输入/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).如果它希望得到有意义的输入并且继续没有得到它,该程序应该安全地和安全地关闭商店.


zwo*_*wol 5

你们提到使用配置文件。这正是我为存储通过输入接收到的参数所做的工作。但是,我最初仍然需要通过标准输入从用户那里获取这些信息。确定我们是否第一次运行的逻辑是基于配置文件的存在。

不是读取标准输入,而是让用户自己编写配置文件;分叉之前检查它是否存在,如果不存在则退出并显示错误。在守护程序中包含一个示例配置文件,并在守护程序的联机帮助页中记录其格式。你这样做有一个手册页,是吗?你的配置文件文本文件,是吗?

此外,您的守护程序逻辑缺少一个关键步骤。分叉后,但调用之前setsid,您需要关闭FDS 0,1,2,然后重新打开他们/dev/null(不要尝试与要做到这一点fclosefopen)。这应该可以解决您缓慢的终端问题。