Главная страница Взаимодействие нетривиальных процессов finclude <door.h> int door return(char *dataptr. size t datasize. door desc t *descptr. size t ndesc): I* Ничего не возвращает вызвавшему процессу в случае успешного завершения, -1 - в случае ошибки */ Возвращаемые данные задаются аргументами dataptr и datasize, а возвращаемые дескрипторы - descptr и ndesc. 15.5. Функция door cred Интерфейс дверей предусматривает полезную возможность получения информации о клиенте при каждом вызове. Это осуществляется функцией door cred: finclude <door.h> int door cred(door cred t *cred): I* Возвращает 0 в случае успешного завершения, -1 - в случае ошибки */ Структура, на которую указывает аргумент cred, имеет тип door cred t, определяемый как 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. Функция doorjnfo Только что описанная функция door cred предоставляет серверу информацию о клиенте. Клиент же может получить информацию о сервере, вызвав doorjnfo: finclude <door.h> int door info(int fd. door info t *info): I* Возвращает 0 в случае успешного завершения, -1 - в случае ошибки */ Дескриптор fd указывает на открытую дверь. Структура типа door inf o t, на которую указывает info, после возвращения из функции содержит информацию о сервере: typedef struct door lnfo { pid t di target; /* идентификатор процесса сервера */ door ptr t di proc; /* процедура сервера */ door ptr t d1 data: /* принимаемые процедурой сервера данные */ door attr t di attributes: /* атрибуты, связанные с данной дверью */ door id t di uniquifier: /* уникальный номер двери */ } door info t: Поле di t3i get содержит идентификатор процесса сервера, а di proc - адрес процедуры сервера в процессе (от которого клиенту, вообще говоря, пользы мало). Указатель, передаваемый процедуре сервера в качестве первого аргумента (cookie), возвращается клиенту в поле di data. Текущие атрибуты двери помещаются в поле di attri butes, и два из них уже были описаны в разделе 15.3. Это атрибуты DOOR PRI VATE и DOOR UNREF. Два других атрибута называются DOOR LOCAL (процедура является локальной для данного процесса) и DOOR REVOKE (сервер аннулировал процедуру, связанную с этой дверью, вызвав door revoke). Каждой двери при создании сопоставляется уникальный в пределах системы номер, который возвращается в поле di uniquif ier. Эта функция обычно вызывается клиентом для получения информации о сервере. Однако она может быть вызвана и из процедуры сервера, причем первым аргументом в этом случае должна быть константа DOOR QUERY. Тогда функция возвратит информацию о вызвавшем потоке, то есть о данном экземпляре процедуры сервера, В этом случае адреса процедуры сервера и принимаемых аргументов (di proc и di data) могут представлять интерес, 15.7. Примеры В этом разделе мы приведем примеры использования пяти только что описанных функций. Функция doorjnfo В листинге 15.3 приведен текст программы, открывающей дверь и вызывающей door i nf о для получения информации об этой двери, которая затем выводится на экран. Листинг 15.3. Вывод информации о двери doors/doorinfo.c 1 finclude unpipc.h 2 int 3 ttiainCint argc, char **argv) 5 int fd; 6 struct stat stat: 7 struct doorjnfo info; 8 if (argc != 2) 9 err quit( usage: doorinfo <pathnattie> ): 10 fd = Open(argv[l], 0 RDONLY); 11 Fstat(fd, &stat): 12 if (SJSD(ЮR(stat.st Itюde) == 0) 13 err quit( pathnattie is not a door ); 14 DoorJnfo(fd. &info); 15 printf( server PID = ld, uniquifier = ld , 16 (long) info.d1 target, (long) info.di uniqu1fier); 17 if (info.di attributes & D0OR L0CAL) 18 printfC. DOOR LOCAL ): 19 if (info.di attributes & DOOR PRIVATE) 20 printfC . DOOR PRIVATE ); 21 if (info.d1 attributes & DOOR REVOKED) 22 printfC. DOOR REVOKED ); 23 if (info.d1 attr1butes & DOOR UNREF) 24 printfC, DOOR UNREF ): 25 printfCNn ): 26 exitCO); 27 } Сначала программа открывает файл с указанным полным именем и проверяет, что это действительно дверь, Поле st mode структуры stat в этом случае должно содержать такое значение, что макрос S ISDOOR будет возвращать значение истина . Затем вызывается функция door info. Сначала мы укажем этой программе полное имя файла, не являющегося дверью, а затем попробуем получить информацию о двух встроенных дверях Solaris 2.6: Solaris % doorinfo /etc/passwd pathname is not a door Solaris % doorinfo /etc/.name service door server PID = 308. uniqui tier = 18. DOOR UNREF Solaris % doorinfo /etc/.syslogdoor server PID - 282, uniquifier = 1635 Solaris % ps -f -p 308 root 308 1 0 Apr 01 ? 0:34 /usr/sbin/nscd Solaris % ps -f -p 282 root 282 1 0 Apr 01 ? 0;10 /usr/sbin/syslogd -n -z 14 Команду ps мы используем для того, чтобы узнать, какая программа выполняется с идентификатором, возвращаемым door info. Буфер результатов слишком мал Когда мы рассказывали о функции door call, мы отметили, что если буфер результатов оказывается слишком мал, библиотека дверей осуществляет автоматическое выделение нового буфера. Сейчас мы покажем это на примере, В листинге 15,4 приведен текст новой программьышиента, которая представляет собой измененную версию листинга 15.2, Листинг 15.4. Вывод адреса полученного результата doors/client2.c 1 finclude unpipc.h 2 int 3 mainCint argc, char **argv) 5 int fd: 6 long ival, oval: 7 door arg t arg:
|
© 2000 - 2024 ULTRASONEX-AMFODENT.RU.
Копирование материалов разрешено исключительно при условии цититирования. |