.\" -*- coding: UTF-8 -*- .\" SPDX-License-Identifier: Linux-man-pages-1-para .\" .\" This man page is Copyright (C) 1999 Andi Kleen , .\" Copyright (C) 2008-2014, Michael Kerrisk , .\" and Copyright (C) 2016, Heinrich Schuchardt .\" .\" Modified, 2003-12-02, Michael Kerrisk, .\" Modified, 2003-09-23, Adam Langley .\" Modified, 2004-05-27, Michael Kerrisk, .\" Added SOCK_SEQPACKET .\" 2008-05-27, mtk, Provide a clear description of the three types of .\" address that can appear in the sockaddr_un structure: pathname, .\" unnamed, and abstract. .\" .\"******************************************************************* .\" .\" This file was generated with po4a. Translate the source file. .\" .\"******************************************************************* .TH UNIX 7 "15 июля 2023 г." "Linux man\-pages 6.05.01" .SH ИМЯ unix \- сокеты для локального межпроцессного взаимодействия .SH СИНТАКСИС .nf \fB#include \fP \fB#include \fP .PP \fIunix_socket\fP\fB = socket(AF_UNIX, type, 0);\fP \fIerror\fP\fB = socketpair(AF_UNIX, type, 0, int *\fP\fIsv\fP\fB);\fP .fi .SH ОПИСАНИЕ Семейство сокетов \fBAF_UNIX\fP (также известное, как \fBAF_LOCAL\fP) используется для эффективного взаимодействия между процессами на одной машине. Доменные сокеты UNIX могут быть как безымянными, так и иметь имя файла в файловой системе (типизированный сокет). В Linux также поддерживается абстрактное пространство имён, которое не зависит от файловой системы. .PP Допустимые типы сокета для домена UNIX: потоковый сокет \fBSOCK_STREAM\fP, датаграмный сокет \fBSOCK_DGRAM\fP, сохраняющий границы сообщений (в большинстве реализаций UNIX, доменные датаграмные сокеты UNIX всегда надёжны и не меняют порядок датаграмм); и (начиная с Linux 2.6.4) ориентированный на соединение задающий последовательность пакетам сокет \fBSOCK_SEQPACKET\fP, сохраняющий границы сообщений и доставляющий сообщения в том же порядке, в каком они были отправлены. .PP Доменные сокеты UNIX поддерживают передачу файловых дескрипторов или учётных данных (credentials) о процессе другим процессам, используя вспомогательные (ancillary) данные. .SS "Формат адреса" Адрес доменного сокета UNIX представляет собой следующую структуру: .PP .in +4n .EX .\" #define UNIX_PATH_MAX 108 .\" struct sockaddr_un { sa_family_t sun_family; /* AF_UNIX */ char sun_path[108]; /* имя пути */ }; .EE .in .PP The \fIsun_family\fP field always contains \fBAF_UNIX\fP. On Linux, \fIsun_path\fP is 108 bytes in size; see also BUGS, below. .PP В различных системных вызовах (например, \fBbind\fP(2), \fBconnect\fP(2) и \fBsendto\fP(2)) в качестве входных данных используется параметр \fIsockaddr_un\fP. Другие системные вызовы (например, \fBgetsockname\fP(2), \fBgetpeername\fP(2), \fBrecvfrom\fP(2) и \fBaccept\fP(2)) возвращают результат в параметре этого типа. .PP В \fIsockaddr_un\fP структуре различают три типа адресов: .TP pathname (путь) a UNIX domain socket can be bound to a null\-terminated filesystem pathname using \fBbind\fP(2). When the address of a pathname socket is returned (by one of the system calls noted above), its length is .IP .in +4n .EX offsetof(struct sockaddr_un, sun_path) + strlen(sun_path) + 1 .EE .in .IP и \fIsun_path\fP содержит путь, оканчивающийся null (в Linux, указанное выше выражение \fBoffsetof\fP() равно \fIsizeof(sa_family_t)\fP, но в некоторых реализациях включаются другие поля перед \fIsun_path\fP, поэтому выражение \fBoffsetof\fP() описывает размер адресной структуры более переносимым способом). .IP Дополнительную информацию о путях сокета смотрите далее. .TP unnamed .\" There is quite some variation across implementations: FreeBSD .\" says the length is 16 bytes, HP-UX 11 says it's zero bytes. A stream socket that has not been bound to a pathname using \fBbind\fP(2) has no name. Likewise, the two sockets created by \fBsocketpair\fP(2) are unnamed. When the address of an unnamed socket is returned, its length is \fIsizeof(sa_family_t)\fP, and \fIsun_path\fP should not be inspected. .TP abstract an abstract socket address is distinguished (from a pathname socket) by the fact that \fIsun_path[0]\fP is a null byte (\[aq]\e0\[aq]). The socket's address in this namespace is given by the additional bytes in \fIsun_path\fP that are covered by the specified length of the address structure. (Null bytes in the name have no special significance.) The name has no connection with filesystem pathnames. When the address of an abstract socket is returned, the returned \fIaddrlen\fP is greater than \fIsizeof(sa_family_t)\fP (i.e., greater than 2), and the name of the socket is contained in the first \fI(addrlen \- sizeof(sa_family_t))\fP bytes of \fIsun_path\fP. .SS "Путевые сокеты" При привязке сокета к пути для максимальной переносимости и простоте кодирования нужно учесть несколько правил: .IP \[bu] 3 Имя пути в \fIsun_path\fP должно завершаться null. .IP \[bu] Длина имени пути, включая завершающий байт null, не должна превышать размер \fIsun_path\fP. .IP \[bu] Аргумент \fIaddrlen\fP, описывающий включаемую структуру \fIsockaddr_un\fP, должен содержать значение, как минимум: .IP .in +4n .EX offsetof(struct sockaddr_un, sun_path)+strlen(addr.sun_path)+1 .EE .in .IP или, проще говоря, для \fIaddrlen\fP можно использовать \fIsizeof(struct sockaddr_un)\fP. .PP .\" Linux does this, including for the case where the supplied path .\" is 108 bytes Есть несколько реализаций по работе с адресами доменных сокетов UNIX, которые не следуют данным правилам. Например, в некоторых реализациях (но не во всех) добавляется конечный null, если если его нет в \fIsun_path\fP. .PP .\" HP-UX .\" Modern BSDs generally have 104, Tru64 and AIX have 104, .\" Solaris and Irix have 108 При написании переносимых приложений учтите, что в некоторых реализациях размер \fIsun_path\fPравен 92 байтам. .PP .\" Различные системные вызовы (например, \fBaccept\fP(2), \fBrecvfrom\fP(2), \fBgetsockname\fP(2), \fBgetpeername\fP(2)) возвращают адресные структуры сокета. В случае с доменными сокетами UNIX аргумент значение\-результат \fIaddrlen\fP, передаваемый вызову, должен быть инициализирован как описано выше. При возврате в аргументе содержится \fIреальный\fP размер адресной структуры. Вызывающий должен проверить полученное значение этого аргумента: если оно превышает значение до вызова, то не гарантируется наличие конечного null в \fIsun_path\fP (смотрите ДЕФЕКТЫ). .SS "Пути к сокетам и права" В реализации Linux учитываются права на каталоги, в которых располагаются сокеты. Создание нового сокета завершается ошибкой, если процесс не имеет права писать или искать (выполнять) в каталог, в котором создаётся сокет. .PP В Linux для подключения к объекту потокового сокета требуются права на запись в этот сокет; схожим образом, для отправки дейтаграммы в дейтаграммный сокет требуются права на запись в этот сокет. В POSIX ничего не сказано о влиянии прав файла сокета и в некоторых системах (например, в старых BSD) права на сокет игнорируются. Переносимые программы не должны полагаться на это свойство для обеспечения безопасности. .PP При создании нового сокета владелец и группа файла сокета назначаются согласно обычных правил. К файлу сокета разрешается любой доступ кроме выключенного процессом с помощью \fBumask\fP(2). .PP .\" However, fchown() and fchmod() do not seem to have an effect .\" Владелец, группа и права доступа пути сокета можно изменять (с помощью \fBchown\fP(2) и \fBchmod\fP(2)). .SS "Абстрактные сокеты" Права на сокеты не учитываются у абстрактных сокетов: \fBumask\fP(2) процесса не учитывается при подключении к абстрактному сокету как и изменение владельца и прав доступа к объекту (посредством \fBfchown\fP(2) и \fBfchmod\fP(2)) не влияют на доступность сокета. .PP Абстрактные сокеты автоматически исчезают при закрытии всех открытых ссылок на них. .PP .\" Пространство имён абстрактных сокетов является непереносимым расширением Linux. .SS "Параметры сокета" В силу исторических причин эти параметры сокетов относятся к типу \fBSOL_SOCKET\fP, даже если они относятся к \fBAF_UNIX\fP. Они могут быть установлены с помощью \fBsetsockopt\fP(2) и прочитаны с помощью \fBgetsockopt\fP(2); тип \fBSOL_SOCKET\fP указывается в качестве семейства сокета. .TP \fBSO_PASSCRED\fP Разрешает приём учётных данных посылающего процесса в вспомогательном сообщении \fBSCM_CREDENTIALS\fP каждого последующего принятого сообщения. Полученные учётные данные были заданы отправителем с помощью \fBSCM_CREDENTIALS\fP, или имеют значение по умолчанию, которое содержит PID отправителя, фактический пользовательский и групповой ID, если отправитель не задал вспомогательные данные \fBSCM_CREDENTIALS\fP. .IP Если при включении этого параметра сокет ещё не соединён, то в абстрактном пространстве имён будет автоматически создано уникальное имя. .IP Значение передаётся в аргументе \fBsetsockopt\fP(2) и возвращается в результате \fBgetsockopt\fP(2) в виде целочисленного логического флага. .TP \fBSO_PASSSEC\fP Разрешает приём метки безопасности SELinux однорангового сокета в вспомогательном сообщении с типом \fBSCM_SECURITY\fP (смотрите ниже). .IP Значение передаётся в аргументе \fBsetsockopt\fP(2) и возвращается в результате \fBgetsockopt\fP(2) в виде целочисленного логического флага. .IP .\" commit 877ce7c1b3afd69a9b1caeb1b9964c992641f52a .\" commit 37a9a8df8ce9de6ea73349c9ac8bdf6ba4ec4f70 Параметр \fBSO_PASSSEC\fP поддерживается для дейтаграммных доменных сокетов UNIX начиная с Linux 2.6.18; поддержка потоковых доменных сокетов UNIX добавлена в Linux 4.2. .TP \fBSO_PEEK_OFF\fP Смотрите \fBsocket\fP(7). .TP \fBSO_PEERCRED\fP С параметром сокета, доступным только для чтения, возвращаются учётные данные однорангового процесса, соединённого с сокетом. Возвращаются информационные данные, которые были действительными на момент вызова \fBconnect\fP(2) или \fBsocketpair\fP(2). .IP Аргументом \fBgetsockopt\fP(2) является указатель на структуру \fIucred\fP; определите макрос тестирования свойств \fB_GNU_SOURCE\fP для получения определения этой структуры из \fI\fP. .IP Использование этого параметра возможо только для соединённых потоковых сокетов \fBAF_UNIX\fP и потоков \fBAF_UNIX\fP и для дейтаграммных сокетных пар, созданных с помощью \fBsocketpair\fP(2). .TP \fBSO_PEERSEC\fP This read\-only socket option returns the security context of the peer socket connected to this socket. By default, this will be the same as the security context of the process that created the peer socket unless overridden by the policy or by a process with the required permissions. .IP The argument to \fBgetsockopt\fP(2) is a pointer to a buffer of the specified length in bytes into which the security context string will be copied. If the buffer length is less than the length of the security context string, then \fBgetsockopt\fP(2) returns \-1, sets \fIerrno\fP to \fBERANGE\fP, and returns the required length via \fIoptlen\fP. The caller should allocate at least \fBNAME_MAX\fP bytes for the buffer initially, although this is not guaranteed to be sufficient. Resizing the buffer to the returned length and retrying may be necessary. .IP The security context string may include a terminating null character in the returned length, but is not guaranteed to do so: a security context "foo" might be represented as either {'f','o','o'} of length 3 or {'f','o','o','\e0'} of length 4, which are considered to be interchangeable. The string is printable, does not contain non\-terminating null characters, and is in an unspecified encoding (in particular, it is not guaranteed to be ASCII or UTF\-8). .IP .\" commit 0b811db2cb2aabc910e53d34ebb95a15997c33e7 .\" The use of this option for sockets in the \fBAF_UNIX\fP address family is supported since Linux 2.6.2 for connected stream sockets, and since Linux 4.18 also for stream and datagram socket pairs created using \fBsocketpair\fP(2). .SS "Свойство автоматической привязки" .\" i.e., sizeof(short) If a \fBbind\fP(2) call specifies \fIaddrlen\fP as \fIsizeof(sa_family_t)\fP, or the \fBSO_PASSCRED\fP socket option was specified for a socket that was not explicitly bound to an address, then the socket is autobound to an abstract address. The address consists of a null byte followed by 5 bytes in the character set \fI[0\-9a\-f]\fP. Thus, there is a limit of 2\[ha]20 autobind addresses. (From Linux 2.1.15, when the autobind feature was added, 8 bytes were used, and the limit was thus 2\[ha]32 autobind addresses. The change to 5 bytes came in Linux 2.3.15.) .SS "Программный интерфейс сокетов" В следующих параграфах описываются специфичные тонкости доменов и неподдерживаемые возможности программного интерфейса сокетов для доменных сокетов UNIX в Linux. .PP Доменные сокеты UNIX не поддерживают передачу внеполосных данных (флаг \fBMSG_OOB\fP у \fBsend\fP(2) и \fBrecv\fP(2)). .PP Флаг \fBMSG_MORE\fP у \fBsend\fP(2) не поддерживается доменными сокетами UNIX. .PP .\" commit 9f6f9af7694ede6314bed281eec74d588ba9474f До Linux 3.4 использование \fBMSG_TRUNC\fP в аргументе \fIflags\fP у \fBrecv\fP(2) не поддерживалось доменными сокетами UNIX. .PP Параметр сокета \fBSO_SNDBUF\fP учитывается в доменных сокетах UNIX, а параметр \fBSO_RCVBUF\fP \(em нет. Для датаграмных сокетов значение \fBSO_SNDBUF\fP считается максимальным размером для исходящих датаграмм. Это ограничение, вычисляемое как удвоенное значение (см. \fBsocket\fP(7)) параметра, содержит меньше 32 байт накладных расходов. .SS "Вспомогательные сообщения" Вспомогательные данные отправляются и принимаются с помощью \fBsendmsg\fP(2) и \fBrecvmsg\fP(2). В силу исторических причин перечисленные типы вспомогательных сообщений относятся к типу \fBSOL_SOCKET\fP, даже если они относятся к \fBAF_UNIX\fP. Для того, чтобы отправить их, установите значение поля \fIcmsg_level\fP структуры \fIcmsghdr\fP равным \fBSOL_SOCKET\fP, а в значении поля \fIcmsg_type\fP укажите его тип. Дополнительная информация приведена в \fBcmsg\fP(3). .TP \fBSCM_RIGHTS\fP Передать или принять набор открытых файловых дескрипторов из другого процесса. Часть с данными содержит целочисленный массив файловых дескрипторов. .IP Обычно, эта операция упоминается как «передача дескриптора файла» другому процессу. Но если точнее, то передается ссылка на открытое файловое описание (смотрите \fBopen\fP(2)) и в принимающем процессе будет использоваться, вероятно, файловый дескриптор с другим номером. Семантически, эта операция эквивалентна дублированию (\fBdup\fP(2)) файлового дескриптора в таблицу файловых дескрипторов другого процесса. .IP Если используемый для приёма вспомогательных данных с файловыми дескрипторами буфер слишком мал (или отсутствует), то вспомогательные данные обрезаются (или отбрасываются), а избыточные файловые дескрипторы автоматически закрываются в принимающем процессе. .IP Если количество файловых дескрипторов, полученных во вспомогательных данных, превышает ограничение ресурса процесса \fBRLIMIT_NOFILE\fP (смотрите \fBgetrlimit\fP(2)), то превысившие файловые дескрипторы автоматически закрываются в принимающем процессе. .IP .\" commit bba14de98753cb6599a2dae0e520714b2153522d The kernel constant \fBSCM_MAX_FD\fP defines a limit on the number of file descriptors in the array. Attempting to send an array larger than this limit causes \fBsendmsg\fP(2) to fail with the error \fBEINVAL\fP. \fBSCM_MAX_FD\fP has the value 253 (or 255 before Linux 2.6.38). .TP \fBSCM_CREDENTIALS\fP Send or receive UNIX credentials. This can be used for authentication. The credentials are passed as a \fIstruct ucred\fP ancillary message. This structure is defined in \fI\fP as follows: .IP .in +4n .EX struct ucred { pid_t pid; /* идентификатор посылающего процесса */ uid_t uid; /* идентификатор пользователя посылающего процесса */ gid_t gid; /* идентификатор группы посылающего процесса */ }; .EE .in .IP Начиная с glibc 2.8, чтобы получить определение данной структуры должен быть определён макрос тестирования свойств \fB_GNU_SOURCE\fP (до включения \fIкаких\-либо\fP заголовочных файлов). .IP The credentials which the sender specifies are checked by the kernel. A privileged process is allowed to specify values that do not match its own. The sender must specify its own process ID (unless it has the capability \fBCAP_SYS_ADMIN\fP, in which case the PID of any existing process may be specified), its real user ID, effective user ID, or saved set\-user\-ID (unless it has \fBCAP_SETUID\fP), and its real group ID, effective group ID, or saved set\-group\-ID (unless it has \fBCAP_SETGID\fP). .IP Для получения сообщения со структурой \fIstruct ucred\fP у сокета должен быть включён параметр \fBSO_PASSCRED\fP. .TP \fBSCM_SECURITY\fP Получить контекст безопасности SELinux (метку безопасности) однорангового сокета. Полученные вспомогательные данные представляют собой строку (с null в конце) с контекстом безопасности. Получатель должен выделить не менее \fBNAME_MAX\fP байт под эти данные в в части данных вспомогательного сообщения. .IP Для получения контекста безопасности у сокета должен быть включён параметр \fBSO_PASSSEC\fP (смотрите выше). .PP При отправке вспомогательных данных с помощью \fBsendmsg\fP(2) посылаемое сообщение может содержать только по одному элементу каждого типа, из представленных выше. .PP По крайней мере один байт реальных данных должен быть отправлен при отправке вспомогательных данных. В Linux это требуется для успешной отправки вспомогательных данных через потоковый доменный сокет UNIX. При отправке вспомогательных данных через дейтаграммный доменный сокет UNIX в Linux необязательно отправлять какие\-либо реальные сопровождающие данные. Однако переносимые приложения должны также включать, по крайней мере, один байт реальных данных при отправке вспомогательных данных через дейтаграммный сокет. .PP При получении из потокового сокета вспомогательные данные формируют своего рода барьер для полученных данных. Например, предположим, что отправитель передает так: .PP .RS .PD 0 .IP (1) 5 \fBsendmsg\fP(2) отправляет четыре байта без вспомогательных данных. .IP (2) \fBsendmsg\fP(2) отправляет один байт вспомогательных данных. .IP (3) \fBsendmsg\fP(2) отправляет четыре байта без вспомогательных данных. .PD .RE .PP Suppose that the receiver now performs \fBrecvmsg\fP(2) calls each with a buffer size of 20 bytes. The first call will receive five bytes of data, along with the ancillary data sent by the second \fBsendmsg\fP(2) call. The next call will receive the remaining four bytes of data. .PP .\" Если место, выделенное для получения входящих вспомогательных данных, слишком маленькое, то вспомогательные данные обрезаются по количеству заголовков, которые влезут в предоставленной буфер (или, в случае списка файловых дескрипторов \fBSCM_RIGHTS\fP, может быть обрезан список файловых дескрипторов). Если для входящих вспомогательных данных буфер не был предусмотрен (т. е., поле \fImsg_control\fP в структуре \fImsghdr\fP, указанное \fBrecvmsg\fP(2), равно NULL), то входящие вспомогательные данные отбрасываются. В обоих случаях, в возвращаемом значении \fBrecvmsg\fP(2) в \fImsg.msg_flags\fP будет установлен флаг \fBMSG_CTRUNC\fP. .SS "Вызовы ioctl" Следующие вызовы \fBioctl\fP(2) возвращают информацию в аргументе \fIvalue\fP. Корректный синтаксис: .PP .RS .nf \fBint\fP\fI value\fP\fB;\fP \fIerror\fP\fB = ioctl(\fP\fIunix_socket\fP\fB, \fP\fIioctl_type\fP\fB, &\fP\fIvalue\fP\fB);\fP .fi .RE .PP Значением \fIioctl_type\fP может быть: .TP \fBSIOCINQ\fP .\" FIXME . https://www.sourceware.org/bugzilla/show_bug.cgi?id=12002, .\" filed 2010-09-10, may cause SIOCINQ to be defined in glibc headers .\" SIOCOUTQ also has an effect for UNIX domain sockets, but not .\" quite what userland might expect. It seems to return the number .\" of bytes allocated for buffers containing pending output. .\" That number is normally larger than the number of bytes of pending .\" output. Since this info is, from userland's point of view, imprecise, .\" and it may well change, probably best not to document this now. Для сокетов \fBSOCK_STREAM\fP этот вызов возвращает количество непрочитанных данных в приёмном буфере. Сокет не должен быть в состоянии LISTEN, иначе возвращается ошибка (\fBEINVAL\fP). Значение \fBSIOCINQ\fP определено в \fI\fP. В качестве альтернативы можно использовать синоним \fBFIONREAD\fP, определённый в \fI\fP. Для сокетов \fBSOCK_DGRAM\fP возвращаемое значение совпадает с дейтаграммными доменными сокетами Интернета; смотрите \fBudp\fP(7). .SH ОШИБКИ .TP \fBEADDRINUSE\fP Заданный локальный адрес уже используется, или сокетный объект файловой системы уже существует. .TP \fBEBADF\fP Эта ошибка может возникать в \fBsendmsg\fP(2) при отправке файлового дескриптора в вспомогательных данных через доменный сокет UNIX (смотрите описание \fBSCM_RIGHTS\fP выше), и указывает на то, что отправляемый номер файлового дескриптора некорректен (например, не является открытым файловым дескриптором). .TP \fBECONNREFUSED\fP Удалённый адрес, указанный \fBconnect\fP(2) не является слушающим сокетом. Эта ошибка также может возникнуть, если путь назначения не является сокетом. .TP \fBECONNRESET\fP Удалённый сокет был неожиданно закрыт. .TP \fBEFAULT\fP Некорректный адрес пользовательской памяти. .TP \fBEINVAL\fP Передан неправильный аргумент. Основная причина \(em не задано значение \fBAF_UNIX\fP в поле \fIsun_type\fP передаваемых адресов или сокет находится в некорректном состоянии для производимой операции. .TP \fBEISCONN\fP Вызов \fBconnect\fP(2) запущен для уже соединённого сокета, или адрес назначения указывает на соединённый сокет. .TP \fBENFILE\fP Достигнуто максимальное количество открытых файлов в системе. .TP \fBENOENT\fP Путь, указанный в удалённом адресе для \fBconnect\fP(2), не существует. .TP \fBENOMEM\fP Не хватает памяти. .TP \fBENOTCONN\fP Для операции над сокетом требуется адрес назначения, а сокет не соединён. .TP \fBEOPNOTSUPP\fP Вызвана потоковая операция для не потокового сокета, или произведена попытка использования параметра для внеполосных данных. .TP \fBEPERM\fP Отправитель указал неправильную информацию (credentials) в структуре \fIstruct ucred\fP. .TP \fBEPIPE\fP Удалённый сокет был закрыт в потоковом сокете. Если разрешено, также будет послан сигнал \fBSIGPIPE\fP. Этого можно избежать, передав флаг \fBMSG_NOSIGNAL\fP при вызове \fBsend\fP(2) или \fBsendmsg\fP(2). .TP \fBEPROTONOSUPPORT\fP Указанный протокол не является \fBAF_UNIX\fP. .TP \fBEPROTOTYPE\fP Удалённый сокет не совпадает с типом локального сокета (\fBSOCK_DGRAM\fP против \fBSOCK_STREAM\fP). .TP \fBESOCKTNOSUPPORT\fP Неизвестный тип сокета. .TP \fBESRCH\fP While sending an ancillary message containing credentials (\fBSCM_CREDENTIALS\fP), the caller specified a PID that does not match any existing process. .TP \fBETOOMANYREFS\fP Эта ошибка может возникнуть в \fBsendmsg\fP(2) при передаче через доменный сокет UNIX в качестве вспомогательных данных файлового дескриптора (смотрите описание \fBSCM_RIGHTS\fP выше). Это происходит, если количество файловых дескрипторов «в полёте» превышает ограничитель ресурса \fBRLIMIT_NOFILE\fP и вызывающий не имеет мандата \fBCAP_SYS_RESOURCE\fP. Файловым дескриптором в полёте считается посланный с помощью \fBsendmsg\fP(2), но ещё не принятый процессом\-получателем с помощью \fBrecvmsg\fP(2). .IP .\" commit 712f4aad406bb1ed67f3f98d04c044191f0ff593 Данная ошибка выявляется начиная с Linux 4.5 (и в некоторых старых версиях, в которые перенесено исправление). В ранних версиях ядра было возможно получить неограниченное количество файловых дескрипторов в полёте, посылая каждый файловый дескриптор с помощью \fBsendmsg\fP(2) и затем закрывая файловый дескриптор, и таким образом он не учитывался в ограничителе ресурса \fBRLIMIT_NOFILE\fP. .PP При создании сокетного объекта на уровне сокетов или файловой системы могут генерироваться другие ошибки. За дополнительной информацией обращайтесь к соответствующей справочной странице. .SH ВЕРСИИ \fBSCM_CREDENTIALS\fP и абстрактное пространство имён появились в Linux 2.2 и не должны использоваться в переносимых программах. Некоторые клоны BSD также поддерживают передачу дополнительной информации (credential), но методы реализации передачи могут серьезно отличаться на разных системах. .SH ЗАМЕЧАНИЯ Привязка сокета к имени файла создаёт сокет в файловой системе, который должен быть удалён создателем, когда необходимость в нём отпадёт (с помощью \fBunlink\fP(2)). Обычная система ссылок UNIX также подходит для работы с сокетами; сокет может быть удалён в любое время, а реальное удаление из файловой системы будет произведено при закрытии последней на него ссылки. .PP To pass file descriptors or credentials over a \fBSOCK_STREAM\fP socket, you must send or receive at least one byte of nonancillary data in the same \fBsendmsg\fP(2) or \fBrecvmsg\fP(2) call. .PP .\" В потоковых доменных сокетах UNIX отсутствует такое понятие как внеполосные данные. .SH ДЕФЕКТЫ .\" The behavior on Solaris is quite similar. При привязке сокета к адресу Linux является одной из реализаций, которые добавляют конечный null, если он отсутствует в \fIsun_path\fP. В большинстве случаев в этом нет проблемы: когда адрес сокета возвращается, он будет на один байт длиннее чем был перед привязкой сокета. Однако такое неожиданное поведение может привести к следующему: если передаётся 108 не\-null байтов при привязке сокета, то с дополнительным конечным null пути превышает длину \fIsizeof(sun_path)\fP. В последствии при возврате адреса сокета (например, из \fBaccept\fP(2)), если входной аргумент \fIaddrlen\fP перед вызовом был равен \fIsizeof(struct sockaddr_un)\fP, то в \fIsun_path\fP возвращаемой структуры адреса \fIбудет отсутствовать\fP конечный null. .PP .\" i.e., traditional BSD Также, некоторые реализации не требуют наличия конечного null при привязке сокета (для определения длины \fIsun_path\fP используется аргумент \fIaddrlen\fP) и когда в этих реализациях возвращается адрес сокета, то в \fIsun_path\fP также отсутствует конечный null. .PP Приложения, которые получают адрес сокета могут содержать код (переносимый) для обработки случая, когда нет конечного null в \fIsun_path\fP, учитывая фактическое количество пригодных байт в пути: .PP .in +4n .EX strnlen(addr.sun_path, addrlen \- offsetof(sockaddr_un, sun_path)) .EE .in .\" The following patch to amend kernel behavior was rejected: .\" http://thread.gmane.org/gmane.linux.kernel.api/2437 .\" Subject: [patch] Fix handling of overlength pathname in AF_UNIX sun_path .\" 2012-04-17 .\" And there was a related discussion in the Austin list: .\" http://thread.gmane.org/gmane.comp.standards.posix.austin.general/5735 .\" Subject: Having a sun_path with no null terminator .\" 2012-04-18 .\" .\" FIXME . Track http://austingroupbugs.net/view.php?id=561 .PP Или же приложение может перед получением адреса сокета выделить буфер размера \fIsizeof(struct sockaddr_un)+1\fP, который будет обнулён перед возвращением. Возвращающий вызов может задать в \fIaddrlen\fP значение \fIsizeof(struct sockaddr_un)\fP, и дополнительный нулевой байт здесь будет конечным null в строке, возвращаемой в \fIsun_path\fP: .PP .in +4n .EX void *addrp; \& addrlen = sizeof(struct sockaddr_un); addrp = malloc(addrlen + 1); if (addrp == NULL) /* Handle error */ ; memset(addrp, 0, addrlen + 1); \& if (getsockname(sfd, (struct sockaddr *) addrp, &addrlen)) == \-1) /* handle error */ ; \& printf("sun_path = %s\en", ((struct sockaddr_un *) addrp)\->sun_path); .EE .in .PP Данного беспорядка можно избежать, если гарантировать, что приложения, \fIсоздающие\fP путевые сокеты, следуют правилам, описанным в общих чертах выше в \fIПутевые сокеты\fP. .SH ПРИМЕРЫ В следующем коде демонстрируется использование пакето\-упорядочивающих сокетов для локального межпроцессного обмена. Он состоит из двух программ. Программа\-сервер ждёт подключения программы\-клиента. Клиент посылает свой каждый аргумент командной строки в виде отдельного сообщения. Сервер считает входящие сообщения как целые числа и складывает их. Клиент посылает строку\-команду «END». Сервер посылает ответное сообщение, содержащее сумму чисел клиента. Клиент печатает сумму и завершает работу. Сервер ждёт подключение следующего клиента. Для остановки сервера, клиент вызывается с аргументом командной строки «DOWN». .PP Следующий вывод был записан при работе сервера в фоновом режиме и повторяющемся запуске клиента. Выполнение программы\-сервера завершилось после получения им команды «DOWN». .SS "Пример вывода" .in +4n .EX $ \fB./server &\fP [1] 25887 $ \fB./client 3 4\fP Результат = 7 $ \fB./client 11 \-5\fP Результат = 6 $ \fB./client DOWN\fP Результат = 0 [1]+ Done ./server $ .EE .in .SS "Исходный код программы" \& .EX /* * File connection.h */ \& #define SOCKET_NAME "/tmp/9Lq7BNBnBycd6nxy.socket" #define BUFFER_SIZE 12 \& /* * File server.c */ \& #include #include #include #include #include #include #include "connection.h" \& int main(int argc, char *argv[]) { struct sockaddr_un name; int down_flag = 0; int ret; int connection_socket; int data_socket; int result; char buffer[BUFFER_SIZE]; \& /* Create local socket. */ \& connection_socket = socket(AF_UNIX, SOCK_SEQPACKET, 0); if (connection_socket == \-1) { perror("socket"); exit(EXIT_FAILURE); } \& /* * For portability clear the whole structure, since some * implementations have additional (nonstandard) fields in * the structure. */ \& memset(&name, 0, sizeof(name)); \& /* Bind socket to socket name. */ \& name.sun_family = AF_UNIX; strncpy(name.sun_path, SOCKET_NAME, sizeof(name.sun_path) \- 1); \& ret = bind(connection_socket, (const struct sockaddr *) &name, sizeof(name)); if (ret == \-1) { perror("bind"); exit(EXIT_FAILURE); } \& /* * Prepare for accepting connections. The backlog size is set * to 20. So while one request is being processed other requests * can be waiting. */ \& ret = listen(connection_socket, 20); if (ret == \-1) { perror("listen"); exit(EXIT_FAILURE); } \& /* This is the main loop for handling connections. */ \& for (;;) { \& /* Wait for incoming connection. */ \& data_socket = accept(connection_socket, NULL, NULL); if (data_socket == \-1) { perror("accept"); exit(EXIT_FAILURE); } \& result = 0; for (;;) { \& /* Wait for next data packet. */ \& ret = read(data_socket, buffer, sizeof(buffer)); if (ret == \-1) { perror("read"); exit(EXIT_FAILURE); } \& /* Ensure buffer is 0\-terminated. */ \& buffer[sizeof(buffer) \- 1] = 0; \& /* Handle commands. */ \& if (!strncmp(buffer, "DOWN", sizeof(buffer))) { down_flag = 1; break; } \& if (!strncmp(buffer, "END", sizeof(buffer))) { break; } \& /* Add received summand. */ \& result += atoi(buffer); } \& /* Send result. */ \& sprintf(buffer, "%d", result); ret = write(data_socket, buffer, sizeof(buffer)); if (ret == \-1) { perror("write"); exit(EXIT_FAILURE); } \& /* Close socket. */ \& close(data_socket); \& /* Quit on DOWN command. */ \& if (down_flag) { break; } } \& close(connection_socket); \& /* Unlink the socket. */ \& unlink(SOCKET_NAME); \& exit(EXIT_SUCCESS); } \& /* * File client.c */ \& #include #include #include #include #include #include #include #include "connection.h" \& int main(int argc, char *argv[]) { struct sockaddr_un addr; int ret; int data_socket; char buffer[BUFFER_SIZE]; \& /* Create local socket. */ \& data_socket = socket(AF_UNIX, SOCK_SEQPACKET, 0); if (data_socket == \-1) { perror("socket"); exit(EXIT_FAILURE); } \& /* * For portability clear the whole structure, since some * implementations have additional (nonstandard) fields in * the structure. */ \& memset(&addr, 0, sizeof(addr)); \& /* Connect socket to socket address. */ \& addr.sun_family = AF_UNIX; strncpy(addr.sun_path, SOCKET_NAME, sizeof(addr.sun_path) \- 1); \& ret = connect(data_socket, (const struct sockaddr *) &addr, sizeof(addr)); if (ret == \-1) { fprintf(stderr, "The server is down.\en"); exit(EXIT_FAILURE); } \& /* Send arguments. */ \& for (size_t i = 1; i < argc; ++i) { ret = write(data_socket, argv[i], strlen(argv[i]) + 1); if (ret == \-1) { perror("write"); break; } } \& /* Request result. */ \& strcpy(buffer, "END"); ret = write(data_socket, buffer, strlen(buffer) + 1); if (ret == \-1) { perror("write"); exit(EXIT_FAILURE); } \& /* Receive result. */ \& ret = read(data_socket, buffer, sizeof(buffer)); if (ret == \-1) { perror("read"); exit(EXIT_FAILURE); } \& /* Ensure buffer is 0\-terminated. */ \& buffer[sizeof(buffer) \- 1] = 0; \& printf("Result = %s\en", buffer); \& /* Close socket. */ \& close(data_socket); \& exit(EXIT_SUCCESS); } .EE .PP For examples of the use of \fBSCM_RIGHTS\fP, see \fBcmsg\fP(3) and \fBseccomp_unotify\fP(2). .SH "СМ. ТАКЖЕ" \fBrecvmsg\fP(2), \fBsendmsg\fP(2), \fBsocket\fP(2), \fBsocketpair\fP(2), \fBcmsg\fP(3), \fBcapabilities\fP(7), \fBcredentials\fP(7), \fBsocket\fP(7), \fBudp\fP(7) .PP .SH ПЕРЕВОД Русский перевод этой страницы руководства был сделан Azamat Hackimov , Dmitriy Ovchinnikov , Dmitry Bolkhovskikh , Katrin Kutepova , Yuri Kozlov и Иван Павлов . .PP Этот перевод является бесплатной документацией; прочитайте .UR https://www.gnu.org/licenses/gpl-3.0.html Стандартную общественную лицензию GNU версии 3 .UE или более позднюю, чтобы узнать об условиях авторского права. Мы не несем НИКАКОЙ ОТВЕТСТВЕННОСТИ. .PP Если вы обнаружите ошибки в переводе этой страницы руководства, пожалуйста, отправьте электронное письмо на .MT man-pages-ru-talks@lists.sourceforge.net .ME .