Главная страница  Взаимодействие нетривиальных процессов 

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 [ 122 ] 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186

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:



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 [ 122 ] 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186

© 2000 - 2024 ULTRASONEX-AMFODENT.RU.
Копирование материалов разрешено исключительно при условии цититирования.