[Linux] Почему процесс стал осиротевшим процессом, но иногда он все еще будет иметь терминальный доступ - PullRequest
0 голосов
/ 24 февраля 2020

У меня есть вопрос, связанный с доступом к терминалу. Ниже приведен мой простой тестовый код, я хочу продемонстрировать, как проверить доступ к терминалу, когда процесс становится осиротевшим процессом. Странно то, что когда я выполняю программу несколько раз, я могу получить другой результат, может ли кто-нибудь помочь объяснить, почему будет разница? Спасибо за помощь!

static void sig_hup(int signo)
{
    if(signo == SIGHUP)
    {
        printf("received the SIGHUP\r\n");
    }
}

void print_ids(char *s)
{
    pid_t pid = getpid();
    printf("[%s] pid = %d, ppid = %d, pgrp = %d, sid = %d, tpgrp = %d\r\n",
        s, getpid(), getppid(), getpgrp(), getsid(pid), tcgetpgrp(STDIN_FILENO)
    );
    fflush(stdout);
}

int main(int argc, char *argv[])
{
    int ret = 0;
    int pid = 0;    
    pid = fork();
    if(pid < 0)
    {
        err_quit("fork fails\r\n");
    }
    else if(pid == 0)
    {
        //child process
        pid_t tmp_pid = 0;
        pid_t current_pid = getpid();
        char s = 0;
        print_ids("child_before");
        signal(SIGHUP, sig_hup);
        kill(getpid(), SIGSTOP);
#if 0
        tmp_pid = setsid();
        if(tmp_pid == current_pid)
        {
            printf("set sid successed\r\n");
        }
        else
        {
            printf("set sid failed, tmp_pid = %d, pid = %d\r\n", tmp_pid, current_pid);
            exit(-1);
        }
#endif
        print_ids("child_after");
        if(read(STDIN_FILENO, &s, 1) != 1)
        {
            printf("read error from TTY, errno = %d\r\n", errno);
        }else
        {
            printf("read from TTY, s = %c\r\n", s);
        }
    }
    else
    {
        print_ids("parent");
        //parent process
        sleep(5);
        exit(0);
    }
    return ret;
}

Когда я выполняю программу вывода, как показано в приведенном ниже результате, первые два раза она работает как положено. Но почему в третий раз потерянный процесс имеет терминальный доступ? Как я знаю, дочерний процесс является фоновым процессом, когда он пытается получить доступ к терминалу, он генерирует SIGTTIN, чтение должно завершиться ошибкой с errno = 5

➜  9_2 ./a.out
[parent] pid = 23263, ppid = 2378, pgrp = 23263, sid = 2378, tpgrp = 23263
[child_before] pid = 23264, ppid = 23263, pgrp = 23263, sid = 2378, tpgrp = 23263
received the SIGHUP
[child_after] pid = 23264, ppid = 1056, pgrp = 23263, sid = 2378, tpgrp = 23263
read error from TTY, errno = 5
➜  9_2 ./a.out
[parent] pid = 23272, ppid = 2378, pgrp = 23272, sid = 2378, tpgrp = 23272
[child_before] pid = 23273, ppid = 23272, pgrp = 23272, sid = 2378, tpgrp = 23272
received the SIGHUP
[child_after] pid = 23273, ppid = 1056, pgrp = 23272, sid = 2378, tpgrp = 23272
read error from TTY, errno = 5
➜  9_2 ./a.out
[parent] pid = 23278, ppid = 2378, pgrp = 23278, sid = 2378, tpgrp = 23278
[child_before] pid = 23279, ppid = 23278, pgrp = 23278, sid = 2378, tpgrp = 23278
received the SIGHUP
[child_after] pid = 23279, ppid = 1056, pgrp = 23278, sid = 2378, tpgrp = 23278
➜  9_2 read from TTY, s = s
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...