ПРИМЕЧАНИЕ
Если мы учтем, что дверь идентифицируется с помощью PID и адреса процедуры сервера (что мы узнаем из структуры door_info_t в разделе 15.6), ограничения на вызовы exec и fork станут понятны. Дочерний процесс не будет принимать вызовов, поскольку его идентификатор процесса отличается от идентификатора, связанного с дверью. Дескриптор должен быть закрыт при вызове exec, потому что хотя идентификатор при этом и не меняется, адрес процедуры сервера уже не будет иметь никакого смысла в той программе, которая будет запущена после вызова exec.
15.4. Функция door_return
После завершения работы процедуры сервера возврат из нее осуществляется вызовом door_return. Это приводит к возврату из door_call соответствующего клиента.
#include
int door_return(char
/* Ничего не возвращает вызвавшему процессу в случае успешного завершения. –1 – в случае ошибки */
Возвращаемые данные задаются аргументами
15.5. Функция door_cred
Интерфейс дверей предусматривает полезную возможность получения информации о клиенте при каждом вызове. Это осуществляется функцией door_cred:
#include
int door_cred(door_cred_t
/* Возвращает 0 в случае успешного завершения, –1 – в случае ошибки */
Структура, на которую указывает аргумент
typedef struct door_cred {
uid_t dc_euid; /* действующий идентификатор пользователя клиента */
gid_t dc_egid; /* действующий идентификатор группы клиента */
uid_t dc_ruid; /* реальный идентификатор пользователя клиента */
gid_t dc_rgid; /* реальный идентификатор группы клиента */
pid_t dc_pid; /* идентификатор процесса клиента */
} door_cred_t;
В эту структуру помещается информация о клиенте при возвращении из вызова door_cred. В разделе 4.4 [21] подробно рассказывается о различиях между действующими и реальными идентификаторами пользователя и группы, а пример использования этой функции приведен в листинге. 15.5.
Обратите внимание, что эта функция не принимает никаких дескрипторов. Она возвращает информацию о клиенте, осуществившем конкретный вызов через дверь, и поэтому должна вызываться из процедуры сервера или другой функции, вызываемой из процедуры сервера.
15.6. Функция door_info
Только что описанная функция door_cred предоставляет серверу информацию о клиенте. Клиент же может получить информацию о сервере, вызвав doo_info:
#include
int door_info(int
/* Возвращает 0 в случае успешного завершения, –1 – в случае ошибки */
Дескриптор
typedef struct doo_info {
pid_t di_target; /* идентификатор процесса сервера */
door_ptr_t di_proc; /* процедура сервера */
door_ptr_t di_data; /* принимаемые процедурой сервера данные */
door_attr_t di_attributes; /* атрибуты, связанные с данной дверью */
door_id_t di_uniquifier; /* уникальный номер двери */
} door info t;