23-31 Мы вызываем процедуру сервера и проверяем результат. Должен возвращаться только один дескриптор и никаких данных. Вскоре мы увидим, что сервер возвращает данные (сообщение об ошибке) только в том случае, если он не может открыть файл. В этом случае функция err_quit выводит сообщение об ошибке.
32-34 Дескриптор извлекается из структуры door_desc_t, и файл копируется в стандартный поток вывода.
В листинге 15.16 приведен текст процедуры сервера. Функция main по сравнению с листингом 15.3 не изменилась.
//doors/serverfd1.c
1 #include "unpipc.h"
2 void
3 servproc(void *cookie, char *dataptr, size_t datasize,
4 door_desc_t *descptr, size_t ndesc)
5 {
6 int fd;
7 char resbuf[BUFFSIZE];
8 door_desc_t desc;
9 dataptr[datasize-1] = 0; /* завершающий О */
10 if ((fd = open(dataptr, O_RDONLY)) == –1) {
11 /* ошибка, нужно сообщить клиенту */
12 snprintf(resbuf, BUFFSIZE, "%s: can't open, %s",
13 dataptr, strerror(errno));
14 Door_return(resbuf, strlen(resbuf), NULL, 0);
15 } else {
16 /* ОК, возвращаем дескриптор */
17 desc.d_data.d_desc.d_descriptor = fd;
18 desc.d_attributes = DOOR_DESCRIPTOR;
19 Door_return(NULL, 0, desc, 1);
20 }
21 }
9-14 Мы завершаем полное имя файла клиента нулем и делаем попытку открыть этот файл вызовом open. Если возникает ошибка, сообщение о ней возвращается клиенту.
15-20 Если файл был успешно открыт, клиенту возвращается только его дескриптор.
Запустим сервер и укажем ему имя двери /tmp/fd1, а затем запустим клиент:
solaris % clientfd1 /tmp/fd1
/etc/shadow
/etc/shadow: can't open. Permission denied
solaris % clientfd1 /tmp/fd1
/no/such/file
/no/such/file: can't open. No such file or directory
solaris % clientfd1 /tmp/fd1
/etc/ntp.conf
multicastclient 224.0.1.1
driftfile /etc/ntp.drift
В первых двух случаях мы указываем имя файла, приводящее к возврату сообщения об ошибке. В третий раз сервер передает клиенту дескриптор файла из двух строк, который благополучно выводится.