SYSTEM(3)

ИМЯ
system - выполняет команду оболочки (shell)

ОБЗОР
#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)

СООТВЕТСТВИЕ СТАНДАРТАМ
C89, C99, POSIX.1-2001.

ЗАМЕЧАНИЯ
Функция 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(); в этом случае нельзя понять, что невозможно выполнить оболочку в процессе-потомке.

СМОТРИТЕ ТАКЖЕ
sh(1), sigaction(2), sigprocmask(2), fork(2), wait(2), exec(3), signal(7)