背景:我们有一个运行Busybox的嵌入式linux系统(资源有限),我们运行的进程通常会在控制台上通过stdout/stderr吐出大量信息,但我们想将其暂时重定向到syslog(在命令上使用syslogd/logger)-无需重新启动进程或重新启动。
使用here找到的代码可以很好地工作,直到我们尝试停止/关闭记录器fd为止,此时写入stdout/stderr的操作将失败,并且一切都会中断。下面的例子:
int main()
{
// Got command to direct all output to syslog:
FILE *fl;
fl = popen("logger","w");
if(fl == NULL)
return 1;
fprintf(fl,"logger test new"); // This goes to syslogd
int nf;
nf = fileno(fl);
dup2(nf,STDOUT_FILENO);
dup2(nf,STDERR_FILENO);
fprintf(stdout,"Written in stdout\n");
fprintf(stderr,"Written in stderr\n");
// ...some time later when we've logged enough things:
pclose(fl);
fprintf(stdout,"This will fail\n");
fprintf(stderr,"Catch fire and die\n");
}
所以问题是,一旦完成日志记录,我们如何恢复原始状态?
在
dup()
和dup2()
上使用RTFM时,如果可以“重新打开”也许freopen()
stdout/stderr,我不清楚我们如何精确地实现这一目标,但是作为最后的选择,也许可以将nf
指向/dev/null/
,因此至少不要崩溃。 最佳答案
您必须在dup2之前对初始文件描述符进行dup,否则dup2将其关闭,并且无法恢复它们。
int stdout_copy = dup(STDOUT_FILENO);
dup2(nf, STDOUT_FILENO);
/* do something with stdout */
dup2(stdout_copy, STDOUT_FILENO);
close(stdout_copy);
进行错误处理,添加
fflush
调用以确保您不会在stdlib缓冲区中保留未写入的数据,并且您应该会很好。关于c - 使用dup2重定向stdout/stderr,然后稍后进行resinstate,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44023742/