如何在Linux中使守护进程的子进程交互?

时间:2011-06-27 10:26:53

标签: c linux

我想从守护进程中生成一个交互式进程。我怎样才能做到这一点?我试过以下代码片段:

int main (int argc, char *argv[])
{
    if (fork()) exit (EXIT_FAILURE) ;
    freopen("/dev/null","w",stderr) ;
    freopen("/dev/null","r",stdin) ;
    freopen("/dev/null","w",stdout) ;
    /*
     */
    if (fork()) exit (EXIT_FAILURE) ;
    pid_t shell_pgrp = getpgrp () ;
    pid_t my_pid = getpid () ;
    int shell_tty = isatty (fileno(stderr)) ?
        dup (fileno(stderr)) : open (ctermid(NULL), O_RDWR|O_NONBLOCK) ;
    shell_tty = fcntl (shell_tty,F_DUPFD,10) ;
    fcntl (shell_tty,F_SETFD,FD_CLOEXEC) ;
    if (shell_tty < 0) exit (EXIT_FAILURE) ;
    if ((shell_pgrp = tcgetpgrp (shell_tty)) != getpgrp()) {
        setpgid (my_pid,shell_pgrp) ;
    }
    if (shell_pgrp < 0) exit (EXIT_FAILURE) ;
    if ((shell_pgrp = tcgetpgrp (shell_tty)) == getpgrp()) {
        signal (SIGTTIN,SIG_IGN) ;
        signal (SIGTTOU,SIG_IGN) ;
        signal (SIGTSTP,SIG_IGN) ;
        signal (SIGHUP ,SIG_IGN) ;
        signal (SIGQUIT,SIG_IGN) ;
        signal (SIGQUIT,SIG_IGN) ;
        if (!tcsetpgrp (shell_tty,shell_pgrp)) {
            argv++ ;
            if (execv(argv[0],argv) < 0) {
                exit (EXIT_FAILURE) ;
            }
        }
    }
}

3 个答案:

答案 0 :(得分:0)

我从未尝试过这个我自己,但我不认为重复标准文件 描述符将起作用。我相信你的衍生过程需要获得一个新的控制终端。 This API可能会对您有所帮助。

答案 1 :(得分:0)

由于在后台突然接管终端可能会令用户感到不安,如何使用命令行选项启动xterm以启动所需的进程?

(显然这仅适用于具有X或其他GUI的系统)

答案 2 :(得分:0)

忽略SIGTTIN和朋友不会删除导致它们首先生成的潜在问题。

我想在你的例子中,将输出写入终端的工作正常,但是读取要么得不到,要么得到部分数据。这是因为您的程序从终端读取数据也不会阻止其他人读取数据。当终端是你的shell时,这会导致你需要加倍每个角色以尝试从你造成这种问题的任何问题中恢复。

是的,您可以从命令行运行程序,这将阻止它读取数据并允许您的其他程序进入并获取输入但是......如果您可以安排,那么您应该安排程序正在运行的用户交互本身并通过IPC将结果发送到守护进程/守护进程子。