POPEN(3) | Руководство программиста Linux | POPEN(3) |
popen, pclose - конвейерный поток в или из процесса
#include <stdio.h>
FILE *popen(const char *command, const char *type);
int pclose(FILE *stream);
Требования макроса тестирования свойств для glibc (см. feature_test_macros(7)):
popen(), pclose():
Функция popen() открывает процесс следующим образом: создаёт канал, выполняет fork и вызывает командную оболочку. Так как канал задается однонаправленным, в аргументе type может быть задан один режим: либо чтение либо запись.
Аргумент command представляет собой указатель на строку с null в конце, которая содержит командную строку оболочки. Эта команда передаётся в /bin/sh с помощью флага -c; все подстановке в ней выполняются оболочкой.
Аргумент type представляет собой указатель на строку с null в конце, которая содержит или букву 'r' (чтение) или букву 'w' (запись). Начиная с glibc 2.9 в этом аргументе также может быть буква 'e', которая указывает на необходимость установки флага закрытия при выполнении (FD_CLOEXEC) в используемом файловом дескрипторе; про полезность флага O_CLOEXEC смотрите в open(2).
Возвращаемое popen() значение является стандартным потоком ввода-вывода, за исключением того, что его нужно закрывать с помощью pclose(), а не fclose(3). Запись в такой поток выполняет запись в стандартный поток ввода команды; стандартного потока вывода команды тот же, что и у процесса, вызвавшего popen(), если он не был изменён самой командой. При чтении из потока выполняется чтение из стандартного потока вывода команды, а стандартный поток ввода тот же, что и у процесса, вызвавшего popen(), если он не был изменён самой командой.
Заметим, что потоки вывода popen() по умолчанию блокируемые и буферизированные.
Функция pclose() ожидает завершения ассоциированного процесса и возвращает код выхода команды, возвращаемый функцией wait4(2).
popen(): при успешном выполнении возвращается указатель на открытый поток, его можно использовать для чтения или записи в канал; если вызов fork(2) или pipe(2) завершается с ошибкой или если функция не может выделить память, то возвращается NULL.
pclose(): при успешном выполнении возвращает код завершения команды; если wait4(2) возвращает ошибку или возникает какая-то другая ошибка, то возвращается -1.
Обе функции записывают в errno соответствующее значение ошибки.
Функция popen() не изменяет errno, если не удалось выделить память. Если завершаются с ошибкой вызовы fork(2) или pipe(2), то в errno содержится номер ошибки. Если значение type некорректно и это обнаружено, то errno присваивается EINVAL.
Если pclose() не удаётся получить код выхода потомка, то errno присваивается ECHILD.
Описание терминов данного раздела смотрите в attributes(7).
Интерфейс | Атрибут | Значение |
popen(), pclose() | Безвредность в нитях | MT-Safe |
POSIX.1-2001, POSIX.1-2008.
Значение 'e' для type есть только в Linux.
Примечание: внимательно прочитайте ЗАМЕЧАНИЯ в 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)
2017-09-15 | GNU |