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

Стивенс Уильям Ричард

Шрифт:
EV_EOF Достигнут конец файла • EV_ERROR Произошла ошибка, код errno записан в поле data •

Типы фильтров приведены в табл. 14.6.

Таблица 14.6. Типы фильтров

Значение filter Описание
EVFILT_AIO События асинхронного ввода-вывода
EVFILT_PROC События exit, fork, exec для процесса
EVFILT_READ Дескриптор готов для чтения (аналогично select)
EVFILT_SIGNAL Описание сигнала
EVFILT_TIMER Периодические или одноразовые таймеры
EVFILT_VNODE Изменение и удаление файлов
EVFILT_WRITE Дескриптор готов для записи (аналогично select)

Перепишем функцию

str_cli
из листинга 6.2 так, чтобы она использовала
kqueue
. Результат представлен в листинге 14.8.

Листинг 14.8. Функция str_cli, использующая kqueue

//advio/str_cli_kqueue04.c

1 #include "unp.h"

2 void

3 str_cli(FILE *fp, int sockfd)

4 {

5 int kq, i, n, nev, stdineof = 0, isfile;

6 char buf[MAXLINE];

7 struct kevent kev[2];

8 struct timespec ts;

9 struct stat st;

10 isfile = ((fstat(fileno(fp), &st) 0) &&

11 (st.st_mode & S_IFMT) == S_IFREG);

12 EV_SET(&kev[0], fileno(fp), EVFILT_READ, EV_ADD, 0, 0, NULL);

13 EV_SET(&kev[1], sockfd, EVFILT_READ, EV_ADD, 0, 0, NULL);

14 kq = Kqueue;

15 ts.tv_sec = ts.tv_nsec = 0;

16 Kevent(kq, kev, 2, NULL, 0, &ts);

17 for (;;) {

18 nev = Kevent(kq, NULL, 0, kev, 2, NULL);

19 for (i = 0; i < nev; i++) {

20 if (kev[i].ident == sockfd) { /* сокет готов для чтения */

21 if ((n = Read(sockfd, buf, MAXLINE)) == 0) {

22 if (stdineof == 1)

23 return; /* нормальное завершение*/

24 else

25 err_quit("str_cli: server terminated prematurely");

26 }

27 Write(fileno(stdout), buf, n);

28 }

29 if (kev[i].ident == fileno(fp)) { /* входной поток готов к чтению */

30 n = Read(fileno(fp), buf, MAXLINE);

31 if (n > 0)

32 Writen(sockfd, buf, n);

33 if (n == 0 || (isfile && n == kev[i].data)) {

34 stdineof = 1;

35 Shutdown(sockfd, SHUT_WR); /* отправка FIN */

36 kev[i].flags = EV_DELETE;

37 Kevent(kq, &kev[i], 1, NULL, 0, &ts); /* удаление

kevent */

38 continue;

39 }

40 }

41 }

42 }

43 }

Проверка, указывает ли дескриптор на файл

10-11
Поведение
kqueue
при достижении конца файла зависит от того, связан ли данный дескриптор с файлом, каналом или терминалом, поэтому мы вызываем
fstat
, чтобы убедиться, что мы работаем с файлом. Эти сведения понадобятся позже.

  • Читать дальше
  • 1
  • ...
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • ...

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

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

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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