ОБЗОР
#include <stdlib.h>
int system(const char *command);
ОПИСАНИЕ
В библиотечной функции system() используется fork(2) для создания процесса-потомка, в котором посредством execl(3) запускается команда оболочки, указанная в command:
execl("/bin/sh", "sh", "-c", command, (char *) 0);
Функция system() возвращает результат после завершения работы команды.
На время выполнения команды SIGCHLD блокируется, а SIGINT и SIGQUIT игнорируются в процессе, который вызвал system() (эти сигналы будут обработаны их действиями по умолчанию внутри процесса-потомка, который выполняет command).
Если значение command равно NULL, то system() возвращает состояние, показывающее доступна ли оболочка в системе.
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
Возвращаемым значением system() может быть одно из:- *
- Если значение command равно NULL, то возвращается ненулевое значение, если оболочка присутствует в системе, или 0, если оболочка недоступна.
- *
- Если процесс-потомок не может быть создан или его состояние невозможно вернуть, то возвращается значение -1.
- *
- Если оболочка не может выполниться в процессе-потомке, то возвращается значение будет таким же как если бы оболочка-потомок завершилась вызовом _exit(2) с состоянием 127.
- *
- Если все системные вызовы выполнены без ошибок, то возвращается значение состояния завершения процесса-потомка, использовавшегося для выполнения command (состояние завершения оболочки — это состояние завершения последней выполнявшейся команды).
В последних двух случаях возвращаемое значение — это «состояние ожидания», которое можно определить с помощью макроса описанного в waitpid(2) (т. е., WIFEXITED(), WEXITSTATUS() и т. п.).
Функция system() не отражает состояние ожидание других потомков.
АТРИБУТЫ
Описание терминов данного раздела смотрите в attributes(7).Интерфейс | Атрибут | Значение |
system() | безвредность в нитях | безвредно (MT-Safe) |
СООТВЕТСТВИЕ СТАНДАРТАМ
POSIX.1-2001, POSIX.1-2008, C89, C99.ЗАМЕЧАНИЯ
Функция system() проста и удобна: она позаботится обо всём для вызовов fork(2), execl(3) и waitpid(2), а также необходимых действиях с сигналами; также оболочка выполнит обычные подстановки и перенаправления ввода-вывода command. Но system() не эффективна: для создания процесса требуются дополнительные системные вызовы, которые запускают оболочку и выполняют команду.Если определён макрос тестирования свойств _XOPEN_SOURCE (до включения всех заголовочных файлов), то при включении <stdlib.h> становятся доступны макросы, описанные в waitpid(2) (WEXITSTATUS() и т. п.).
Как уже упоминалось, функция system() игнорирует SIGINT и
SIGQUIT. Это может привести к тому, что программы вызывающие её из цикла
станут не прерываемыми, пока сами не проверят условия выхода для своих
дочерних процессов. Пример:
while (что-то) { int ret = system("foo"); if (WIFSIGNALED(ret) && (WTERMSIG(ret) == SIGINT || WTERMSIG(ret) == SIGQUIT)) break; }
Не используйте system() в программах с привилегиями set-user-ID или set-group-ID, потому что некоторые странные значения переменных окружения могут нарушить целостность системы. Вместо неё рекомендуется использование семейства функций exec(3), кроме execlp(3) или execvp(3). Фактически, функция system() неправильно работает из программ с привилегиями set-user-ID или set-group-ID в системах, где /bin/sh — это bash версии 2, так как bash 2 сбрасывает права при запуске (в Debian используется изменённый bash, который этого не делает, если оболочка вызывается как sh).
В версиях glibc до 2.1.3 проверка доступности /bin/sh в действительности не выполнялась, если значение command равно NULL; вместо этого всегда предполагалось наличие, и в этом случае system() всегда возвращала 1. Начиная с glibc 2.1.3, эта проверка выполняется, так как несмотря на требование POSIX.1-2001 a conforming implementation to provide a shell, that shell may not be available or executable if the calling program has previously called chroot(2) (which is not specified by POSIX.1-2001).
Существует вероятность, что команда оболочки возвратит значение 127, которое также является и возвращаемым значением самой system(); в этом случае нельзя понять, что невозможно выполнить оболочку в процессе-потомке.