Книга: UNIX: разработка сетевых приложений
Пример: функция bind и доменный сокет Unix
Разделы на этой странице:
Пример: функция bind и доменный сокет Unix
Программа, показанная в листинге 15.2, создает доменный сокет Unix, с помощью функции bind
связывает с ним полное имя и затем вызывает функцию getsockname
и выводит это полное имя.
Листинг 15.2. Связывание полного имени с доменным сокетом Unix
unixdomain/unixbind.c
1 #include "unp.h"
2 int
3 main(int argc, char **argv)
4 {
5 int sockfd;
6 socklen_t len;
7 struct sockaddr_un addr1, addr2;
8 if (argc != 2)
9 err_quit("usage: unixbind <pathname>");
10 sockfd = Socket(AF_LOCAL, SOCK_STREAM, 0);
11 unlink(argv[1]); /* игнорируем возможную ошибку */
12 bzero(&addr1, sizeof(addr1));
13 addr1.sun_family = AF_LOCAL;
14 strncpy(addr1.sun_path, argv[1], sizeof(addr1.sun_path) - 1);
15 Bind(sockfd, (SA*)&addr1, SUN_LEN(&addr1));
16 len = sizeof(addr2);
17 Getsockname(sockfd, (SA*)&addr2, &len);
18 printf("bound name = %s, returned len = %dn", addr2.sun_path, len);
19 exit(0);
20 }
Удаление файла
11
Полное имя, которое функция bind
должна связать с сокетом, — это аргумент командной строки. Если это полное имя уже существует в файловой системе, при выполнении функции bind
возникает ошибка. Следовательно, мы вызываем функцию unlink
, чтобы удалить файл в том случае, если он уже существует. Если его не существует, функция unlink
возвращает ошибку, которую мы игнорируем.
Вызов функций bind и getsockname
12-18
Мы копируем аргумент командной строки, используя функцию strncpy
, чтобы избежать переполнения структуры, если полное имя слишком длинное. Поскольку мы инициализируем структуру нулем и затем вычитаем единицу из размера массива sun_path
, мы знаем, что полное имя оканчивается нулем. Далее вызывается функция bind
и мы используем макрос SUN_LEN
для вычисления длины аргумента функции. Затем мы вызываем функцию getsockname
, чтобы получить имя, которое было только что связано с сокетом, и выводим результат.
Если мы запустим программу в Solaris, то получим следующие результаты:
solaris % umask сначала выводим наше значение umask
022 оно отображается в восьмеричной системе
solaris % unixbind /tmp/moose
bound name = /tmp/moose, returned len = 13
solaris % unixbind /tmp/moose снова запускаем программу
bound name = /tmp/moose, returned len = 13
solaris % ls -l /tmp/moose
srwxr-xr-x 1 andy staff 0 Aug 10 13:13 /tmp/moose
solaris % ls -lF /tmp/foo.bar
srwxr-xr-x 1 andy staff 0 Aug 10 13:13 /tmp/moose=
Сначала мы выводим наше значение umask
, поскольку в POSIX указано, что права доступа к создаваемому объекту определяются этим значением. Наше значение 022 выключает биты, разрешающие запись в файл для пользователей из группы (group-write) и прочих пользователей (other-write). Затем мы запускаем программу и видим, что длина, возвращаемая функцией getsockname
, равна 13: один байт для элемента sun_len
, один байт для элемента sun_family
и 11 байт для полного имени (исключая завершающий нуль). Это пример аргумента типа «значение-результат», значение которого при завершении функции отличается от значения при вызове функции. Мы можем вывести полное имя, используя спецификатор формата %s
функции printf
, поскольку полное имя, хранящееся в sun_path
, представляет собой завершающуюся нулем строку. Затем мы снова запускаем программу, чтобы проверить, что вызов функции unlink
удаляет соответствующий файл.
Мы запускаем команду ls -l
, чтобы увидеть биты разрешения для файла и тип файла. В Solaris (и большинстве версий Unix) тип файла — это сокет, что обозначается символом s. Мы также замечаем, что все девять битов разрешения включены, так как Solaris не изменяет принятые по умолчанию биты разрешения на наше значение umask
. Наконец, мы снова запускаем ls
с параметром -F
, что заставляет Solaris добавить знак равенства (соответствующий типу «сокет») к полному имени.
ПРИМЕЧАНИЕ
Изначально значение umask не действовало на создаваемые процессами доменные сокеты Unix, но с течением времени производители исправили это упущение, чтобы устанавливаемые разрешения соответствовали ожиданиям разработчиков. Тем не менее все еще существуют системы, в которых разрешения доменного сокета могут не зависеть от значения umask. В других системах сокеты могут отображаться как каналы (символ р), а значок равенства при вызове ls -F может не отображаться вовсе. Однако поведение, демонстрируемое в нашем примере, является наиболее типичным.
- 15.2. Структура адреса доменного сокета Unix
- Пример установочного скрипта
- Пример из практики
- 2.1.3. Функция getopt_long()
- ПРИМЕР ПРОСТОЙ ПРОГРАММЫ НА ЯЗЫКЕ СИ
- Группировка по встроенным функциям и UDF
- Примеры получения статистики
- Пример применения метода «пять почему»
- Глава 1 UNIX для начинающих
- Пример 12-8. Частота встречаемости отдельных слов
- 19.1.1. Функция jQuery()
- 1.2.5. Пример программы