popen, pclose -
конвейерный
поток в или
из
процесса
Standard C library (
libc,
-lc)
#include <stdio.h>
FILE *popen(const char *command, const char *type);
int pclose(FILE *stream);
popen(),
pclose():
_POSIX_C_SOURCE >= 2
|| /* glibc <= 2.19: */ _BSD_SOURCE || _SVID_SOURCE
Функция
popen()
открывает
процесс
следующим
образом:
создаёт
канал,
выполняет fork
и вызывает
командную
оболочку.
Так как
канал
задается
однонаправленным,
в
аргументе
type может
быть задан
один режим:
либо
чтение
либо
запись.
Аргумент
command
представляет
собой
указатель
на строку с
null в конце,
которая
содержит
командную
строку
оболочки.
Эта
команда
передаётся
в
/bin/sh с
помощью
флага
-c; все
подстановке
в ней
выполняются
оболочкой.
The
type argument is a pointer to a null-terminated string which must
contain either the letter 'r' for reading or the letter 'w' for writing. Since
glibc 2.9, this argument can additionally include the letter 'e', which causes
the close-on-exec flag (
FD_CLOEXEC) to be set on the underlying file
descriptor; see the description of the
O_CLOEXEC flag in
open(2)
for reasons why this may be useful.
Возвращаемое
popen()
значение
является
стандартным
потоком
ввода-вывода,
за
исключением
того, что
его нужно
закрывать
с помощью
pclose(), а не
fclose(3).
Запись в
такой
поток
выполняет
запись в
стандартный
поток
ввода
команды;
стандартного
потока
вывода
команды
тот же, что и
у процесса,
вызвавшего
popen(), если он
не был
изменён
самой
командой.
При чтении
из потока
выполняется
чтение из
стандартного
потока
вывода
команды, а
стандартный
поток
ввода тот
же, что и у
процесса,
вызвавшего
popen(), если он
не был
изменён
самой
командой.
Заметим,
что потоки
вывода
popen()
по
умолчанию
блокируемые
и
буферизированные.
Функция
pclose()
ожидает
завершения
ассоциированного
процесса и
возвращает
код выхода
команды,
возвращаемый
функцией
wait4(2).
popen(): при
успешном
выполнении
возвращается
указатель
на
открытый
поток, его
можно
использовать
для чтения
или записи
в канал;
если вызов
fork(2) или
pipe(2)
завершается
с ошибкой
или если
функция не
может
выделить
память, то
возвращается
NULL.
pclose(): при
успешном
выполнении
возвращает
код
завершения
команды;
если
wait4(2)
возвращает
ошибку или
возникает
какая-то
другая
ошибка, то
возвращается
-1.
On failure, both functions set
errno to indicate the error.
The
popen() function does not set
errno if memory allocation
fails. If the underlying
fork(2) or
pipe(2) fails,
errno
is set to indicate the error. If the
type argument is invalid, and this
condition is detected,
errno is set to
EINVAL.
Если
pclose() не
удаётся
получить
код выхода
потомка, то
errno
присваивается
ECHILD.
Описание
терминов
данного
раздела
смотрите в
attributes(7).
Интерфейс |
Атрибут |
Значение |
popen(), pclose() |
Безвредность
в нитях |
MT-Safe |
POSIX.1-2001, POSIX.1-2008.
The 'e' value for
type is a Linux extension.
Примечание:
внимательно
прочитайте
ЗАМЕЧАНИЯ
в
system(3).
Так как
смещение
поиска у
открытого
для чтения
стандартного
ввода
команды
доступным
процессу,
вызвавшему
popen(), и
исходный
процесс
выполнял
буферное
чтение, то
позиция
ввода
команды
может быть
не той, что
ожидается.
Подобным
образом,
вывод из
команды,
открытой
на запись,
может
будет
спутан с
выводом из
исходного
процесса.
Последнего
можно
избежать,
если
вызывать
fflush(3) перед
popen().
Ошибка при
попытке
запуска
оболочки
неотличима
от ошибки
оболочки
при
попытке
запуска
программы
или от
ошибки при
немедленном
выходе
команды.
Единственное
отличие
это код
выхода 127.
sh(1),
fork(2),
pipe(2),
wait4(2),
fclose(3),
fflush(3),
fopen(3),
stdio(3),
system(3)
Русский
перевод
этой
страницы
руководства
был сделан
Alexey, Azamat Hackimov <
[email protected]>, kogamatranslator49
<
[email protected]>, Kogan, Max Is <
[email protected]>, Yuri
Kozlov <
[email protected]> и Иван
Павлов <
[email protected]>
Этот
перевод
является
бесплатной
документацией;
прочитайте
Стандартную
общественную
лицензию GNU
версии 3
или более
позднюю,
чтобы
узнать об
условиях
авторского
права. Мы не
несем
НИКАКОЙ
ОТВЕТСТВЕННОСТИ.
Если вы
обнаружите
ошибки в
переводе
этой
страницы
руководства,
пожалуйста,
отправьте
электронное
письмо на
[email protected]