UNIX: разработка сетевых приложений - Уильям Стивенс
Шрифт:
Интервал:
Закладка:
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
Г.2. Заголовочный файл config.h
Для обеспечения переносимости всего исходного кода, используемого в тексте книги, применялась утилита GNU autoconf. Ее можно загрузить по адресу http://ftp.gnu.org/gnu/autoconf. Эта программа генерирует сценарий интерпретатора с названием configure, который надо запустить после загрузки программного обеспечения в свою систему. Этот сценарий определяет, какие свойства обеспечивает ваша система Unix: имеется ли в структуре адреса сокета поле длины, поддерживается ли многоадресная передача, поддерживаются ли структуры адреса сокета канального уровня, и т.д. В результате получается файл с названием config.h. Этот файл — первый заголовочный файл, включенный в unp.h (см. предыдущий раздел). В листинге Г.2 показан заголовочный файл config.h для BSD/OS 3.0.
Строки, начинающиеся с #define, относятся к тем свойствам, которые обеспечены данной системой. Закомментированные строки и строки, начинающиеся с #undef, относятся к свойствам, данной системой не поддерживаемым.
Листинг Г.2. Заголовочный файл config.h для BSD/OS
i386-pc-bsdi3.0/config.h
1 /* config.h. Автоматически генерируется сценарием configure. */
2 /* Определяем константы, если имеется соответствующий заголовочный файл */
3 #define CPU_VENDOR_OS "i386-pc-bsdi3.0"
4 /* #undef HAVE_NETCONFIG_H */ /* <netconfig.h> */
5 /* #undef HAVE_NETDIR_H */ /* <netdir.h> */
6 #define HAVE_PTHREAD_H 1 /* <pthread.h> */
7 #define HAVE_STRINGS_H 1 /* <strings.h> */
8 /* #undef HAVE_XTI_INET_H */ /* <xti_inet.h> */
9 #define HAVE_SYS_FILIO_H 1 /* <sys/filio.h> */
10 #define HAVE_SYS_IOCTL_H 1 /* <sys/ioctl.h> */
11 #define HAVE_SYS_SELECT_H 1 /* <sys/select.h> */
12 #define HAVE_SYS_SOCKIO_H 1 /* <sys/sockio.h> */
13 #define HAVE_SYS_SYSCTL_H 1 /* <sys/sysctl.h> */
14 #define HAVE_SYS_TIME_H 1 /* <sys/time.h> */
15 /* Определена, если можно подключить <time.h> и <sys/time.h> */
16 #define TIME_WITH_SYS_TIME 1
17 /* Определены, если имеются соответствующие функции */
18 #define HAVE_BZERO 1
19 #define HAVE_GETHOSTBYNAME2 1
20 /* #undef HAVE_PSELECT */
21 #define HAVE_VSNPRINTF 1
22 /* Определены, если прототипы функций есть в заголовочном файле */
23 /* #undef HAVE_GETADDRINFO_PROTO */ /* <netdb.h> */
24 /* #undef HAVE_GETNAMEINFO_PROTO */ /* <netdb.h> */
25 #define HAVE_GETHOSTNAME_PROTO 1 /* <unistd.h> */
26 #define HAVE_GETRUSAGE_PROTO 1 /* <sys/resource.h> */
27 #define HAVE_HSTRERROR_PROTO 1 /* <netdb.h> */
28 /* #undef HAVE_IF_NAMETOINDEX_PROTO */ /* <net/if.h> */
29 #define HAVE_INET_ATON_PROTO 1 /* <arpa/inet.h> */
30 #define HAVE_INET_PTON_PROTO 1 /* <arpa/inet.h> */
31 /* #undef HAVE_ISFDTYPE_PROTO */ /* <sys/stat.h> */
32 /* #undef HAVE_PSELECT_PROTO */ /* <sys/select.h> */
33 #define HAVE_SNPRINTF_PROTO 1 /* <stdio.h> */
34 /* #undef HAVE_SOCKATMARK_PROTO */ /* <sys/socket.h> */
35 /* Определены, если определены соответствующие структуры */
36 /* #undef HAVE_ADDRINFO_STRUCT */ /* <netdb.h> */
37 /* #undef HAVE_IF_NAMEINDEX_STRUCT */ /* <net/if.h> */
38 #define HAVE_SOCKADDR_DL_STRUCT 1 /* <net/if_dl.h> */
39 #define HAVE TIMESPEC STRUCT 1 /* <time.h> */
40 /* Определены, если имеется указанное свойство */
41 #define HAVE_SOCKADDR_SA_LEN 1 /* в sockaddr{} есть поле sa_len */
42 #define HAVE_MSGHDR_MSG_CONTROL 1 /* в msghdr{} есть поле msg_control */
43 /* Имена устройств XTI для TCP и UDP */
44 /* #undef HAVE_DEV_TCP */ /* большинство здесь */
45 /* #undef HAVE_DEV_XTI_TCP */ /* для AIX */
46 /* #undef HAVE_DEV_STREAMS_XTISO_TCP */ /* для OSF 3.2 */
47 /* При необходимости определяем типы данных */
48 /* #undef int8_t */ /* <sys/types.h> */
49 /* #undef int16_t */ /* <sys/types.h> */
50 /* #undef int32_t */ /* <sys/types.h> */
51 #define uint8_t unsigned char /* <sys/types.h> */
52 #define uint16_t unsigned short /* <sys/types.h> */
53 #define uint32_t unsigned int /* <sys/types.h> */
54 /* #undef size_t */ /* <sys/types.h> */
55 /* #undef ssize_t */ /* <sys/types.h> */
56 /* socklen_t должен иметь тип uint32_t, но configure определяет его
57 как unsigned int. т. к. это значение используется в начале компиляции.
58 иногда до того, как в данной реализации определяется тип uint32_t */
59 #define socklen_t unsigned int /* <sys/socket.h> */
60 #define sa_family_t SA_FAMILY_T /* <sys/socket.h> */
61 #define SA_FAMILY_T uint8_t
62 #define t_scalar_t int32_t /* <xti.h> */
63 #define t_uscalar_t uint32_t /* <xti.h> */
64 /* Определены, если система поддерживает указанное свойство */
65 #define IPV4 1 /* IPv4, V в верхнем регистре */
66 #define IPv4 1 /* IPv4, v в нижнем регистре, на всякий случай */
67 /* #undef IPV6 */ /* IPv6, V в верхнем регистре */
68 /* #undef IPv6 */ /* IPv6, v в нижнем регистре, на всякий случай */
69 #define UNIXDOMAIN 1 /* доменные сокеты Unix */
70 #define UNIXdomain 1 /* доменные сокеты Unix */
71 #define MCAST 1 /* поддержка многоадресной передачи */
Г.3. Стандартные функции обработки ошибок
В этой книге мы определяем набор своих собственных функций для обработки ошибок. Причина, по который мы создаем эти функции, заключается в том, что они позволяют нам обрабатывать ошибки с помощью одной строки кода, как, например, показано ниже:
if (условие ошибки)
err_sys(формат printf с любым количеством аргументов);
вместо
if (условие ошибки) {
char buff[200];
snprintf(buff, sizeof(buff), формат printf с любым количеством аргументов);
perror(buff);
exit(1);
}
Наши функции обработки ошибок используют следующую возможность ANSI С: список аргументов может иметь переменную длину. Более подробную информацию об этом вы найдете в разделе 7.3 книги [68].