Теория и практика программирования на Си в Unix

       

Использование


Системные вызовы, позволяющие программировать средства STREAMS, аналогичны обращениям, управляющим файлами.
- Открытие Stream open () Открывается специальный файл. При возврате получают дескриптор, используемый для операций со Stream, выделенным ядром.
- Считывание и запись read (), write (), putmsg (), getmsg () Два последних вызова характерны для STREAMS и позволяют управлять контрольной информацией одновременно с данными. Кроме того, функции putmsg () и getmsg () открыто манипулируют данными, структурированными в сообщения, в отличие от read () и write (), работающих только с байтами.
- Контрольные операции ioctl () Этот вызов позволяет, в частности, ввести модуль в Stream (опция I_PUSH) или вывести модуль из Stream (опция I_POP). В случае транспортного соединения, построенного на Stream интерфейсом TLI, можно ввести модуль tirdwr, позволяющий использовать функции read () и write () для считывания или записи в точке доступа транспортной службы (см. пример раздела 5.3.5). Этот примитив позволяет также определить модули в Stream (опция I_LOOK).

ПРОГРАММА 42 /* получение списка модулей Stream */ #include "tli.h" main() { char name[] ="/dev/tcp"; int tfd; char filename[FMNAMESZ + 1]; /* FMNAMESZ определяется в <sys/conf.h> */ struct t_info info; /* создание точки входа в транспортный уровень */ tfd = t_open(name, O_RDWR, &info); /* поиск и вывод на экран списка модулей Stream */ for (;;) { ioct1(tfd, I_LOOK, filename);

printf(" module = %s\n", filename); ioct1(tfd, I_POP, (char *) 0);

} fflush(stdout); } /* полученный результат */ module = timod

- Одновременное ожидание на нескольких дескрипторах вво- да-вывода
Системный вызов poll () позволяет организовать состояние ожидания событий на нескольких дескрипторах Streams. Этот примитив блокирует программу до получения одного из ожидаемых событий или до истечения временной задержки. Пример использования показан в гл. 1.
- Мультиплексорный модуль
Один из модулей может принимать данные из нескольких источников (мультиплексорный модуль), благодаря функции ioctl () c опцией I_LINK. Таким образом, можно, например, обладать несколькими драйверами - надстройками над уровнем IP (рис. 5.7.).




ПРОГРАММА 43 /* мультиплексная работа модуля IP с тремя драйверами : Token ring, Ethernet и Х25 **********************/

/* *******************/ #include <stdio.h> #include <fcntl.h> #include <sys/conf.h> #include <stropts.h> main() { int fd_ip, fd_ether, fd_token, fd_x25, fd_tp; /* создание точек входа в транспортный уровень */ fd_ip = open("/dev/ip", O_RDWR); fd_ether = open("/dev/ether", O_RDWR); fd_token = open("/dev/token", O_RDWR); fd_x25 = open("/dev/x25", O_RDWR); /* связывание IP с драйверами */ ioct1(fd_ip, I_LINK, fd_ether); ioct1(fd_ip, I_LINK, fd_token);

ioct1(fd_ip, I_LINK, fd_x25); /* связывание транспортного уровня с IP */ fd_tp = open("/dev/tip", O_RDWR); ioct1(fd_tp, I_LINK, fd_ip); /* затем надо с помощью fork создать демона */ switch (fork()) { case 0 : break ; /* порожденный процесс */ case -1 : err_sys("fork echoue"); default: exit(0) ; /* отец оставляет сына */ } /* надо закрыть дескрипторы */ close(fd_ip); close(fd_ether); close(fd_token);

close(fd_x25); /* демон ждет */ pause(); }

Существует определенное число системных вызовов и макросов STREAMS, позволяющих конструировать модули Stream (putq, putbq, getq...).




Содержание раздела