Книга: 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 может не отображаться вовсе. Однако поведение, демонстрируемое в нашем примере, является наиболее типичным.

Оглавление книги

Оглавление статьи/книги

Генерация: 2.371. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз