Отправка процесса в фоновый режим и возврат управления в мою оболочку

Я программирую оболочку для своего класса CS, и часть проекта включает в себя запуск процесса в фоновом режиме, если символ "&" передается пользователем.

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

Я должен звонить tcsetpgrp после execvp если это фоновый процесс? Если да, могу ли я получить pid моей оболочки, просто позвонив getpid?

3 ответа

tcsetpgrp() работает над группами процессов, а не отдельными процессами. Что вы хотите сделать, это:

  1. Когда вы создаете новый конвейер, звоните setpgid() поместить все элементы конвейера в новую группу процессов (с идентификатором PID первого процесса в конвейере в качестве PGID). (Конвейер - это последовательность процессов, запускаемых вашей оболочкой, когда она видит запрос вроде ls | grep foo | wc -l - самый простой конвейер имеет только один процесс). Обычно вы бы позвонили setpgid(0, 0) от первого процесса в конвейере, до вызова exec(),

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

  3. Когда оболочка находится в фоновом режиме, она должна использовать блокировку waitpid() вызов, чтобы дождаться завершения дочернего процесса, а не показывать подсказку. После завершения каждого процесса в конвейере переднего плана он должен снова вернуться на передний план (и показать подсказку).

  4. Когда оболочка находится на переднем плане, она должна вызвать waitpid() с WNOHANG а также WUNTRACED флажки для проверки состояния дочерних процессов непосредственно перед тем, как вы показываете приглашение - это сообщит вам, когда они остановились или вышли, и позволит вам проинформировать пользователя.

Вы должны взглянуть на fork, чтобы создать дочерний процесс. Затем используйте exec в ребенке выполнить нужную команду.

Если ваша оболочка запускает процесс, используя & чтобы справиться с этим, $! Переменная shell будет содержать PID дочернего процесса. Вы можете отправить сигналы этому процессу или использовать wait $! ждать его завершения.

Другие вопросы по тегам