Разработка приложений в среде Linux. Второе издание
Шрифт:
Получение файлового дескриптора происходит аналогично. Необходимо выделить достаточное пространство буфера для управляющего сообщения, и каждая приходящая структура
struct cmsghdr
будет сопровождаться новым файловым дескриптором. Для иллюстрации использования таких вложенных структур мы написали пример программы, которая по нашей прихоти названа просто
cat
. Она принимает имя файла в качестве единственного аргумента, открывает указанный файл в дочернем процессе и передает результирующий файловый дескриптор в родительский процесс через сокет домена Unix.
1: /* passfd.с */
2:
3: /* Программа ведет себя подобно обычной команде /bin/cat, которая обрабатывает
4: только один аргумент (имя файла). Мы создаем сокеты домена Unix при помощи
5: socketpair, затем разветвляем через fork. Дочерний процесс открывает файл,
6: имя которого передается в командной строке, пересылает файловый дескриптор и
7: имя файла обратно в порождающий процесс, после этого завершается. Родительский
8: процесс ожидает файловый дескриптор от дочернего процесса, а потом копирует
9: данные из файлового дескриптора в stdout до тех пор, пока данные не
10: заканчиваются. Затем родительский процесс завершается. */
11:
12: #include <alloca.h>
13: #include <fcntl.h>
14: #include <stdio.h>
15: #include <string.h>
16: #include <sys/socket.h>
17: #include <sys/uio.h>
18: #include <sys/un.h>
19: #include <sys/wait.h>
20: #include <unistd.h>
21:
22: #include "sockutil.h" /* простые служебные функции */
23:
24: /* Дочерний процесс. Он пересылает файловый дескриптор. */
25: int childProcess(char * filename, int sock) {
26: int fd;
27: struct iovec vector; /* некоторые данные для передачи fd в w/ */
28: struct msghdr msg; /* полное сообщение */
29: struct cmsghdr * cmsg; /* управляющее сообщение, которое */
30: /* включает в себя fd */
31:
32: /* Открыть файл, дескриптор которого будет передан. */
33: if ((fd = open(filename, O_RDONLY)) < 0) {
34: perror("open");
35: return 1;
36: }
37:
38: /*
Передать имя файла через сокет, включая завершающий
39: символ '\0' */
40: vector.iov_base = filename;
41: vector.iov_len = strlen(filename) + 1;
42:
43: /* Соединить первую часть сообщения. Включить
44: имя файла iovec */
45: msg.msg_name = NULL;
46: msg.msg_namelen = 0;
47: msg.msg_iov = &vector;
48: msg.msg_iovlen = 1;
49:
50: /* Теперь управляющее сообщение. Мы должны выделить участок памяти
51: для файлового дескриптора. */
52: cmsg = alloca(sizeof(struct cmsghdr) + sizeof(fd));
53: cmsg->cmsg_len = sizeof(struct cmsghdr) + sizeof(fd);
54: cmsg->cmsg_level = SOL_SOCKET;
55: cmsg->cmsg_type = SCM_RIGHTS;
56:
57: /* Копировать файловый дескриптор в конец
58: управляющего сообщения */
59: memcpy(CMSG_DATA(cmsg), &fd, sizeof(fd));
60:
61: msg.msg_control = cmsg;
62: msg.msg_controllen = cmsg->cmsg_len;
63:
64: if (sendmsg(sock, &msg, 0) != vector.iov_len)
65: die("sendmsg");
66:
67: return 0;
68: }
69:
70: /* Родительский процесс. Он получает файловый дескриптор. */
71: int parentProcess(int sock) {
72: char buf[80]; /* пространство для передачи имени файла */
73: struct iovec vector; /* имя файла от дочернего процесса */
74: struct msghdr msg; /* полное сообщение */
75: struct cmsghdr * cmsg; /* управляющее сообщение с fd */
76: int fd;
77:
78: /* установка iovec для имени файла */
79: vector.iov_base = buf;
80: vector.iov_len = 80;
81:
82: /* сообщение, которое мы хотим получить */
83:
84: msg.msg_name = NULL;
Поделиться:
Популярные книги
Последний попаданец 8
8. Последний попаданец
Фантастика:
юмористическая фантастика
рпг
5.00
рейтинг книги
Купеческая дочь замуж не желает
Фантастика:
фэнтези
6.89
рейтинг книги
Я – Стрела. Трилогия
Я - Стрела
Любовные романы:
любовно-фантастические романы
эро литература
6.82
рейтинг книги
Последний Паладин
1. Путь Паладина
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Горькие ягодки
Любовные романы:
современные любовные романы
7.44
рейтинг книги
Фиктивный брак
Фантастика:
фэнтези
6.71
рейтинг книги
Отмороженный 6.0
6. Отмороженный
Фантастика:
боевая фантастика
постапокалипсис
рпг
5.00
рейтинг книги
Законы Рода. Том 5
5. Граф Берестьев
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Свет во мраке
8. Изгой
Фантастика:
фэнтези
7.30
рейтинг книги
Кодекс Крови. Книга II
2. РОС: Кодекс Крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Сын Петра. Том 1. Бесенок
1. Сын Петра
Фантастика:
попаданцы
альтернативная история
6.80
рейтинг книги
Довлатов. Сонный лекарь
1. Не вывожу
Фантастика:
альтернативная история
аниме
5.00
рейтинг книги
Странник
4. Дворянская кровь
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Вечная Война. Книга V
5. Вечная Война
Фантастика:
юмористическая фантастика
космическая фантастика
7.29