Вход/Регистрация
Разработка приложений в среде Linux. Второе издание
вернуться

Троан Эрик В.

Шрифт:

В библиотеке

libutil
glibc предлагает две функции —
openpty
и
forkpty
, — выполняющие почти всю работу по поддержке псевдотерминалов.

#include <pty.h>

int openpty(int * masterfd, int * slavefd, char * name,

 struct termios * term, struct winsize * winp);

int forkpty(int * masterfd, char * name,

 struct termios * term, struct winsize * winp);

Функция

openpty
открывает ведущие и подчиненные псевдотерминалы, необязательно используя структуры
struct termios
и
struct winsize
, передаваемые как опции настройки псевдотерминала, возвращая
0
в случае успеха и
– 1
в случае ошибки. Файловые дескрипторы ведущего устройства и подчиненного компонента возвращаются аргументам
masterfd
и
slavefd
соответственно. Аргументы
term
и
winp
могут быть
NULL
, в случае чего они игнорируются, и настройка не выполняется.

Функция

forkpty
работает так же, как и
openpty
, но вместо возврата файлового дескриптора подчиненного компонента она разветвляет псевдотерминал как управляющий терминал stdin, stdout и stderr для дочернего процесса, а затем, подобно
fork
, возвращает идентификатор дочернего процесса родительскому и 0 дочернему либо -1 при возникновении ошибки.

Даже с этими удобными интерфейсами связана значительная проблема: аргумент name был изначально предназначен для возврата имени устройства псевдотерминала вызывающему коду, но его использование небезопасно, поскольку

openpty
и
forkpty
не знают размера буфера. Всегда передавайте
NULL
в аргументе
name
. Используйте функцию
ttyname
, описанную в начале этой главы, чтобы получить путевое имя файла устройства псевдотерминала.

Предпочтительный способ работы с

struct termios
заключается в использовании цикла чтение-модификация-запись, но данному случаю это не соответствует по двум причинам. Можно передать
NULL
и принять значения по умолчанию, что достаточно в большинстве случаев; а когда вы хотите предоставить настройки
termios
, вы часто заимствуете настройки у другого tty, или знаете точно, какими они должны быть (например, в случае концентратора последовательного порта SCSI, описанного ранее в этой главе).

tcgetattr(STDIN_FILENO, &term);

ioctl(STDIN_FILENO, TIOCGWINSZ, &ws);

pid = forkpty(&masterfd, NULL, &term, &ws);

16.6.3. Сложные способы открытия псевдотерминалов

Интерфейс Unix98 для распределения пары псевдотерминала представляет собой следующий набор функций.

#define _XOPEN_SOURCE 600

#include <stdlib.h>

#include <fcntl.h>

int posix_openpt(int oflag);

int grantpt(int fildes);

int unlockpt(int fildes);

char * ptsname(int fildes);

Функция

posix_openpt
— это то же, что и открытие устройства
/dev/ptmx
, но теоретически она более переносима (поскольку везде принимается). Рекомендуется в этот раз использовать
open("/dev/ptmx", oflag)
для максимальной практической переносимости. Если вы хотите установить один или два флага
open
или
posix_openpt
, используйте
O_RDWR
, как обычно; если вы вместо этого не открываете управляющий tty для процесса, используйте
O_RDWR | O_NOCTTY
.
open
или
posix_openpt
вернет открытый файловый дескриптор управляющему устройству псевдотерминала. Затем вызовите
grantpt
с файловым дескриптором управляющего устройства псевдотерминала, возвращенным из
posix_openpt
, для изменения режима и владельца подчиненного компонента псевдотерминала, а потом —
unlockpt
, чтобы сделать подчиненный компонент псевдотерминала доступным для открытия. Интерфейс Unix98 для открытия подчиненного устройства псевдотерминала должен просто открыть имя, возвращенное
ptsname
. Все эти функции возвращают
– 1
в случае ошибки, кроме
ptsname
, возвращающей в такой ситуации
NULL
.

Функции в

ptypair.c
распределяют согласованную пару устройств pty. Пример функции
get_master_pty
в строке 22
ptypair.с
открывает управляющее устройство pty и возвращает файловый дескриптор родительскому процессу, а также предоставляет имя соответствующему подчиненному компоненту pty. Он сначала испытывает интерфейс Unix98 на распределение управляющего устройства pty, а если это не работает (например, если ядро скомпилировано без поддержки pty Unix98, возможно, для встроенных систем), возвращается к старому интерфейсу стиля BSD. Соответствующая функция
get_slave_pty
в строке 87 может быть использована после
fork
для открытия соответствующего подчиненного компонента pty.

1: /* ptypair.c */

2:

3: #define _XOPEN_SOURCE 600

4: #include <errno.h>

5: #include <fcntl.h>

6: #include <grp.h>

7: #include <stdlib.h>

8: #include <string.h>

9: #include <sys/types.h>

 10: #include <sys/stat.h>

 11: #include <unistd.h>

  • Читать дальше
  • 1
  • ...
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: