Г.1. Заголовочный файл unp.h

Г.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

Данный текст является ознакомительным фрагментом.