10.4.3. Запуск новых программ

10.4.3. Запуск новых программ

Хотя доступно целых шесть способов запустить одну программу из другой, все они делают почти одно и то же — заменяют текущую выполняющуюся программу другой программой. Обратите внимание на слово "заменяет" — все следы текущей выполняющейся программы при этом исчезают. Если вы хотите оставить исходную программу работающей, вы должны создать новый процесс вызовом fork(), а затем запустить новую программу из дочернего процесса.

Эти шесть функций лишь слегка отличаются по интерфейсу. Только одна из них — execve() — является системным вызовом Linux. Остальные реализованы в библиотеках пользовательского пространства и вызывают execve() для запуска новой программы. Ниже представлены прототипы семейства функций exec().

int execl(const char *path, const char *arg0, ...);

int execlp(const char *file, const char *arg0, ...);

int execle(const char *path, const char *arg0, ...);

int execv(const char *path, const char **argv);

int execvp(const char *file, const char **argv);

int execve(const char *file, const char **argv, const char **envp);

Как уже упоминалось, все эти программы пытаются заменить текущую программу новой. Если это удается, то управление не возвращается (то есть программа, которая вызвала другую программу, уже не выполняется). Если не удается, то возвращается значение -1 и устанавливается код ошибки в errno, как при любом другом системном вызове. Когда новая программа запускается, она принимает массив аргументов (argv) и массив переменных окружения (envp). Каждый элемент envp имеет форму ПЕРЕМЕННАЯ=значение[22].

Основная разница между функциями семейства exec() состоит в том, как новой программе передаются аргументы командной строки. Функции execl() передают каждый элемент в отдельном аргументе argv, причем список завершается NULL. Традиционно первый элемент argv — это команда, использованная для запуска программы. Например, команда оболочки /bin/cat /etc/passwd /etc/group обычно получается в результате следующей вызова exec:

execl("/bin/cat", "/bin/cat", "/etc/passwd", "/etc/group", NULL);

Первый аргумент — это полный путь к программе, которую требуется выполнить, а остальные аргументы передаются программе в виде argv. Заключительный параметр execl() должен быть равен NULL — это служит признаком конца списка параметров. Если вы пропустите NULL, то, скорее всего, функция завершится ошибкой сегментации либо вернет EINVAL. Окружение, переданное новой программе — это то, на что указывает глобальная переменная environ, как упоминалось ранее в настоящей главе.

Функциям execv аргументы командной строки передаются как массив С строк[23], имеющих тот же формат, что применяется для передачи argv новой программе.

Последним элементом должен быть NULL для обозначения конца массива, а первый элемент (argv[0]) должен содержать имя вызываемой программы.

Наш пример с bin/cat /etc/passwd /etc/group может быть закодирован, используя execv, следующим образом:

char *argv[] = { "/bin/cat", "/bin/cat", "/etc/passwd", "/etc/group", NULL }; execv("/bin/cat", argv);

Если нужно передать специфическое окружение новой программе, для этого подойдут execle() и execve(). Они в точности похожи на execl() и execv(), но принимают указатель на окружение в качестве последнего аргумента. Окружение устанавливается так же, как argv.

Например, ниже показан один способ запуска /usr/bin/env (эта программа печатает окружение, которое ей передано) с небольшим набором переменных окружения:

char *newenv[] = { "PATH=/bin:/usr/bin", "HOME=/home/sweethome", NULL };

execle("/usr/bin/env", "/usr/bin/env", NULL, newenv);

Вот та же идея, реализованная с помощью execve():

char *argv[] = { "/usr/bin/env", NULL };

char *newenv[] = { "PATH=/bin:/usr/bin", "HOME=/home/sweethome", NULL };

execve("/usr/bin/env", argv, newenv);

Последние две функции, execlp() и execvp(), отличаются от первых двух тем, что выполняют поиск программы, которую нужно запустить, в текущем пути (установленном переменной окружения PATH). Аргументы программы, однако, не модифицируются, поэтому argv[0] не содержит полного пути к запускаемой программе. Ниже показана модифицированная версия нашего первого примера, который ищет cat в текущем PATH.

execlp("cat", "cat", "/etc/passwd", "/etc/group", NULL);

char *argv[] = { "cat", "/etc/passwd", "/etc/group", NULL };

execvp("cat", argv);

Если вместо этого воспользоваться execl() или execv(), этот фрагмент кода завершится ошибкой, если только cat не окажется в текущем каталоге.

Если вы пытаетесь запустить программу со специфическим окружением, при этом желая выполнять поиск пути, вам придется искать путь вручную и использовать execle() или execve(), поскольку ни одна из функций exec() не делает того, что вам нужно.

Обработчики сигналов предохраняются внутри функций exec() несколько неочевидным образом. Этот механизм рассматривается в главе 12.

Поделитесь на страничке

Следующая глава >

Похожие главы из других книг:

Запуск программ

Из книги автора

Запуск программ Существует несколько способов запуска приложений. Все они, за исключением одного, использовались и в предыдущих версиях Windows. Новый вариант – запуск программ с использованием строки поиска меню Пуск. Зная название программы, достаточно набрать в строке


Установка новых программ

Из книги автора

Установка новых программ Но какими бы потрясающими талантами ни обладала Vista, и сколько бы крутых программ ни хранило в себе ее увесистое брюхо, их нам все равно будет мало. А значит, мы будем искать, покупать, скачивать превеликое множество других программ, каждую из


4.2.2. Запуск программ и переключение между ними

Из книги автора

4.2.2. Запуск программ и переключение между ними В общем случае запустить программу или приложение на выполнение можно несколькими способами:? Щелкнуть мышкой по значку программы на панели (если таковой имеется).? Щелкнуть мышкой по соответствующему значку рабочего стола


Установка новых программ

Из книги автора

Установка новых программ Но какими бы потрясающими талантами ни обладала Vista, и сколько бы крутых программ ни хранило в себе ее увесистое брюхо, их нам все равно будет мало. А значит, мы будем искать, покупать, скачивать превеликое множество других программ, каждую из


Запуск программ до и после установки

Из книги автора

Запуск программ до и после установки Расширенные INF-файлы поддерживают такую возможность, как запуск команд перед установкой INF-файла или после нее. При этом для указания блока, описывающего программы, запускаемые перед установкой INF-файла, используется ключевое слово


Запрещение/Разрешения на запуск программ

Из книги автора

Запрещение/Разрешения на запуск программ Запрещение запуска программWindows позволяет ограничить доступ к программам, кроме разрешенных в специальном списке.Для ограничения запускаемых программ надо открыть раздел HKCUSOFTWAREMicrosoftWindowsCurrentVersonPoliciesExplorerи создать там ключ


Быстрый запуск программ

Из книги автора

Быстрый запуск программ Может быть, диалоговое окно Макрос работает и идеально правильно, но оно так неэффективно! Ведь когда требуется что-то выполнить, обычно это нужно немедленно, КТО захочет открывать диалоговое окно, искать в длинном списке приведенных MCIKHV шрифтом


Автоматический запуск VBA-программ

Из книги автора

Автоматический запуск VBA-программ Предположим, что у вас есть VBA-программа, которую вы любите настолько, что хотели бы видеть ее в действии самой первой каждый раз, когда запускаете свое приложение. А если вы любите свою программу так сильно, что и такую, казалось бы,


14.1. Запуск внешних программ

Из книги автора

14.1. Запуск внешних программ Никакой язык не может использоваться в качестве «клея», если он не позволяет запускать внешние программы. В Ruby для этого есть несколько способов.Не могу не обмолвиться о том, что перед запуском внешней программы неплохо бы понять, что она


Создание новых языков

Из книги автора

Создание новых языков Хотя мы и говорим об XML, как о формате описания данных, на самом деле XML — это метаязык, язык, который описывает другие языки. Строго говоря, когда мы создаем XML-документ, мы создаем его не на XML, а в соответствии с XML-синтаксисом. XML — это всего лишь набор


Запуск native-программ

Из книги автора

Запуск native-программ Ветвь реестра HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSession Manager включает в себя параметр BootExecute, имеющий тип REG_MULTI_SZ. Данный параметр должен содержать названия лишь специальных программ, называемых native-программами. Они работают только с функциями Native API, большинство


Быстрый запуск программ

Из книги автора

Быстрый запуск программ Среднестатистический пользователь компьютера применяет в повседневной работе не менее 20–30 различных приложений. Быстро запустить необходимую программу стандартными средствами Microsoft Windows невозможно. Выручают в таком случае специальные