Приложение Г Различные исходные коды
Приложение Г
Различные исходные коды
Г.1. Заголовочный файл unp.h
Почти каждая программа в этой книге начинается с подключения заголовочного файла unp.h, показанного в листинге Г.1[1]. Этот файл подключает все стандартные системные заголовочные файлы, необходимые для работы большинства программ, а также некоторые общие системные заголовочные файлы. В нем также определены такие константы, как MAXLINE, прототипы функций ANSI С для тех функций, которые мы определяем в тексте (например, readline), и все используемые нами функции-обёртки. Сами прототипы в приведенном ниже листинге мы не показываем.
Листинг Г.1. Заголовочный файл unp.h
//lib/unp.h
1 /* Наш собственный заголовочный файл */
2 #ifndef __unp_h
3 #define __unp_h
4 #include "../config.h" /* параметры конфигурации для данной ОС */
5 /* "../config.h" генерируется сценарием configure */
6 /* изменив список директив #include,
7 нужно также изменить файл acsite.m4 */
8 #include <sys/types.h> /* основные системные типы данных */
9 #include <sys/socket.h> /* основные определения сокетов */
10 #include <sys/time.h> /* структура timeval{} для функции select() */
11 #include <time.h> /* структура timespec{} для функции pselect() */
12 #include <netinet/in.h> /* структура sockaddr_in{} и другие сетевые
определения */
13 #include <arpa/inet.h> /* inet(3) функции */
14 #include <errno.h>
15 #include <fcntl.h> /* для неблокируемых сокетов */
16 #include <netdb.h>
17 #include <signal.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <sys/stat.h> /* для констант S_xxx */
22 #include <sys/uio.h> /* для структуры iovec{} и ready/writev */
23 #include <unistd.h>
24 #include <sys/wait.h>
25 #include <sys/un.h> /* для доменных сокетов Unix */
26 #ifdef HAVE_SYS_SELECT_H
27 #include <sys/select.h> /* для удобства */
28 #endif
29 #ifdef HAVE_SYS_SYSCTL_H
30 #include <sys/sysctl.h>
31 #endif
32 #ifdef HAVE_POLL_H
33 #include <poll.h> /* для удобства */
34 #endif
35 #ifdef HAVE_SYS_EVENT_H
36 #include <sys/event.h> /* для kqueue */
37 #endif
38 #ifdef HAVE_STRINGS_H
39 #include <strings.h> /* для удобства */
40 #endif
41 /* Три заголовочных файла обычно нужны для вызова ioctl
42 для сокета/файла: <sys/ioctl.h>, <sys/filio.h>,
43 <sys/sockio.h> */
44 #ifdef HAVE_SYS_IOCTL_H
45 #include <sys/ioctl.h>
46 #endif
47 #ifdef HAVE_SYS_FILIO_H
48 #include <sys/filio.h>
49 #endif
50 #ifdef HAVE_SYS_SOCKIO_H
51 #include <sys/sockio.h>
52 #endif
53 #ifdef HAVE_PTHREAD_H
54 #include <pthread.h>
55 #endif
56 #ifdef HAVE_NET_IF_DL_H
57 #include <net/if_dl.h>
58 #endif
59 #ifdef HAVE_NETINET_SCTP_H
60 #include <netinet/sctp.h>
61 #endif
62 /* OSF/1 фактически запрещает recv() и send() в <sys/socket.h> */
63 #ifdef __osf__
64 #undef recv
65 #undef send
66 #define recv(a,b,c,d) recvfrom(a,b,c,d,0,0)
67 #define send(a,b,c,d) sendto(a,b,c,d,0,0)
68 #endif
69 #ifndef INADDR_NONE
70 #define INADDR_NONE 0xffffffff /* должно было быть в <netinet/in.h> */
71 #endif
72 #ifndef SHUT_RD /* три новые константы Posix.1g */
73 #define SHUT_RD 0 /* отключение чтения */
74 #define SHUT_WR 1 /* отключение записи */
75 #define SHUT_RDWR 2 /* отключение чтения и записи */
76 #endif
77 #ifndef INET_ADDRSTRLEN
78 #define INET_ADDRSTRLEN 16 /* "ddd.ddd.ddd.ddd"
79 1234567890123456 */
80 #endif
81 /* Нужно, даже если нет поддержки IPv6, чтобы мы всегда могли
82 разместить в памяти буфер требуемого размера без директив #ifdef */
83 #ifndef INET6_ADDRSTRLEN
84 #define INET6_ADDRSTRLEN 46 /* максимальная длина строки адреса IPv6:
85 "xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx" или
86 "xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:ddd.ddd.ddd.ddd"
87 1234567890123456789012345678901234567890123456 */
88 #endif
89 /* Определяем bzero() как макрос, если эта функция отсутствует в
стандартной библиотеке С */
90 #ifndef HAVE_BZERO
91 #define bzero(ptr,n) memset(ptr, 0, n)
92 #endif
93 /* В более старых распознавателях отсутствует gethostbyname2() */
94 #ifndef HAVE_GETHOSTBYNAME2
95 #define gethostbyname2(host, family) gethostbyname((host))
96 #endif
97 /* Структура, возвращаемая функцией recvfrom_flags() */
98 struct in_pktinfo {
99 struct in_addr ipi_addr; /* IPv4-адрес получателя */
100 int ipi_ifindex; /* полученный индекс интерфейса */
101 };
102 /* Нам нужны более новые макросы CMSG_LEN() и CMSG_SPACE(), но в
103 настоящее время их поддерживают далеко не все реализации. Им требуется
104 макрос ALIGN(), но это зависит от реализации */
105 #ifndef CMSG_LEN
106 #define CMSG_LEN(size) (sizeof(struct cmsghdr) + (size))
107 #endif
108 #ifndef CMSG_SPACE
109 #define CMSG_SPACE(size) (sizeof(struct cmsghdr) + (size))
110 #endif
111 /* POSIX требует макрос SUN_LEN(), но он определен
112 не во всех реализациях. Этот макрос 4.4BSD работает
123 независимо от того, имеется ли поле длины */
114 #ifndef SUN_LEN
115 #define SUN_LEN(su)
116 (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path))
117 #endif
118 /* В POSIX "домен Unix" называется "локальным IPC".
119 Но пока не во всех системах определены AF_LOCAL и PF_LOCAL */
120 #ifndef AF_LOCAL
121 #define AF_LOCAL AF_UNIX
122 #endif
123 #ifndef PF_LOCAL
124 #define PF_LOCAL PF_UNIX
125 #endif
126 /* POSIX требует определения константы INFTIM в <poll.h>, но во многих
127 системах она по-прежнему определяется в <sys/stropts.h>. Чтобы
128 не подключать все функции работы с потоками, определяем ее здесь.
129 Это стандартное значение, но нет гарантии, что оно равно -1 */
130 #ifndef INFTIM
131 #define INFTIM (-1) /* бесконечный тайм-аут */
132 #ifdef HAVE_POLL_H
133 #define INFTIM_UNPH /* надо указать в unpxti.h, что эта константа
определена здесь */
134 #endif
135 #endif
136 /* Это значение можно было бы извлечь из SOMAXCONN в <sys/socket.h>,
137 но многие ядра по-прежнему определяют его как 5,
хотя на самом деле поддерживается гораздо больше */
138 #define LISTENQ 1024 /* второй аргумент функции listen() */
139 /* Различные константы */
140 #define MAXLINE 4096 /* максимальная длина текстовой строки */
141 #define BUFFSIZE 8192 /* размер буфера для чтения и записи */
142 /* Определение номера порта, который может быть использован для
взаимодействия клиент-сервер */
143 #define SERV_PORT 9877 /* клиенты и серверы TCP и UDP */
144 #define SERV_PORT_STR "9877" /* клиенты и серверы TCP и UDP */
145 #define UNIXSTR_PATH "/tmp/unix.str" /* потоковые клиенты и серверы
домена Unix */
146 #define UNIXDG_PATH "/tmp/unix.dg" /* клиенты и серверы протокола
дейтаграмм домена Unix */
147 /* Дальнейшие определения сокращают преобразования типов
аргументов-указателей */
148 #define SA struct sockaddr
149 #define HAVE_STRUCT_SOCKADDR_STORAGE
150 #ifndef HAVE_STRUCT_SOCKADDR_STORAGE
151 /*
152 * RFC 3493: протокольно-независимая структура адреса сокета
153 */
154 #define __SS_MAXSIZE 128
155 #define __SS_ALIGNSIZE (sizeof(int64_t))
156 #ifndef HAVE_SOCKADDR_SA_LEN
157 #define __SS_PADS1SIZE (__SS_ALIGNSIZE - sizeof(u_char) -
sizeof(sa_family_t))
158 #else
159 #define _SS_PAD1SIZE (__SS_ALIGNSIZE - sizeof(sa_family_t))
160 #endif
161 #define __SS_PAD2SIZE (__SS_MAXSIZE — 2*__SS_ALIGNSIZE)
162 struct sockaddr_storage {
163 #ifdef HAVE_SOCKADDR_SA_LEN
164 u_char ss_len;
165 #endif
166 sa_family_t ss_family;
167 char __ss_pad1[__SS_PAD1SIZE];
168 int64_t ss_align;
169 char __ss_pad2[_SS_PAD2SIZE];
170 };
171 #endif
172 #define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
173 /* заданные по умолчанию разрешения на доступ для новых файлов */
174 #define DIR_MODE (FILE_MODE | S_IXUSR | S_IXGRP | S_IXOTH)
175 /* разрешения по умолчанию на доступ к файлам для новых каталогов */
176 typedef void Sigfunc(int); /* для обработчиков сигналов */
177 #define min(a, b) ((а) < (b) ? (a) : (b))
178 #define max(a, b) ((a) > (b) ? (a) : (b))
179 #ifndef HAVE_ADDRINFO_STRUCT
180 #include "../lib/addrinfo.h"
181 #endif
182 #ifndef HAVE_IF_NAMEINDEX_STRUCT
183 struct if_nameindex {
184 unsigned int if_index; /* 1, 2, ... */
185 char *if_name; /* имя, заканчивающееся нулем: "le0", ... */
186 };
187 #endif
188 #ifndef HAVE_TIMESPEC_STRUCT
189 struct timespec {
190 time_t tv_sec; /* секунды */
191 long tv_nsec; /* и наносекунды */
192 };
193 #endif
Данный текст является ознакомительным фрагментом.