system(3) выполняет команду оболочки (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)

СООТВЕТСТВИЕ СТАНДАРТАМ

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