【问题标题】:daemon: closed stderr and accept(2)守护进程:关闭标准错误并接受(2)
【发布时间】:2015-07-20 06:31:34
【问题描述】:

我编写了一个 TCP 守护程序,它接受给定端口上的客户端连接,然后使用 execv(3) 执行命令。在每个编写守护进程的教程中都提到关闭 stdin、stdout、stderr 以成功守护进程。

但是我发现accept(2) 重用了已经关闭的stdout/stderr 的文件描述符编号,所以在调用fork(2) 和execv(3) 之后,子进程将输出写入套接字只是因为stdout/stderr 映射到文件描述符现在与客户端套接字关联。

有什么想法可以在不使用 shell 输出重定向的情况下避免这种情况吗?

【问题讨论】:

    标签: linux file sockets descriptor


    【解决方案1】:

    首先,对于守护进程,它的父进程必须退出,所以它会被重定向到INIT进程,它会成为一个守护进程。

    我认为您的用例是,您从其他客户端获取命令并在您的守护程序中执行它,然后将输出重定向到请求客户端。 如果您打算使用 STD_ERR 和 STD_OUT 概念的关闭,那么您必须小心仅以串行方式接收请求。

    现在来解决您的问题, 要将 STD_ERR 和 STD_OUT 重定向到接受的客户端 FD,您必须保持 STD_ERR 和 STD_OUT 打开直到客户端被接受,仅接受客户端后,关闭 STD_OUT,然后将 DUP 与接受的客户端 FD 一起使用。

    请参阅以下链接以从此类问题中获得更多想法。 practical examples use dup or dup2

    【讨论】:

      【解决方案2】:

      大家!

      如果您不希望标准输入/输出的文件描述符被 accept(2) 以及可能返回新文件描述符的任何其他函数重用,请避免对它们调用 close(2)/fclose(3),但将它们重定向到 /dev/null (如果可用)。这个想法来自 daemon(3) 的手册页。

      freopen ("/dev/null", "r", stdin);
      freopen ("/dev/null", "w", stdout);
      freopen ("/dev/null", "w", stderr);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-03-19
        • 2014-09-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-21
        • 2011-08-13
        相关资源
        最近更新 更多