Поле di_target содержит идентификатор процесса сервера, a di_proc — адрес процедуры сервера в процессе (от которого клиенту, вообще говоря, пользы мало). Указатель, передаваемый процедуре сервера в качестве первого аргумента
Текущие атрибуты двери помещаются в поле di_attributes, и два из них уже были описаны в разделе 15.3. Это атрибуты DOOR_PRIVATE и DOOR_UNREF. Два других атрибута называются DOOR_LOCAL (процедура является локальной для данного процесса) и DOOR_REVOKE (сервер аннулировал процедуру, связанную с этой дверью, вызвав door_revoke).
Каждой двери при создании сопоставляется уникальный в пределах системы номер, который возвращается в поле di_uniquifier.
Эта функция обычно вызывается клиентом для получения информации о сервере. Однако она может быть вызвана и из процедуры сервера, причем первым аргументом в этом случае должна быть константа DOOR_QUERY. Тогда функция возвратит информацию о вызвавшем потоке, то есть о данном экземпляре процедуры сервера. В этом случае адреса процедуры сервера и принимаемых аргументов (di_proc и di_data) могут представлять интерес.
15.7. Примеры
В этом разделе мы приведем примеры использования пяти только что описанных функций.
Функция door_info
В листинге 15.3 приведен текст программы, открывающей дверь и вызывающей door_infо для получения информации об этой двери, которая затем выводится на экран.
//doors/doorinfo.c
1 #include "unpipc.h"
2 int
3 main(int argc, char **argv)
4 {
5 int fd;
6 struct stat stat;
7 struct door_info info;
8 if (argc != 2)
9 err_quit("usage; doorinfo
10 fd = Open(argv[1], O_RDONLY);
11 Fstat(fd, &stat);
12 if (S_ISDOOR(stat.st_mode) == 0)
13 err_quit("pathname is not a door");
14 Door_info(fd, &info);
15 printf("server PID = %ld, uniquifier = %ld",
16 (long)info.di_target, (long)info.di_uniquifier);
17 if (info.di_attributes & DOOR_LOCAL)
18 printf(", DOOR_LOCAL");
19 if (info.di_attributes & DOOR_PRIVATE)
20 printf(", DOOR_PRIVATE");
21 if (info.di_attributes & DOOR_REVOKED)
22 printf(", DOOR_REVOKED");
23 if (info.di_attributes & DOOR_UNREF)
24 printf(", DOOR_UNREF");
25 printf("\n");
26 exit(0);
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, uniquifier = 18, DOOR_UNREF
solaris % doorinfo /etc/.syslog_door
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.
//doors/client2.c
1 #include "unpipc.h"
2 int
3 main(int argc, char **argv)
4 {
5 int fd;
6 long ival, oval;
7 door_arg_t arg;
8 if (argc != 3)