Чтение онлайн

на главную - закладки

Жанры

Linux программирование в примерах

Роббинс Арнольд

Шрифт:

1911 return FALSE;

1912 }

Строки 1906–1912 порождают процесс, на этот раз закрывая оба канала, если

fork
потерпит неудачу. Здесь также первоначальное значение
errno
сохраняется и восстанавливается для последующего использования при диагностике.

1914 if (pid == 0) { /* порожденный процесс */

1915 if (close(1) == -1)

1916 fatal(_("close of stdout in child failed (%s)"),

1917 strerror(errno));

1918 if (dup(ctop[1]) != 1)

1919 fatal(_{"moving pipe to stdout in child failed (dup: %s)"), strerror(errno));

1920 if (close(0) == -1)

1921 fatal(_("close of stdin in child failed (%s)"),

1922 strerror(errno));

1923 if (dup(ptoc[0]) != 0)

1924 fatal(_("moving pipe to stdin in child failed (dup: %s)"), strerror(errno));

1925 if (close(ptoc[0]) == -1 || close(ptoc[1]) == -1

1926 || close(ctop[0]) == -1 || close(ctop[1]) == -1)

1927 fatal(_("close of pipe failed (%s)"), strerror(errno));

1928 /* stderr HE дублируется в stdout потомка */

1929 execl("/bin/sh", "sh", "-c", str, NULL);

1930 _exit(errno == ENOENT ? 127 : 126);

1931 }

Строки 1914–1931 обрабатывают код потомка, с соответствующей проверкой ошибок и сообщениями на каждом шагу. Строка 1915 закрывает стандартный вывод. Строка 1918 копирует записываемый конец канала от потомка к родителю на 1. Строка 1920 закрывает стандартный ввод, а строка 1923 копирует читаемый конец канала от родителя к потомку на 0. Если это все работает, стандартные ввод и вывод теперь на месте и подключены к родителю.

Строки 1925–1926 закрывают все четыре первоначальные дескрипторы файлов каналов, поскольку они больше не нужны. Строка 1928 напоминает нам, что стандартная ошибка остается на месте. Это лучшее решение, поскольку пользователь увидит ошибки от сопроцесса. Программа

awk
, которая должна перехватить стандартную ошибку, может использовать в команде обозначение '
2>&1
' для перенаправления стандартной ошибки сопроцесса или записи в отдельный файл.

Наконец, строки 1929–1930 пытаются запустить для оболочки

execl
и соответственно выходят, если это не удается.

1934 /* родитель */

1935 rp->pid = pid;

1936 rp->iop = iop_alloc(ctop[0], str, NULL);

1937 if (rp->iop == NULL) {

1938 (void)close(ctop[0]);

1939 (void)close(ctop[1]);

1940 (void)close(ptoc[0]);

1941 (void)close(ptoc[1]);

1942 (void)kill(pid, SIGKILL); /* overkill? (pardon pun) */

1943

1944 return FALSE;

1945 }

Первым шагом родителя является настройка входного конца от сопроцесса. Указатель

rp
указывает на
struct redirect
, которая содержит поле для сохранения PID порожденного процесса,
FILE*
для вывода и указатель
IOBUF*
с именем
iop
.
IOBUF
является внутренней структурой данных
gawk
для осуществления ввода. Она, в свою очередь, хранит копию нижележащего дескриптора файла.

Строка 1935 сохраняет значение ID процесса. Строка 1936 выделяет память для новой

IOBUF
для данных дескриптора файла и командной строки. Третий аргумент здесь равен
NULL
: он позволяет при необходимости использовать предварительно выделенный
IOBUF
.

Если выделение памяти потерпело неудачу, строки 1937–1942 производят очистку, закрывая каналы и посылая сигнал «kill» порожденным процессам, чтобы заставить их завершить работу. (Функция

kill
описана в разделе 10.6.7 «Отправка сигналов
kill
и
killpg
».)

1946 rp->fp = fdopen(ptoc[1], "w");

1947 if (rp->fp == NULL) {

1948 iop_close(rp->iop);

1949 rp->iop = NULL;

1950 (void)close(ctop[0]);

1951 (void)close(ctop[1]);

1952 (void)close(ptoc[0]);

1953 (void)close(ptoc[1]);

1954 (void)kill(pid, SIGKILL); /* избыточно? (пардон, каламбур)
[104]
*/

104

Игра слов kill-overkill (избыточно — overkill) — Примеч. перев.

1955

1956 return FALSE;

1957 }

Строки 1946–1957 аналогичны. Они устанавливают вывод родителя на потомка, сохраняя дескриптор файла для записывающего конца канала от родителя к потомку в

FILE*
, используя функцию
fdopen
. Если это завершается неудачей, строки 1947–1957 предпринимают те же действия, что и ранее: закрывают все дескрипторы каналов и посылают сигнал порожденным процессам.

С этого момента записываемый конец канала от родителя к потомку и читаемый конец канала от потомка к родителю хранятся в более крупных структурах:

FILE*
и
IOBUF
соответственно. Они автоматически закрываются обычными процедурами, которые закрывают эти структуры. Однако, остаются две задачи:

1960 os_close_on_exec(ctop[0], str, "pipe", "from");

1961 os_close_on_exec(ptoc[1], str, "pipe", "from");

1962

1963 (void)close(ptoc[0]);

1964 (void)close(ctop[1]);

1966

1967 return TRUE;

1968 }

...

1977 }

Строки 1960–1961 устанавливают флаг close-on-exec для двух дескрипторов, которые остались открытыми.

os_close_on_exec
является простой функцией-оболочкой, которая выполняет эту работу на Unix- и POSIX-совместимых системах, но ничего не делает на системах, в которых нет флага close-on-exec. Это скрывает проблему переносимости в одном месте и позволяет избежать в коде множества запутывающих
#ifdef
здесь и в других местах
io.c
.

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

Вперед в прошлое 8

Ратманов Денис
8. Вперед в прошлое
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Вперед в прошлое 8

Эволюционер из трущоб. Том 4

Панарин Антон
4. Эволюционер из трущоб
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Эволюционер из трущоб. Том 4

Барон. Книга вторая

Первухин Андрей Евгеньевич
6. Ученик
Фантастика:
фэнтези
попаданцы
5.40
рейтинг книги
Барон. Книга вторая

Ботаник 2

Щепетнов Евгений Владимирович
2. Ботаник
Фантастика:
фэнтези
боевая фантастика
6.00
рейтинг книги
Ботаник 2

Последний Герой. Том 4

Дамиров Рафаэль
Последний герой
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Последний Герой. Том 4

Вперед в прошлое 5

Ратманов Денис
5. Вперед в прошлое
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Вперед в прошлое 5

Кодекс Крови. Книга II

Борзых М.
2. РОС: Кодекс Крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга II

Товарищ "Чума" 9

lanpirot
9. Товарищ "Чума"
Фантастика:
городское фэнтези
попаданцы
альтернативная история
5.00
рейтинг книги
Товарищ Чума 9

Черный рынок

Вайс Александр
6. Фронтир
Фантастика:
боевая фантастика
космическая фантастика
космоопера
5.00
рейтинг книги
Черный рынок

"Дальние горизонты. Дух". Компиляция. Книги 1-25

Усманов Хайдарали
Собрание сочинений
Фантастика:
фэнтези
боевая фантастика
попаданцы
5.00
рейтинг книги
Дальние горизонты. Дух. Компиляция. Книги 1-25

Бастард Императора. Том 15

Орлов Андрей Юрьевич
15. Бастард Императора
Фантастика:
городское фэнтези
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Бастард Императора. Том 15

Наследник

Назимов Константин Геннадьевич
3. Травник
Фантастика:
фэнтези
6.80
рейтинг книги
Наследник

Кодекс Охотника. Книга X

Винокуров Юрий
10. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
6.25
рейтинг книги
Кодекс Охотника. Книга X

Матабар III

Клеванский Кирилл Сергеевич
3. Матабар
Фантастика:
фэнтези
5.00
рейтинг книги
Матабар III