Как я могу предотвратить фоновые задания от чтения ввода с терминала? - PullRequest
1 голос
/ 07 декабря 2011

Я пишу программу оболочки для класса, и у меня возникла проблема, которую я не до конца понимаю.

Я должен реализовать фоновые задания. Проблемы, препятствующие чтению фонового задания из терминала. Каждый ресурс, о котором я говорю, просто не вызывает wait (), но это вызывает у меня ошибку. Прямо сейчас у меня есть небольшая программа, которая просто читает ввод и перепечатывает его до eof. Что происходит, после того, как в какой-то момент я выполняю форк и exec при наборе других команд, он начинает печатать 0

0 0 0 , , .

Я сталкивался с некоторыми предлагаемыми решениями, такими как изменение группы процессов. UNIX Системный вызов для регистрации фонового процесса

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

Я начал писать обработчик сигнала, чтобы поймать SIGTTIN, однако я не уверен, что делать в этот момент. Я думал, что использую kill (), чтобы приостановить программу, но как мне получить pid процесса, который пытается прочитать.

edit: я должен упомянуть, что эта проблема является причиной, потому что моя тестовая программа читает входные данные как int. Но мне нужно, чтобы он блокировался при чтении.

edit: Моя простая тестовая программа

  cin >> temp;
  do{
    cout << temp << endl;
    cin >> temp;

  }while(!cin.eof());

когда он разветвляется, ребенок бежит

  if(PID == 0){
    /*code for checking if IO is redirected*/
    execvpe(args[0], args, curState.getEnv());
    cout << args[0] << " not a command" << endl;
    exit(1);
  }

Затем родитель проверяет, стоит ли ждать

if(jobWait()){
    waitpid(PID, &status, 0);
  }

1 Ответ

2 голосов
/ 07 декабря 2011

Решил мою проблему, если я правильно использую setpgid (int, int), то фоновое приложение останавливается при попытке прочитать ввод. Затем я могу передать ему управление терминалом из родительского процесса с помощью tcsetpgrp (int, int) и ждать дочернего процесса с помощью waitpid (int, & int, int), и до тех пор, пока я обрабатываю SIGCHLD, чтобы родительский элемент не останавливался после ребенок выходит, и родитель может затем возобновить управление с помощью tcsetpgrp (int, int)

...