Пример: функция 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 = %d ", 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 может не отображаться вовсе. Однако поведение, демонстрируемое в нашем примере, является наиболее типичным.

Поделитесь на страничке

Следующая глава >

Похожие главы из других книг

5.1.1. Учебный пример: формат файлов паролей в Unix

Из книги Искусство программирования для Unix автора Реймонд Эрик Стивен

5.1.1. Учебный пример: формат файлов паролей в Unix Во многих операционных системах данные пользователей, необходимые для регистрации и запуска пользовательского сеанса, представляют собой трудную для понимания двоичную базу данных. В противоположность этому, в


5.1.1. Учебный пример: формат файлов паролей в Unix

Из книги Искусство программирования для Unix автора Реймонд Эрик Стивен

5.1.1. Учебный пример: формат файлов паролей в Unix Во многих операционных системах данные пользователей, необходимые для регистрации и запуска пользовательского сеанса, представляют собой трудную для понимания двоичную базу данных. В противоположность этому, в


Как не следует делать это - C-Unix пример

Из книги Основы объектно-ориентированного программирования автора Мейер Бертран

Как не следует делать это - C-Unix пример Первым контрпримером механизма (наиболее полно представленным в Unix, но доступным и на других платформах, реализующих C) является процедура signal, вызываемая в следующей форме:signal (signal_code, your_routine)с эффектом вызова обработчика исключения -


Пример: очереди сообщений Posix и функция select

Из книги UNIX: взаимодействие процессов автора Стивенс Уильям Ричард

Пример: очереди сообщений Posix и функция select Дескриптор очереди сообщений (переменная типа mqd_t) не является «обычным» дескриптором и не может использоваться с функциями select и poll (глава 6 [24]). Тем не менее их можно использовать вместе с каналом и функцией mq_notify. (Аналогичный


Пример: функция приема сообщений в случае сокета

Из книги Системное программирование в среде Windows автора Харт Джонсон М

Пример: функция приема сообщений в случае сокета Часто оказывается удобным отправлять и получать сообщения в виде единых блоков. Как было показано в главе 11, каналы позволяют это сделать. Однако в случае сокетов требуется создание заголовка, содержащего размер


Пример 22-1. Простая функция

Из книги Linux глазами хакера автора Флёнов Михаил Евгеньевич

Пример 22-1. Простая функция #!/bin/bashfunky (){ echo "Это обычная функция."} # Функция должна быть объявлена раньше, чем ее можно будет использовать. # Вызов функции.funkyexit 0Функция должна быть объявлена раньше, чем ее можно будет использовать. К сожалению, в Bash нет возможности


Пример 22-2. Функция с аргументами

Из книги UNIX: разработка сетевых приложений автора Стивенс Уильям Ричард

Пример 22-2. Функция с аргументами #!/bin/bash# Функции и аргументыDEFAULT=default # Значение аргумента по-умолчанию.func2 () { if [ -z "$1" ] # Длина аргумента #1 равна нулю? then echo "-Аргумент #1 имеет нулевую длину.-" # Или аргумент не был передан функции. else echo


6.2.2. Доменный вход

Из книги автора

6.2.2. Доменный вход Если вы настроили сервер Linux так, чтобы пользователи Windows могли входить в систему через smb, используя его как домен, то необходимо убрать комментарии с секции [netlogon]:; [netlogon]; comment = Network Logon Service; path = /usr/local/samba/lib/netlogon; guest ok = yes; writable = noВ этой секции так же


4.4. Функция bind

Из книги автора

4.4. Функция bind Функция bind связывает сокет с локальным адресом протокола. В случае протоколов Интернета адрес протокола — это комбинация 32-разрядного адреса IPv4 или 128-разрядного адреса IPv6 с 16-разрядным номером порта TCP или UDP.#include <sys/socket.h>int bind(int sockfd, const struct sockaddr *myaddr, socklen_t


Пример: функция str_echo, использующая стандартный ввод-вывод

Из книги автора

Пример: функция str_echo, использующая стандартный ввод-вывод Сейчас мы модифицируем наш эхо-сервер TCP (см. листинг 5.2) для использования стандартного ввода-вывода вместо функций readline и writen. В листинге 14.6 представлена версия нашей функции str_echo, использующая стандартный


Пример: функция mcast_join

Из книги автора

Пример: функция mcast_join В листинге 21.1[1] показана первая часть функции mcast_join. Эта часть демонстрирует простоту интерфейса программирования, не зависящего от протокола.Листинг 21.1. Присоединение к группе: сокет IPv4//lib/mcast_join.c 1 #include "unp.h" 2 #include <net/if.h> 3 int 4 mcast_join(int sockfd, const SA *grp,


Пример: функция mcast_set_loop

Из книги автора

Пример: функция mcast_set_loop В листинге 21.4 показана наша функция mcast_set_loop.Поскольку аргументом является дескриптор сокета, а не структура адреса сокета, мы вызываем нашу функцию sockfd_to_family, чтобы получить семейство адресов сокета. Устанавливается соответствующий параметр