16.1.2. Управляющие терминалы

We use cookies. Read the Privacy and Cookie Policy

16.1.2. Управляющие терминалы

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

Нормальные процессы не могут менять свои управляющие терминалы; это может делать только лидер сеанса. В Linux изменение управляющего терминала лидера сеанса не распространяется на другие процессы того же сеанса. Лидеры сеансов почти всегда устанавливают управляющий терминал при запуске до создания каких-либо дочерних процессов, чтобы гарантировать, что все процессы сеанса совместно используют один управляющий терминал.

Существуют два интерфейса для смены управляющего tty лидера сеанса. Первый реализуется с помощью нормальных системных вызовов open() и close().

1. Закройте все файловые дескрипторы, относящиеся к текущему управляющему терминалу.

2. Откройте новый терминал без установки флага O_NOCTTY.

Второй метод включает вызовы ioctl() на отдельных файловых дескрипторах, ссылающихся на старые и новые терминалы.

1. Установите флаг TIOCNOTTY на файловый дескриптор, привязанный к исходному управляющему tty (обычно ioctl(0, TIOCNOTTY, NULL) нормально работает). Это разрывает соединение между сеансом и tty.

2. Установите флаг TIOCSCTTY на файловый дескриптор, привязанный к новому управляющему tty. Это устанавливает новый управляющий tty.

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

Функция tcsetpgrp() позволяет процессу, работающему на терминале, сменить группу процессов переднего плана для этого терминала[108].

int tcsetpgrp(int ttyfd, pid_t pgrp);

Первый параметр определяет tty, управляющая группа процессов которого изменяется, a pgrp является группой процессов, которую необходимо переместить на передний план. Процессы могут менять группу процессов переднего плана только для своего управляющего терминала. Если процесс, совершающий изменение, не принадлежит к группе процессов переднего плана на этом терминале, генерируется сигнал SIGTTOU, если только он не игнорируется или заблокирован[109].