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;