Единственный способ запустить в Unix на выполнение какой-либо файл — вызвать функцию exec
. (Мы будем часто использовать общее выражение «функция exec
», когда неважно, какая из шести функций семейства exec
вызывается.) Функция exec
заменяет копию текущего процесса новым программным файлом, причем в новой программе обычно запускается функция main
. Идентификатор процесса при этом не изменяется. Процесс, вызывающий функцию exec
, мы будем называть вызывающим процессом , а выполняемую при этом программу — новой программой .
ПРИМЕЧАНИЕ
В старых описаниях и книгах новая программа ошибочно называется «новым процессом». Это неверно, поскольку новый процесс не создается.
Различие между шестью функциями exec
заключается в том, что они допускают различные способы задания аргументов:
■ выполняемый программный файл может быть задан или именем файла ( filename ), или полным именем ( pathname );
■ аргументы новой программы либо перечисляются один за другим, либо на них имеется ссылка через массив указателей;
■ новой программе либо передается окружение вызывающего процесса, либо задается новое окружение.
#include
int execl(const char * pathname , const char * arg0 , ... /* (char*)0 */ );
int execv(const char * pathname , char *const argv []);
int execle(const char * pathname , const char * arg0 ... /* (char*)0,
char *const envp [] */ );
int execve(const char * pathname , char *const argv [], char *const envp []);
int execlp(const char * filename , const char * arg0 , .... /* (char*)0 */ );
int execvp(const char * filename , char *const argv []);
Все шесть функций возвращают: -1 в случае ошибки, если же функция выполнена успешно, то ничего не возвращается
Эти функции возвращают вызывающему процессу значение -1, только если происходит ошибка. Иначе управление передается в начало новой программы, обычно функции main
.
Отношения между этими шестью функциями показаны на рис. 4.4. Обычно только функция execve
является системным вызовом внутри ядра, а остальные представляют собой библиотечные функции, вызывающие execve
.
Рис. 4.4. Отношения между шестью функциями exec
Отметим различия между этими функциями:
1. Три верхних функции (см. рис. 4.4) принимают каждую строку как отдельный аргумент, причем перечень аргументов завершается пустым указателем (так как их количество может быть различным). У трех нижних функций имеется массив argv
, содержащий указатели на строки. Этот массив должен содержать пустой указатель, определяющий конец массива, поскольку размер массива не задается.
2. Две функции в левой колонке получают аргумент filename
. Он преобразуется в pathname
с использованием текущей переменной окружения PATH
. Если аргумент filename
функций execlp
или execvp
содержит косую черту ( /
) в любом месте строки, переменная PATH
не используется. Четыре функции в двух правых колонках получают полностью определенный аргумент pathname
.
3. Четыре функции в двух левых колонках не получают явного списка переменных окружения. Вместо этого с помощью текущего значения внешней переменной environ
создается список переменных окружения, который передается новой программе. Две функции в правой колонке получают точный список переменных окружения. Массив указателей envp
должен быть завершен пустым указателем.
Дескрипторы, открытые в процессе перед вызовом функции exec
, обычно остаются открытыми во время ее выполнения. Мы говорим «обычно», поскольку это свойство может быть отключено при использовании функции fcntl
для установки флага дескриптора FD_CLOEXEC
. Это нужно серверу inetd
, о котором пойдет речь в разделе 13.5.
4.8. Параллельные серверы
Сервер, представленный в листинге 4.2, является последовательным (итеративным) сервером . Для такого простого сервера, как сервер времени и даты, это допустимо. Но когда обработка запроса клиента занимает больше времени, мы не можем связывать один сервер с одним клиентом, поскольку нам хотелось бы обрабатывать множество клиентов одновременно. Простейшим способом написать параллельный сервер под Unix является вызов функции fork
, порождающей дочерний процесс для каждого клиента. В листинге 4.3 представлена общая схема типичного параллельного сервера.
Читать дальше
Конец ознакомительного отрывка
Купить книгу