Читать книгу 📗 "Linux программирование в примерах - Роббинс Арнольд"
9.4.3.5. Сводка fcntl()
Сводка для системного вызова
fcntl()Таблица 9.5. Сводка
fcntl()Значение cmd | Значение arg | Возвращает |
|---|---|---|
F_DUPFD | Наименьший новый дескриптор | Дублирует аргумент fd |
F_GETFD | Получает флаги дескриптора файла (close-on-exec) | |
F_SETFD | Новое значение флага | Устанавливает флаги дескриптора файла (close-on-exec) |
F_GETFL | Получает флаги основного файла | |
F_SETFL | Новое значение флага | Устанавливает флаги основного файла |
Флаги создания, статуса и прав доступа файла копируются, когда дескриптор файла дублируется. Флаг close-on-exec не копируется.
9.5. Пример: двусторонние каналы в
gawkДвусторонний канал соединяет два процесса двунаправленным образом. Обычно, по крайней мере для одного из процессов, на канал с другим процессом настраиваются как стандартный ввод, так и стандартный вывод. Оболочка Корна (
ksh<i>команды и аргументы движка базы данных</i> |& /* Запустить сопроцесс в фоновом режиме */print -p "команда базы данных" /* Записать в сопроцесс */read -p db_response /* Прочесть из сопроцесса */Здесь движок базы данных представляет любую серверную программу, которая может управляться интерфейсной частью, в данном случае, сценарием
ksh
Рис. 9.7. Сопроцессы оболочки Корна
В обычном
awkawkgawk|&kshawkprint "<i>команда</i>" |& "<i>движок базы данных</i>" /* Запустить сопроцесс, записать в него */"<i>движок базы данных</i>" |& getline db_response /* Прочесть из сопроцесса */gawk|&io.cgawktwo_way_open()1561 static int1562 two_way_open(const char *str, struct redirect *rp)1563 { ...1827 /* случай 3: двусторонний канал с порожденным процессом */1828 {1829 int ptoc[2], сtop[2];1830 int pid;1831 int save_errno;18351836 if (pipe(ptoc) < 0)1837 return FALSE; /* установлен errno, диагностика от вызывающего */18381839 if (pipe(ctop) < 0) {1840 save_errno = errno;1841 close(ptoc[0]);1842 close(ptoc[1]);1843 errno = save_errno;1844 return FALSE;1845 }Первым шагом является создание двух каналов,
ptocctopСтроки 1836–1837 создают первый канал,
ptocsave_errnoerrnopipe()close()errno1906 if ((pid = fork()) < 0) {1907 save_errno = errno;1908 close(ptoc[0]); close(ptoc[1]);1909 close(ctop[0]); close(ctop[1]);1910 errno = save_errno;