Чтение онлайн

ЖАНРЫ

Linux программирование в примерах
Шрифт:

envp
является окружением для использования новым процессом, с таким же форматом, как глобальная переменная
environ
(см. раздел 2.4 «Переменные окружения»). В новой программе это окружение становится начальным значением
environ
.

Программа не должна возвращаться из вызова

exec
. Если она возвращается, возникла проблема. Чаще всего либо не существует затребованная программа, либо она существует, но не является исполняемой (значения для
errno ENOENT
и
EACCESS
соответственно). Может быть множество других ошибок; см. справочную страницу execve(2).

В предположении, что вызов был успешным, текущее содержимое адресного пространства

процесса сбрасывается. (Ядро сначала сохраняет в безопасном месте данные
argv
и
envp
.) Ядро загружает для новой программы исполняемый код вместе со всеми глобальными и статическими переменными. Затем ядро инициализирует переменные окружения переданными
execve
данными, а далее вызывает процедуру
main
новой программы с переданным функции
execve
массивом
argv
. Подсчитывается число аргументов и это значение передается
main
в
argc
.

К этому моменту новая программа запущена. Она не знает (и не может определить), какая программа была в процессе до нее. Обратите внимание, что ID процесса не меняется. Многие другие атрибуты при вызове

exec
сохраняются; вскоре мы рассмотрим это более подробно.

exec
для процесса можно сравнить с ролями, которые играют в жизни люди. В различное время в течение дня один человек может быть родителем, супругом, другом, студентом или рабочим, покупателем в магазине и т.д. Это одна и та же личность, исполняющая различные роли. Также и процесс — его PID, открытые файлы, текущий каталог и т.п. — не изменяются, тогда как выполняемая работа - запущенная с помощью
exec
программа — может измениться.

9.1.4.2. Функции-оболочки:

execl
и др.

Пять дополнительных функций, действующих в качестве оболочек, предоставляют более удобные интерфейсы для

execve
. В первой группе все принимают список аргументов, каждый из которых передается в виде явного параметра функции:

int execl(const char *path, const char *arg, ...)

Первый аргумент,

path
, является путем к исполняемому файлу. Последующие аргументы, начиная с
arg
, являются отдельными элементами, которые должны быть помещены в
argv
. Как и ранее, явным образом должен быть включен
argv[0]
. Вы должны в качестве последнего аргумента передать завершающий указатель
NULL
, чтобы
execl
смогла определить, где заканчивается список аргументов. Новая программа наследует любые переменные окружения, которые находятся в переменной
environ
.

int execlp(const char *file, const char *arg, ...)

Эта функция подобна

execl
, но она имитирует механизм поиска команд оболочки, разыскивая
file
в каждом каталоге, указанном в переменной окружения
PATH
. Если
file
содержит символ
/
, этот поиск не осуществляется. Если
PATH
в окружении не присутствует,
execlp
использует путь по умолчанию. В GNU/Linux по умолчанию используется "
:/bin:/usr/bin
", но в других системах может быть другое значение. (Обратите внимание, что ведущее двоеточие в
PATH
означает, что сначала поиск осуществляется в текущем каталоге.)

Более того, если файл найден и имеет право доступа на исполнение, но не может быть исполнен из-за того, что неизвестен его формат,

execlp
считает, что это сценарий оболочки и запускает оболочку с именем файла в качестве аргумента.

int execle(const char *path, const char *arg, ...,

 char *const envp[])

Эта функция также подобна

execl
, но принимает дополнительный аргумент,
envp
,
который становится окружением новой программы. Как и в случае с
execl
, вы должны для завершения списка аргументов поместить перед
envp
указатель
NULL
.

Вторая группа функций-оболочек принимает массив в стиле

argv
:

int execv(const char *path, char *const argv[])

Эта функция подобна

execve
, но новая программа наследует любое окружение, которое находится в переменной environ текущей программы.

int execvp(const char *file, char *const argv[])

Эта функция подобна

execv
, но она осуществляет такой же поиск в
PATH
, как и функция
execlp
. Она также переходит на исполнение сценария оболочки, если найденный файл не может быть исполнен непосредственно.

В табл. 9.1 подведены итоги для шести функций

exec
.

Таблица 9.1. Сводка семейства функций

exec
по алфавиту

Функция Поиск пути Окружение пользователя Назначение
execl
Исполняет список аргументов.
execle
Исполняет список аргументов с окружением.
execlp
Исполняет список аргументов с поиском пути
execv
Исполняет с
argv
execve
Исполняет с
argv
и окружением (системный вызов).
execvp
Исполняет с
argv
и с поиском пути

Функций

execlp
и
execvp
лучше избегать, если вы не знаете, что переменная окружения
PATH
содержит приемлемый список каталогов.

9.1.4.3. Имена программ и

argv[0]

До сих пор мы все время считали

argv[0]
именем программы. Мы знаем, что оно может содержать, а может и не содержать символ
/
, в зависимости от способа вызова программы, если этот символ содержится, это хорошая подсказка к тому, что для вызова программы использовалось имя пути.

Однако, как должно быть ясно к этому времени, то, что

argv[0]
содержит имя файла, является лишь соглашением. Ничто не может воспрепятствовать передаче вами вызываемой программе в качестве
argv[0]
произвольной строки. Следующая программа,
ch09-run.c
, демонстрирует передачу произвольной строки:

1 /* ch09-run.c --- запуск программы с другим именем и любыми аргументами */

2

3 #include <stdio.h>

4 #include <errno.h>

5 #include <unistd.h>

6

7 /* main --- настроить argv и запустить указанную программу */

8

9 int main(int argc, char **argv)

10 {

11 char *path;

Поделиться с друзьями: