Как сделать дочерний процесс-демон интерактивным в Linux? - PullRequest
1 голос
/ 27 июня 2011

Я хочу порождать интерактивный процесс от демона. Как я могу этого достичь? Я пробовал следующий фрагмент кода:

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 голосов
/ 27 июня 2011

Поскольку что-то в фоновом режиме внезапно захватывает терминал, может сбивать с толку пользователя, как насчет запуска xterm с использованием параметра командной строки, чтобы он запустил желаемый процесс?

(Очевидно, это работает только в системе с X или другим графическим интерфейсом)

0 голосов
/ 27 июня 2011

Игнорирование SIGTTIN и друзей не устраняет основную проблему, которая вызвала их генерацию.

Я предполагаю, что в вашем примере запись вывода в терминал работает нормально, но чтение либо ничего не дает, либо частичные данные. Это связано с тем, что ваша программа, считывающая данные из терминала, также не мешает кому-либо читать данные. Когда терминалом является ваша оболочка, это приводит к ситуациям, когда вам нужно удваивать каждый символ, чтобы попытаться восстановиться после любой проблемы, которая у вас возникла.

Да, вы можете запустить программу из командной строки, которая остановит ее от чтения данных и позволит вашей другой программе войти и захватить ввод, но ... если вы можете это сделать, вам нужно просто организовать программу который работает, сам выполняет взаимодействие с пользователем и отправляет результаты демону / потомку демона через IPC.

0 голосов
/ 27 июня 2011

Я никогда не пробовал это сам, но я не думаю, что дублирование стандартного файла дескрипторы будут работать. Я считаю, что ваш порожденный процесс должен приобрести новый управляющий терминал. Этот API, вероятно, поможет вам.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...