c - Linux 守护进程和 STDIN/STDOUT

标签 c linux bash

我正在开发一个 linux 守护进程,但在 stdin/stdout 方面遇到了一些问题。通常,由于守护程序的性质,您没有任何标准输入或标准输出。但是,我的守护进程中确实有一个函数,当守护进程第一次运行时调用该函数来指定守护进程成功运行所需的不同参数。当这个函数被调用时,终端变得非常缓慢,我不得不启动一个单独的 shell 并用 top 杀死守护进程以获得响应提示。现在我怀疑这与关闭标准输入/标准输出的 fork 过程有关,但我不太确定如何解决这个问题。如果你们能对情况有所了解,我们将不胜感激。谢谢。

编辑:

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

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

最佳答案

通常,守护进程的标准输入应该连接到/dev/null,这样如果从标准输入读取任何内容,您会立即得到一个EOF。通常,标准输出应该连接到一个文件 - 日志文件或 /dev/null。后者意味着所有写入都会成功,但不会存储任何信息。同样,标准错误应连接到 /dev/null 或日志文件。

所有程序,包括守护进程,都有权假定标准输入、标准输出和标准错误是正确打开的文件流。

守护进程控制其输入来源和输出去向通常是合适的。输入很少来自 /dev/null 以外的地方。如果代码是为了在没有标准输出或标准错误的情况下生存而编写的(例如,它打开标准日志 channel ,或者可能使用 syslog(3)),那么关闭 stdout 和 stderr 可能是合适的。否则,将它们重定向到 /dev/null 可能是合适的,同时仍将消息记录到日志文件中。或者,您可以将 stdout 和 stderr 重定向到一个日志文件 - 请注意不断增长的日志文件。

您的响应时间缓慢到不可能的可能是因为您的程序没有在某处的读取循环中注意 EOF。它可能会提示用户在/dev/null 上输入,并从/dev/null 读取响应,但没有得到 'y' 或 'n' 返回,它会再次尝试,这会严重破坏你的系统。当然,代码的缺陷在于不处理 EOF,并计算它获得无效响应的次数并在合理的尝试次数(16、32、64)后停止犯傻。如果该程序需要一个有意义的输入并且继续得不到它,它应该理智和安全地关闭商店。

关于c - Linux 守护进程和 STDIN/STDOUT,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4869860/

相关文章:

c - volatile 对数组和类型转换的意义

c# - 函数定义,C 到 .NET

使用 mknod() 创建目录

c/unix : abort process that runs for too long

linux - 使用 bash 获取特定列的总和?

linux - 如何从 HH :MM Format for a Shell Script 中的参数中捕获值

linux - bash中的-z是什么

linux - 使用 r8 寄存器作为循环计数器会导致无限循环 - 为什么?

android - "CPU does not support SVM"在 Windows 上的 Android-Studio 中显示,但在 Linux 上不显示

linux - Perl 正则表达式递归替换多个文件组中的字符串,如 "*.php" "*.html"