c - 使用 execl 执行守护进程

标签 c linux daemon

我正在 Linux 上用 C 编写一个程序,其中包含一个模块 允许在远程机器上执行 shell 命令。这 实际执行命令的最简单方法当然是 只需使用 system() 函数,或使用 popen 然后抓取 输出。但是,由于与当前不相关的其他设计要求,我选择使用更底层的方法 问题。

基本上,我设置了管道和分支,然后调用 execl。这一切 工作完美,除了一个恼人的异常。它不起作用 如果要执行的 shell 命令是守护进程,则正确。在那里面 案例,它只是挂起。我不知道为什么。我的理解是 当守护进程启动时,它通常会 fork ,然后父进程退出。由于我的应用程序有一个通往父级的开放管道,因此调用 当 parent 退出时, to read() 应该失败。但反而 应用程序挂起。

下面是一些重现问题的基本代码:


int main(int argc, char** argv)
{
        // Create a pipe and fork
        //
        int fd[2];
        int p = pipe(fd);
        pid_t pid = fork();<p></p>

<pre><code>    if (pid > 0)
    {
            // Read from the pipe and output the result
            //
            close(fd[1]);
            char buf[1024] = { 0 };
            read(fd[0], buf, sizeof(buf));
            printf("%s\n", buf);

            // Wait for child to terminate
            int status;
            wait(&status);
    }
    else if (pid == 0)
    {
            // Redirect stdout and stderr to the pipe and execute the shell
            // command
            //
            dup2(fd[1], STDOUT_FILENO);
            dup2(fd[1], STDERR_FILENO);
            close(fd[0]);
            execl("/bin/sh", "sh", "-c", argv[1], 0);
    }
</code></pre>

<p>}
</p>

如果您将代码与普通的 shell 命令一起使用,则该代码可以正常工作。但是如果 你尝试运行一个守护进程,它只是挂起而不是返回到 应有的提示。

最佳答案

最可能的解决方案是在 execl() 之上添加 close(fd[1]);

您的程序挂起的原因是 read() 函数等待守护进程向其 stdout/stderr 写入内容。如果守护进程(包括程序的子进程,以及子进程的派生子进程保留其 stdout/stderr)不写任何东西,并且至少有一个进程保持管道的可写端打开,读( )永远不会回来。但是那个进程是什么,它使管道的可写端保持打开状态?它很可能是您程序的子进程的子进程,即长期运行的守护进程。虽然它可能在守护进程时调用了 close(0);close(1);,但很可能它没有调用 close(fd[1] );,所以管道的可写端仍然是打开的。

关于c - 使用 execl 执行守护进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/800712/

相关文章:

Perl 守护进程不使用 Sleep()

c - 使用字符数组作为长整型数组

c - 特定的 C 函数如何工作?

c++ - atoi(string.c_str()) 偶尔出现未处理的异常已更新

linux - Vagrant 规定将 PATH 变量写入 .profile

ruby-on-rails - 非 ruby​​ 站点上的 ruby​​ 错误

c - h_errno 总是打印 "unknown host"

c++ - 面对 SIGTERM 的信号处理程序问题

c - linux中收到SIGHUP信号后如何重启C守护程序

eclipse - 无法启动守护进程,如何为 “Insert Project Name”更新Gradle Classpath