На разницу между этими функциями указывают последние буквы их названий. Различия между ними собраны в табл. 27.1 и подробно описаны в следующем списке.

• Большинство функций семейства exec() ожидают получить путь к программе, которую нужно загрузить. Но execlp() и execvp() позволяют указать лишь имя файла. В этом случае файл ищется в каталогах из списка, заданного в переменной среды PATH (подробнее о ней читайте ниже). Такой же поиск выполняется командной оболочкой, когда в нее вводят название команды. Чтобы обозначить эту особенность, имена этих функций содержат букву p (от PATH). Переменная PATH игнорируется, если в имени файла присутствует слеш (/): в этом случае имя воспринимается как относительный или абсолютный путь.

• Вместо того чтобы передавать новой программе список аргументов argv в виде массива, функции execle(), execlp() и execl() используют для этого список. Первый из этих аргументов соответствует элементу argv[0] в функции main() новой программы и, следовательно, совпадает с аргументом filename или последней частью аргумента pathname. В конце списка аргументов должен находиться нулевой указатель, чтобы данные вызовы могли определить конец (в прототипах, приведенных выше, это требование обозначено закомментированным (char *) NULL). Чтобы отличить данные функции от тех, что передают список аргументов в виде массива с NULL в конце, их имена содержат букву l (от list — «список»). Функции, которые применяют для этой цели массив (execve(), execvp() и execv()), обозначены буквой v (от vector — «вектор»).

• Функции execve() и execle() позволяют программисту явно задать переменные среды для новой программы, используя аргумент envp — массив указателей на символьные строки, который заканчивается значением NULL. Чтобы обозначить этот факт, имена данных функций заканчиваются буквой e (от environment — «среда»). Остальные функции семейства exec() применяют для новой программы среду вызывающего процесса (то есть содержимое глобальной переменной environ).

В библиотеке glibc версии 2.11 появилась нестандартная функция execvpe(file, argv, envp). Она похожа на execvp(), но вместо того, чтобы наследовать переменные среды для новой программы из environ, она принимает их в виде аргумента envp (по аналогии с execve() и execle()).

На следующих нескольких страницах будут демонстрироваться примеры использования этих разновидностей вызова exec().

Таблица 27.1. Краткое перечисление различий между разными функциями вида exec()

Функция — Задание программного файла (-, p) — Задание аргументов (v, l) — Источник переменных среды (e, — )

execve() — pathname — Массив — Аргумент envp

execle() — pathname — Список — Аргумент envp

execlp() — filename + PATH — Список — environ вызывающего процесса

execvp() — filename + PATH — Массив — environ вызывающего процесса

execv() — pathname — Массив — environ вызывающего процесса

execl() — pathname — Список — environ вызывающего процесса

27.2.1. Переменная среды PATH

Функции execvp() и execlp() позволяют нам указать только имя файла, который нужно выполнить. Для его поиска они используют переменную среды PATH. Значение PATH представляет собой строку с именами каталогов (префиксы путей), которые разделяются двоеточиями. Например, в следующем значении PATH содержится пять каталогов:

$ echo $PATH

/home/mtk/bin:/usr/local/bin:/usr/bin:/bin:.

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

Пути, заданные в PATH, могут быть либо абсолютными (если начинаются со знака /), либо относительными. Относительный путь интерпретируется с учетом текущего каталога вызывающего процесса. Текущий каталог можно задать с помощью символа. (точка), как в вышеприведенном примере.

Текущий каталог в переменной PATH можно также задать в виде префикса нулевой длины — двух двоеточий подряд или начального/завершающего двоеточия (например, /usr/bin:/bin:). В стандарте SUSv3 такой подход считается устаревшим; текущий каталог следует указывать явно с помощью символа. (точка).

Если переменная PATH не определена, функции execvp() и execlp() по умолчанию используют список путей вида.:/usr/bin:/bin.

Перейти на страницу:

Похожие книги