Почему я не называю «читать» после установки другого идентификатора группы? - PullRequest
0 голосов
/ 26 октября 2018

В этой программе я изменяю идентификатор группы дочернего процесса.

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>

int main(void) {
 int status;
 char b[4];
 pid_t pid, ch_pid;

 switch(pid=fork()) {
 case -1:
    perror("Fork failed");
    exit(1);
  case  0:
    printf("\nCHILD: This is child process!\n");
    printf("CHILD: My PID is-- %d\n", getpid());
    printf("CHILD: My parent PID -- %d\n", getppid());
    printf("CHILD: My GID is -- %d\n", getpgid(getpid()));
    printf("CHILD: My SID is -- %d\n", getsid(getpid()));
    int k = setpgid(getpid(),getpid()); /*Modifies group id. Therefore, when user press
             Cn+C, ChPr can't die*/
    printf("BEFORE SETPGRP CHILD: My GID is -- %d\n", getpgid(getpid()));
    printf("BEFORE SETPGRP CHILD: My SID is -- %d\n", getsid(getpid()));
    //read(0,b,4);
    //printf("b: %s\n",b);
    pause();
    exit(0);
  default:
    printf("PARENT: This is parent process!\n");
        printf("PARENT: My PID -- %d\n", getpid());
        printf("PARENT: My child PID %d\n",pid);
    printf("PARENT: My parent PID %d\n",getppid());
    printf("PARENT: My GID %d\n",getpgid(getpid()));
    printf("PARENT: My SID %d\n",getsid(getpid()));
    pause();
    exit(0);
 }
    return 0;
}

Но когда я пытаюсь вызвать «чтение» (закомментированные строки), терминал bash не читает и не выводит.Тем не менее, родительский процесс читает успешно.Зачем?Родительский и дочерний процессы имеют одинаковый идентификатор сеанса.Это значит, что они контролируются от общего tty.Я заметил, что если я изменю GID для дочернего процесса и нажму Cntrl + C, родительский процесс прервется только и дочерний процесс станет сиротой.Итак, если я раскомментирую «read» в моей программе и нажму Cntrl + C, это убьет оба процесса.Может быть неудачный read-call посылает некоторый сигнал bash?Спасибо!

Ответы [ 2 ]

0 голосов
/ 30 октября 2018

read(2) разрешено только для процессов в группе процессов переднего плана терминала (это группа процессов, связанная с терминалом в драйвере терминала).Другие процессы останавливаются, драйвер tty отправляет им сигнал SIGSTOP.Некоторые управляющие символы также относятся к группе процессов управления терминалом.

См. termios(4) или tty(4) для описания управления tty.

0 голосов
/ 26 октября 2018

Терминал имеет настройку группы процессов переднего плана .Когда оболочка выполняет команды, она запускает приоритетные задания в приоритетной группе процессов терминала, но фоновые задания помещаются в свою собственную группу процессов.Только группа процессов переднего плана может читать из терминала.Если фоновый процесс пытается прочитать, он приостановлен;когда пользователь перемещает его на передний план, группа терминальных процессов изменяется на эту группу, процесс возобновляется, и тогда он сможет читать.Существует режим stty tostop, который можно использовать для управления возможностью записи в терминал фоновым процессом, но подобной опции для чтения нет, это всегда запрещено.

Если вы хотите, чтобы процесс былвозможность читать из терминала после изменения его группы процессов, вам нужно изменить приоритетную группу процессов терминала.Это делается с помощью функции tcsetpgrp().

tcsetpgrp(0, getpgid(getpid()));
...