Читаем Linux API. Исчерпывающее руководство полностью

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

#define _XOPEN_SOURCE 500

#include

char *ptsname(int mfd);

Возвращает указатель на (возможно, статически выделенную) строку при успешном завершении или NULL при ошибке

Библиотека GNU языка C предоставляет реентерабельную версию вызова ptsname() в виде ptsname_r(mfd, strbuf, buflen). Однако данная функция является нестандартной и доступна лишь в нескольких UNIX-системах. Чтобы получить объявление ptsname_r() из заголовочного файла , необходимо определить макрос проверки возможностей _GNU_SOURCE.

Разблокировав вторичное устройство с помощью функции unlockpt(), можно его открыть, воспользовавшись традиционным системным вызовом open().

60.3. Открытие первичного устройства: вызов ptyMasterOpen()

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

• большинство программ выполняют описанные действия точно таким же образом, так что для удобства их можно объединить в единую функцию;

• наша версия ptyMasterOpen() инкапсулирует все подробности и особенности псевдотерминалов стандарта UNIX 98.

#include "pty_master_open.h"

int ptyMasterOpen(char *slaveName, size_t snLen);

Возвращает файловый дескриптор при успешном завершении или -1 при ошибке

Функция ptyMasterOpen() открывает неиспользуемый первичный конец псевдотерминала, вызывает для него grantpt() и unlockpt() и копирует имя связанного с ним вторичного устройства в буфер, на который указывает аргумент slaveName. Вызывающий процесс должен указать в аргументе snLen количество памяти, доступной этому буферу. Реализация данной функции показана в листинге 60.1.

Листинг 60.1. Реализация функции ptyMasterOpen()

pty/pty_master_open.c

#define _XOPEN_SOURCE 600

#include

#include

#include "pty_master_open.h" /* Объявляет ptyMasterOpen() */

#include "tlpi_hdr.h"

int

ptyMasterOpen(char *slaveName, size_t snLen)

{

int masterFd, savedErrno;

char *p;

masterFd = posix_openpt(O_RDWR | O_NOCTTY);

/* Открываем первичный pty */

if (masterFd == -1)

return -1;

if (grantpt(masterFd) == -1) { /* Разрешаем доступ ко вторичному pty */

savedErrno = errno;

close(masterFd); /* Может изменить 'errno' */

errno = savedErrno;

return -1;

}

if (unlockpt(masterFd) == -1) { /* Разблокируем вторичный pty */

savedErrno = errno;

close(masterFd); /* Может изменить 'errno' */

errno = savedErrno;

return -1;

}

p = ptsname(masterFd); /* Получаем имя вторичного pty */

if (p == NULL) {

savedErrno = errno;

close(masterFd); /* Может изменить 'errno' */

errno = savedErrno;

return -1;

}

if (strlen(p) < snLen) {

strncpy(slaveName, p, snLen);

} else { /* Возвращаем ошибку, если буфер слишком маленький */

close(masterFd);

errno = EOVERFLOW;

return -1;

}

return masterFd;

}

pty/pty_master_open.c

Точно так же мы могли бы отказаться от применения аргументов slaveName и snLen, давая вызывающему процессу возможность самостоятельно получить имя вторичного устройства псевдотерминала с помощью вызова ptsname(). Мы этого не сделали, поскольку в системе BSD псевдотерминалы не имеют аналога функции ptsname().

60.4. Соединение процессов с помощью псевдотерминала: вызов ptyFork()

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

#include "pty_fork.h"

pid_t ptyFork(int *masterFd, char *slaveName, size_t snLen,

const struct termios *slaveTermios,

const struct winsize *slaveWS);

В родителе: возвращает идентификатор потомка при успешном завершении или -1 при ошибке; в успешно созданном потомке: всегда возвращает 0

Реализация функции ptyFork() показана в листинге 60.2. Рассмотрим работу функции.

1. Открывает первичное устройство псевдотерминала с помощью функции ptyMasterOpen() (листинг 60.1) .

2. Если аргумент slaveName равен NULL, то копирует имя вторичного устройства в буфер . В противном случае slaveName должен указывать на буфер размером как минимум snLen байт. При необходимости вызывающий процесс может использовать данное имя для обновления учетных файлов (см. главу 40). Это может пригодиться в приложениях, которые обеспечивают вход в систему, например ssh, rlogin и telnet. С другой стороны, такие программы, как script(1) (см. раздел 60.6), не обновляют учетные файлы, поскольку не предоставляют возможность входа в систему.

3. Делает вызов fork() с целью создать дочерний процесс .

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных