Читать «UNIX: взаимодействие процессов» онлайн - страница 245
Уильям Ричард Стивенс
Первый файл в этом примере называется squareproc.h. В нем определен один тип данных для входных аргументов функции, возводящей в квадрат, и еще один — для возвращаемых ею результатов. В этом заголовочном файле также определяется полное имя двери для данной процедуры. Его текст его приведен в листинге 15.8.
Листинг 15.8. Заголовочный файл squareproc.h
//doors/squareproc.h
1 #define PATH_SQUARE_DOOR "/tmp/squareproc_door"
2 typedef struct { /* аргументы squareproc() */
3 long arg1;
4 } squareproc_in_t;
5 typedef struct { /* возврат squareproc() */
6 long res1;
7 } squareproc_out_t;
Наша новая процедура будет принимать длинное целое и возвращать квадратный корень из него (типа double). Мы определяем полное имя двери этой процедуры, структуры аргументов и результатов в заголовочном файле sqrtproc.h в листинге 15.9.
Листинг 15.9. Заголовочный файл sqrtproc.h
//doors/sqrtproc.h
1 #define PATH_SQRT_DOOR "/tmp/sqrtproc_door"
2 typedef struct { /* входные данные sqrtproc() */
3 long arg1;
4 } sqrtproc_in_t;
5 typedef struct { /* возвращаемые sqrtproc() данные */
6 double res1;
7 } sqrtproc_out_t;
Программа-клиент приведена в листинге 15.10. Она последовательно вызывает две процедуры сервера и выводит возвращаемые ими результаты. Эта программа устроена аналогично другим клиентским программам, приведенным в этой главе.
Листинг 15.10. Клиент, вызывающий две процедуры
//doors/client7.c
1 #include "unpipc.h"
2 #include "squareproc.h"
3 #include "sqrtproc.h"
4 int
5 main(int argc, char **argv)
6 {
7 int fdsquare, fdsqrt;
8 door_arg_t arg;
9 squareproc_in_t square_in;
10 squareproc_out_t square_out;
11 sqrtproc_in_t sqrt_in;
12 sqrtproc_out_t sqrt_out;
13 if (argc != 2)
14 err_quit("usage: client7 <integer-value>");
15 fdsquare = Open(PATH_SQUARE_DOOR, O_ROWR);
16 fdsqrt = Open(PATH_SQRT_DOOR, O_RDWR);
17 /* подготовка аргументов и вызов squareproc() */
18 square_in.arg1 = atol(argv[1]);
19 arg.data_ptr = (char*)&square_in;
20 arg.data_size = sizeof(square_in);
21 arg.desc_ptr = NULL;
22 arg.desc_num = 0;
23 arg.rbuf = (char*)&square_out;
24 arg.rsize = sizeof(square_out);
25 Door_call(fdsquare, &arg);
26 /* подготовка аргументов и вызов sqrtproc() */
27 sqrt_in.arg1 = atol(argv[1]);
28 arg.data_ptr = (char*)&sqrt_in;
29 arg.data_size = sizeof(sqrt_in);
30 arg.desc_ptr = NULL;
31 arg.desc_num = 0;
32 arg.rbuf = (char*)&sqrt_out;
33 arg.rsize = sizeof(sqrt_out);
34 Door_call(fdsqrt, &arg);
35 printf("result: %ld %g\n", square_out.res1, sqrt_out.res1);
36 exit(0);
37 }
Текст двух серверных процедур приведен в листинге 15.11. Каждая из них выводит текущий идентификатор потока и значение аргумента, делает 5-секунд-ную паузу, вычисляет результат и завершает работу.
Листинг 15.11. Две процедуры сервера
//doors/server7.c
1 #include "unpipc.h"
2 #include <math.h>
3 #include "squareproc.h"
4 #include "sqrtproc.h"
5 void
6 squareproc(void *cookie, char *dataptr, size_t datasize,