Основы программирования в Linux
Часть 204 из 324 Информация о книге
<b>#include <unistd.h></b><b>char **environ;</b><b>int execl(const char *path, const char *arg0, ..., (char *)0);</b><b>int execlp(const char *file, const char *arg0, ..., (char *)0);</b><b>int execle(const char *path, const char *arg0, ..., (char *)0,</b><b> char *const envp[]);</b><b>int execv(const char *path, char *const argv[]);</b><b>int execvp(const char *file, char *const argv[]);</b><b>int execve(const char *path, char *const argv[], char *const envp[]);</b>Эти функции делятся на два вида.
,execlиexeclpпринимают переменное число аргументов, заканчивающихся указателемexecle. Уnullиexecvвторой аргумент — массив строк. В обоих случаях новая программа стартует с заданными аргументами, представленными в массивеexecvp, передаваемом функцииargv.mainЭти функции реализованы, как правило, с использованием
, хотя нет обязательных требований на этот счет.execveФункции, имена которых содержат суффикс
, отличаются тем, что ищут переменную окруженияpдля определения исполняемого файла новой программы. Если эта переменная не позволяет найти нужный файл, необходимо передать функции как параметр абсолютное имя файла, включающее каталоги.PATHПередать значение окружению программы может глобальная переменная
. Другой вариант — дополнительный аргумент в функцияхenvironиexecle, способный передавать строки, используемые как окружение новой программы.execveЕсли вы хотите применить функцию
для запуска программыexec, можно выбирать любую функцию из семействаps, как показано в вызовах приведенного далее фрагмента программного кода:exec#include <unistd.h>/* Пример списка аргументов *//* Учтите, что для argv[0] необходимо имя программы */char *const ps_argv[] = {"ps", "ax", 0};/* He слишком полезный пример окружения */char *const ps_envp[] = {"PATH=/bin:/usr/bin", "TERM=console", 0};/* Возможные вызовы функций exec */execl("/bin/ps", "ps", "ax", 0);/* предполагается, что ps в /bin */execlp("ps", "ps", "ax", 0);/* предполагается, что /bin в PATH */execle("/bin/ps", "ps", "ax", 0, ps_envp);/* передается свое окружение */execv("/bin/ps", ps_argv);execvp("ps", ps_argv);execve("/bin/ps", ps_argv, ps_envp);А теперь выполните упражнение 11.2.
Упражнение 11.2. ФункцияexeclpДавайте изменим пример и используем вызов
:execlp#include <unistd.h>#include <stdio.h>#include <stdlib.h>int main() {<i> printf("Running ps with execlp\n");</i><i> execlp("ps", "ps", "ax", 0);</i>printf("Done.\n");exit(0);}Когда вы выполните эту программу, рехес.с, то получите обычный вывод команды
, но без сообщенияps. Кроме того, обратите внимание на то, что в выводе нет процесса с именемDone:рехес$ <b>./рехес</b>Running ps with execlpPID TTY STAT TIME COMMAND1 ? S 0:03 init [5]...1262 pts/1 Ss 0:00 /bin/bash1273 pts/2 S 0:00 su -1274 pts/2 S+ 0:00 -bash1463 pts/1 SN 0:00 oclock1465 pts/1 S 0:01 emacs Makefile1514 pts/1 R+ 0:00 ps axКак это работает
Программа выводит первое сообщение и затем вызывает функцию
, которая ищет каталоги, заданные в переменной окруженияexeclpдля обнаружения программыPATH. Далее она выполняет команду вместо программыps, запустив ее так, как будто вы ввели команду командной оболочкирехес$ <b>ps ax</b>Когда
завершается, вы получаете новую строку приглашения командной оболочки. Возврата в программуpsне происходит, поэтому второе сообщение не выводится. PID нового процесса тот же, что и у исходного, то же самое можно сказать о PID родительского процесса и значениирехес. В сущности, происходит следующее: выполняющаяся программа запустила на выполнение новый код и новый исполняемый файл, заданный в вызове функцииnice.execСуществует ограничение для общего размера списка аргументов и окружения процесса, запускаемого функциями
. Оно задается в переменнойexecи в системах Linux равно 128 Кбайт. В других системах может задаваться меньший предельный размер, что способно порождать проблемы. Стандарт POSIX гласит, чтоARG_MAXдолжна быть не менее 4096 байтов.ARG_MAX