signal

title: signal(7)

summary: обзор сигналов

text:
# signal(7)

## ИМЯ
signal - обзор сигналов

## ОПИСАНИЕ
В Linux поддерживаются надёжные (reliable) сигналы POSIX (далее, «стандартные сигналы») и сигналы реального времени POSIX.

### Обработчики сигнала
Каждый сигнал имеет текущий обработчик, который определяет, что будет делать процесс при поступлении сигнала.

В таблице далее есть столбец «Действие», в котором указан обработчик по умолчанию для каждого сигнала:

Term

Действие по умолчанию — завершение процесса.

Ign

Действие по умолчанию — игнорирование сигнала.

Core

Действие по умолчанию — завершение процесса и вывод дампа в файл (смотрите core(5)).

Stop

Действие по умолчанию — остановка процесса.

Cont

Действие по умолчанию — продолжение работы процесса, если он в данный момент остановлен.

Процесс может изменить обработчик сигнала с помощью sigaction(2) или signal(2) (последний менее переносим, если используется для установки обработчика сигнала; дополнительную информацию смотрите в signal(2)). Используя данные системные вызовы процесс может выбрать одно из следующих действий при получении сигнала: выполнить действие по умолчанию, игнорировать сигнал, поймать сигнал обработчиком сигнала — функцией, задаваемой программистом, которая автоматически вызывается при получении сигнала.

По умолчанию обработчик сигнала использует обычный стек процесса. Возможно сделать так, чтобы обработчик сигнала использовал альтернативный стек; как это делается и когда это может быть полезно смотрите в sigaltstack(2).

Реакция на сигналы является атрибутом процесса: в многонитевом приложении реакция на определённый сигнал одинакова для всех нитей.

Потомок, созданный с помощью fork(2), наследует реакцию на сигналы от своего родителя. При execve(2) реакция на сигналы устанавливается в значение по умолчанию; реакция на игнорируемые сигналы не изменяется.

### Отправка сигнала
Для отправки сигнала можно использовать следующие системные вызовы и библиотечные функции:

raise(3)

Посылает сигнал вызвавшей нити.

kill(2)

Посылает сигнал указанному процессу, всем членам указанной группы процессов или всем процессам в системе.

killpg(3)

Посылает сигнал всем членам указанной группы процессов.

pthread_kill(3)

Посылает сигнал указанной нити POSIX в том же процессе, что и вызывающий.

tgkill(2)

Посылает сигнал указанной нити в указанном процессе (данный системный вызов используется в реализации pthread_kill(3)).

sigqueue(3)

Посылает сигнал реального времени указанному процессу с сопроводительными данными.

### Ожидание сигнала для обработки
Следующие системные вызовы приостанавливают выполнение вызывающей нити до тех пор, пока не будет пойман сигнал (или необработанный сигнал не завершит процесс):

pause(2)

Приостанавливает выполнение до тех пор, пока не будет пойман любой сигнал.

sigsuspend(2)

Временно изменяет маску сигналов (смотрите далее) и приостанавливает выполнение до получения одного из незамаскированных сигналов.

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

- С помощью sigwaitinfo(2), sigtimedwait(2) и sigwait(3). Они приостанавливают выполнение до поступления одного из заданного набора сигналов. Каждый из этих вызовов возвращает информацию о полученном сигнале.

- С помощью signalfd(2). Данный вызов возвращает файловый дескриптор, который можно использовать для чтения информации о сигналах, доставляемых вызывающему. Каждое выполнение read(2) с этим файловым дескриптором блокируется до тех пор, пока один из сигналов набора, указанного в вызове signalfd(2), не будет послан вызывающему. В возвращаемом read(2) буфере содержится структура, описывающая сигнал.

### Сигнальная маска и ожидающие сигналы
Сигнал может быть заблокирован. Это означает, что он не будет доставлен до тех пор, пока не будет разблокирован. В промежуток времени от генерации сигнала и до его доставки о сигнале говорят как об ожидающем.

В каждой нити процесса имеется независимая сигнальная маска, определяющая набор сигналов, которые нить, в данный момент, блокирует. Нить может управлять сигнальной маской с помощью pthread_sigmask(3). В обычном однонитевом приложении для работы с сигнальной маской можно использовать вызов sigprocmask(2).

Потомок, создаваемый с помощью fork(2), наследует копию родительской маски сигналов; маска сигналов сохраняется при вызове execve(2).

Сигнал может быть направлен процессу или нити. Направленный процессу сигнал предназначен (и ожидается) для процесса в целом. Сигнал может быть направлен процессу ядром из-за аппаратного исключения или с помощью kill(2) или sigqueue(3). Направленный нити сигнал предназначен определённой нити. Сигнал может быть направлен нити, так как был сгенерирован при выполнении определённой инструкции машинного языка, которая привела к аппаратному исключению (например, SIGSEGV при некорректном доступен к памяти или SIGFPE при математической ошибке), или направлен определённой нити с помощью интерфейса tgkill(2) или pthread_kill(3).

Направленный процессу сигнал может быть доставлен в любую из нитей, у которой сигнал не заблокирован. Если имеется несколько таких нитей, то ядро выбирает произвольную нить, которой и доставит сигнал.

Нить может получить набор сигналов, которые находятся в состоянии ожидания с помощью вызова sigpending(2). Этот набор будет состоять из объединения набора ожидающих сигналов, направленных процессу, и набора ожидающих сигналов для вызвавшей нити.

Потомок, созданный с помощью fork(2), первоначально имеет пустой набор ожидающих сигналов; набор ожидающих сигналов сохраняется при вызове execve(2).

### Стандартные сигналы
Linux поддерживает стандартные сигналы, перечисленные далее. Во второй колонке таблицы указан стандарт (если есть), которым введён сигнал, например, «P1990» — сигнал описан в первоначальной версии стандарта POSIX.1-1990; «P2001» — сигнал добавлен в SUSv2 и POSIX.1-2001.

Сигнал

Стандарт

Действие

Комментарий

SIGABRT

P1990

Core

Сигнал аварии (abort), посланный abort(3)

SIGALRM

P1990

Term

Сигнал таймера, посланный alarm(2)

SIGBUS

P2001

Core

Ошибка шины (некорректный адрес доступа)

SIGCHLD

P1990

Ign

Потомок остановлен или завершился

SIGCLD

-

Ign

Синоним SIGCHLD

SIGCONT

P1990

Cont

Продолжить, если остановлен

SIGEMT

-

Term

Ловушка эмулятора

SIGFPE

P1990

Core

Ошибка операций с плавающей запятой

SIGHUP

P1990

Term

Обнаружен обрыв связи с управляющим

терминалом, либо завершение управляющего терминалом процесса

SIGILL

P1990

Core

Недопустимая инструкция

SIGINFO

-

Синоним SIGPWR

SIGINT

P1990

Term

Прерывание с клавиатуры

SIGIO

-

Term

Теперь возможен ввод/вывод (4.2BSD)

SIGIOT

-

Core

Ловушка IOT. Синоним SIGABRT

SIGKILL

P1990

Term

Kill-сигнал

SIGLOST

-

Term

Утрачена блокировка файла (не используется)

SIGPIPE

P1990

Term

Обрыв канала: запись в канал без

читателей; смотрите pipe(7)

SIGPOLL

P2001

Term

Опрашиваемое событие (Sys V)

Синоним SIGIO

SIGPROF

P2001

Term

Время профилирования истекло

SIGPWR

-

Term

Отказ питания (System V)

SIGQUIT

P1990

Core

Выход с клавиатуры

SIGSEGV

P1990

Core

Некорректная ссылка в память

SIGSTKFLT

-

Term

Ошибка стека на сопроцессоре (не используется)

SIGSTOP

P1990

Stop

Остановить процесс

SIGTSTP

P1990

Stop

Останов введён с терминала

SIGSYS

P2001

Core

Неправильный системный вызов (SVr4);

смотрите также seccomp(2)

SIGTERM

P1990

Term

Сигнал завершения

SIGTRAP

P2001

Core

Прерывание из-за трассировки/останова

SIGTTIN

P1990

Stop

Ввод с терминала для фонового процесса

SIGTTOU

P1990

Stop

Вывод с терминала для фонового процесса

SIGUNUSED

-

Core

Синоним SIGSYS

SIGURG

P2001

Ign

Требующее внимание условие сокета (4.2BSD)

SIGUSR1

P1990

Term

Определяемый пользователем сигнал 1

SIGUSR2

P1990

Term

Определяемый пользователем сигнал 2

SIGVTALRM

P2001

Term

Виртуальный будильник (4.2BSD)

SIGXCPU

P2001

Core

Превышен предел процессорного времени (4.2BSD);

смотрите setrlimit(2)

SIGXFSZ

P2001

Core

Превышен предел размера файла (4.2BSD);

смотрите setrlimit(2)

SIGWINCH

-

Ign

Сигнал изменения размера окна (4.3BSD, Sun)

Сигналы SIGKILL и SIGSTOP нельзя поймать, заблокировать или проигнорировать.

В Linux до версии 2.2 включительно поведением по умолчанию для сигналов SIGSYS, SIGXCPU, SIGXFSZ и SIGBUS (на всех архитектурах кроме SPARC и MIPS) было завершение процесса без создания дампа (в некоторых системах UNIX действием по умолчанию для SIGXCPU и SIGXFSZ является завершение процесса без создания дампа). Linux версии 2.4 соответствует требованиям POSIX.1-2001 для этих сигналов и завершает процесс с созданием дампа.

Сигнал SIGEMT не определён в POSIX.1-2001, но, тем не менее, появляется почти во всех системах UNIX, где действием по умолчанию для него является завершение процесса с созданием дампа.

Сигнал SIGPWR (не определён в POSIX.1-2001) по умолчанию, обычно, игнорируется (в других системах UNIX).

Для сигнала SIGIO (не определён в POSIX.1-2001) в других системах UNIX действием по умолчанию является игнорирование.

### Семантика очерёдности и доставки стандартных сигналов
Если несколько стандартных сигналов ожидают обработки процессом, то порядок доставки сигналов не определён.

Стандартные сигналы не упорядочиваются. Если генерируется несколько экземпляров стандартного сигнала заблокированному процессу, то только один экземпляр сигнала помечается как ожидающий (и сигнал будет доставлен только после разблокировки). В случае, если уже есть ожидающий стандартный сигнал, структура siginfo_t (смотрите sigaction(2)), связанная с этим сигналом, не перезаписывается при поступлении последующих экземпляров того же сигнала. То есть, процесс получит информацию, связанную с первым экземпляром сигнала.

### Нумерация стандартных сигналов
Числовое значение каждого сигнала показано в таблице ниже. У многих сигналов номера различаются на разных архитектурах. Первое числовое значение в каждой строке таблицы описывает номер сигнала на x86, ARM и большинстве других архитектур; второе значение для Alpha и SPARC, третье для MIPS, последнее для PARISC. Символ минус (-) означает, что сигнал отсутствует в соответствующей архитектуре.

Сигнал

x86/ARM

Alpha/

MIPS

PARISC

Примечания

большинство других

SPARC

SIGHUP

1

1

1

1

SIGINT

2

2

2

2

SIGQUIT

3

3

3

3

SIGILL

4

4

4

4

SIGTRAP

5

5

5

5

SIGABRT

6

6

6

6

SIGIOT

6

6

6

6

SIGBUS

7

10

10

10

SIGEMT

-

7

7

-

SIGFPE

8

8

8

8

SIGKILL

9

9

9

9

SIGUSR1

10

30

16

16

SIGSEGV

11

11

11

11

SIGUSR2

12

31

17

17

SIGPIPE

13

13

13

13

SIGALRM

14

14

14

14

SIGTERM

15

15

15

15

SIGSTKFLT

16

-

-

7

SIGCHLD

17

20

18

18

SIGCLD

-

-

18

-

SIGCONT

18

19

25

26

SIGSTOP

19

17

23

24

SIGTSTP

20

18

24

25

SIGTTIN

21

21

26

27

SIGTTOU

22

22

27

28

SIGURG

23

16

21

29

SIGXCPU

24

24

30

12

SIGXFSZ

25

25

31

30

SIGVTALRM

26

26

28

20

SIGPROF

27

27

29

21

SIGWINCH

28

28

20

23

SIGIO

29

23

22

22

SIGPOLL

Тот же, что SIGIO

SIGPWR

30

29/-

19

19

SIGINFO

-

29/-

-

-

SIGLOST

-

-/29

-

-

SIGSYS

31

12

12

31

SIGUNUSED

31

-

-

31

Также заметим следующее:

- Если определён сигнал SIGUNUSED, то он является синонимом SIGSYS. Начиная с glibc 2.26, определение SIGUNUSED удалено из всех архитектур.

- Сигнал с номером 29 на Alpha соответствует SIGINFO/SIGPWR (одинаковый номер), а на SPARC соответствует SIGLOST.

### Сигналы реального времени
Начиная с версии 2.2, Linux поддерживает сигналы реального времени согласно первоначальному описанию расширений реального времени в POSIX.1b (теперь включено в POSIX.1-2001). Диапазон поддерживаемых сигналов реального времени определяется макросами SIGRTMIN и SIGRTMAX. Согласно POSIX.1-2001 требуется, чтобы реализация поддерживала не менее _POSIX_RTSIG_MAX (8) сигналов реального времени.

Ядро Linux поддерживает 33 таких сигнала, начиная с номера 32 до номера 64. Однако внутри реализации нитей POSIX в glibc используется два (для NPTL) или три (для LinuxThreads) сигнала реального времени (смотрите pthreads(7)), а значение SIGRTMIN корректируется должным образом (до 34 или 35). Так как диапазон доступных сигналов реального времени различается в зависимости от реализации нитей в glibc (и это может происходить во время выполнения при смене ядра и glibc), и, более того, диапазон сигналов реального времени различен в разных системах UNIX, то программы никогда не должны задавать сигналы реального времени по номерам, а вместо этого всегда должны записывать их в виде SIGRTMIN+n и выполнять проверку (во время выполнения), что SIGRTMIN+n не превышает SIGRTMAX.

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

Действием по умолчанию для необработанных сигналов реального времени является завершение процесса (terminate).

Сигналы реального времени отличаются от обычных в следующем:

1.

В очередь можно добавлять несколько экземпляров одного сигнала реального времени. В случае со стандартными сигналами, если доставляется несколько экземпляров сигнала, в то время как этот тип сигнала в данный момент заблокирован, то только один экземпляр будет добавлен в очередь.

2.

Если сигнал отправляется с помощью sigqueue(3), то с сигналом может быть отправлено некоторое значение (целочисленное, либо указатель). Если принимающий процесс устанавливает обработчик для сигнала, используя флаг SA_SIGINFO и вызов sigaction(2), то он может получить это значение через поле si_value структуры siginfo_t, переданной обработчику в виде второго аргумента. Кроме этого, поля si_pid и si_uid данной структуры можно использовать для получения идентификатора процесса и реального идентификатора пользователя, отправившего сигнал.

3.

Сигналы реального времени доставляются точно в порядке поступления. Несколько сигналов одного типа доставляются в порядке, определяемых их отправлением. Если процессу отправлено несколько разных сигналов реального времени, то порядок их доставки начинается с сигнала с наименьшим номером (то есть сигналы с наименьшим номером имеют наивысший приоритет). Порядок же для стандартных сигналов в такой ситуации не определён.

Если процессу передан и стандартный сигнал, и сигнал реального времени, то в POSIX однозначно не определено, какой из них будет доставлен первым. В Linux, как и во многих других реализациях в таких случаях, отдан приоритет стандартным сигналам.

В соответствии с POSIX, реализация должна позволять ставить в очередь процесса, как минимум, _POSIX_SIGQUEUE_MAX (32) сигнала реального времени. Однако в Linux это делается по-другому. В ядрах до версии 2.6.7 включительно, Linux накладывает общесистемный лимит на количество сигналов режима реального времени в очереди для всех процессов. Этот лимит может быть получен и изменён (если есть права) через файл /proc/sys/kernel/rtsig-max. Текущее количество сигналов режима реального времени в очереди можно получить из файла /proc/sys/kernel/rtsig-nr. В Linux 2.6.8 данные интерфейсы /proc были заменены на ограничение ресурса RLIMIT_SIGPENDING, которое устанавливает ограничение на очередь сигналов на каждого пользователя отдельно; дополнительную информацию можно найти в setrlimit(2).

Для дополнительных сигналов реального времени требуется расширение структуры набора сигналов (sigset_t) с 32 до 64 бит. В связи с этим, различные системные вызовы заменены на новые системные вызов, поддерживающие набор сигналов большего размера. Вот соответствие старых и новых системных вызовов:

Linux версии 2.0 и более ранние

Linux версии 2.2 и новее

sigaction(2)

rt_sigaction(2)

sigpending(2)

rt_sigpending(2)

sigprocmask(2)

rt_sigprocmask(2)

sigreturn(2)

rt_sigreturn(2)

sigsuspend(2)

rt_sigsuspend(2)

sigtimedwait(2)

rt_sigtimedwait(2)

### Прерывание системных вызовов и библиотечных функций обработчиками сигналов
Если обработчик сигнала вызван во время заблокированного системного вызова или библиотечной функции, то может произойти следующее:

- вызов автоматически перезапускается после возврата из обработчика сигнала; или

- вызов завершается с ошибкой EINTR.

Выбираемое поведение зависит от интерфейса и от того, был ли обработчик сигнала установлен с флагом SA_RESTART (смотрите sigaction(2)). Но в различных системах UNIX есть другие различия; далее описаны подробности для Linux.

Если заблокированный вызов к одному из следующих интерфейсов прерван обработчиком сигнала, то вызов автоматически перезапускается после завершения обработчика сигнала, если задействован флаг SA_RESTART; иначе вызов завершается ошибкой EINTR:

- Вызовы read(2), readv(2), write(2), writev(2) и ioctl(2) для «медленных» устройств. «Медленным» называют устройство, которое может навсегда заблокировать ввод-вывод, например, терминал, канал или сокет. Если вызов ввода-вывода для медленного устройства уже передал немного данных на момент прерывания обработчиком сигнала, то вызов вернёт состояние успешного выполнения (обычно, количество переданных байт). Заметим, что диск (локальный) не подходит под определение медленного устройства; операции ввода-вывода с дисками не прерываются сигналами.

- Вызов open(2), если он может выполнить блокировку (например, при открытии FIFO; смотрите fifo(7)).

- Вызовы wait(2), wait3(2), wait4(2), waitid(2) и waitpid(2).

- Интерфейсы сокетов: accept(2), connect(2), recv(2), recvfrom(2), recvmmsg(2), recvmsg(2), send(2), sendto(2) и sendmsg(2), если для сокета не указано время ожидания (смотрите далее).

- Интерфейсы файловой блокировки: flock(2) и операции F_SETLKW и F_OFD_SETLKW у fcntl(2).

- Интерфейсы очереди сообщений POSIX: mq_receive(3), mq_timedreceive(3), mq_send(3) и mq_timedsend(3).

- Вызов futex(2) с FUTEX_WAIT (начиная с Linux 2.6.22; до этой версии вызов завершался с ошибкой EINTR).

- getrandom(2).

- pthread_mutex_lock(3), pthread_cond_wait(3) связанный с этим программный интерфейс.

- futex(2) FUTEX_WAIT_BITSET.

- Интерфейсы семафоров POSIX: sem_wait(3) и sem_timedwait(3) (начиная с Linux 2.6.22; до этой версии вызовы завершались с ошибкой EINTR).

- Вызов read(2) из файлового дескриптора inotify(7) (начиная с Linux 3.8; прежде всегда завершался с ошибкой EINTR).

Следующие интерфейсы никогда не перезапускаются после прерывания обработчиком сигнала независимо от наличия SA_RESTART; они всегда завершаются с ошибкой EINTR, если прерываются обработчиком сигнала:

- «Входные» интерфейсы сокетов, если установлен таймаут (SO_RCVTIMEO) на сокете с помощью setsockopt(2): accept(2), recv(2), recvfrom(2), recvmmsg(2) (также с аргументом timeout, не равным NULL) и recvmsg(2).

- «Выходные» интерфейсы сокетов, если установлен таймаут (SO_RCVTIMEO) на сокете с помощью setsockopt(2): connect(2), send(2), sendto(2) и sendmsg(2).

- Интерфейсы, используемые для ожидания сигналов: pause(2), sigsuspend(2), sigtimedwait(2) и sigwaitinfo(2).

- Интерфейсы комбинирования (multiplexing) файловых дескрипторов: epoll_wait(2), epoll_pwait(2), poll(2), ppoll(2), select(2) и pselect(2).

- IPC-интерфейсы System V: msgrcv(2), msgsnd(2), semop(2) и semtimedop(2).

- Интерфейсы сна: clock_nanosleep(2), nanosleep(2) и usleep(3).

- io_getevents(2).

Функция sleep(3) также никогда не перезапускается, если прервана обработчиком сигнала, но сообщает об успешном выполнении: возвращает количество оставшиеся для сна секунд.

### Прерывание системных вызовов и библиотечных функций сигналами останова
В Linux, даже в отсутствии обработчиков сигнала, некоторые блокирующие интерфейсы могут завершаться с ошибкой EINTR, если процесс останавливается одним из сигналов останова и затем возобновляет работу при получении сигнала SIGCONT. Такое поведение не предусмотрено POSIX.1 и в других системах отсутствует.

Интерфейсы Linux, к которым это относится:

- «Входные» интерфейсы сокетов, если установлен таймаут (SO_RCVTIMEO) на сокете с помощью setsockopt(2): accept(2), recv(2), recvfrom(2), recvmmsg(2) (также с аргументом timeout, не равным NULL) и recvmsg(2).

- «Выходные» интерфейсы сокетов, если установлен таймаут (SO_RCVTIMEO) на сокете с помощью setsockopt(2): connect(2), send(2), sendto(2) и sendmsg(2), если установлен таймаут отправления (SO_SNDTIMEO).

- epoll_wait(2), epoll_pwait(2).

- semop(2), semtimedop(2).

- sigtimedwait(2), sigwaitinfo(2).

- Linux 3.7 и старее: read(2) из файлового дескриптора inotify(7)

- Linux версии 2.6.21 и более ранних: futex(2) с FUTEX_WAIT, sem_timedwait(3), sem_wait(3).

- Linux версии 2.6.8 и более ранних: msgrcv(2), msgsnd(2).

- Linux версии 2.4 и более ранних: nanosleep(2).

## СООТВЕТСТВИЕ СТАНДАРТАМ
POSIX.1, кроме описанных исключений.

## ЗАМЕЧАНИЯ
Описание безопасных асинхронных функций при работе с сигналами смотрите в signal-safety(7).

В файле /proc/[pid]/task/[tid]/status содержатся различные поля о сигналах, которые нить блокирует (SigBlk), ловит (SigCgt) или игнорирует (SigIgn). Набор отлавливаемые или игнорируемых сигналов одинаков для всех нитей процесса. Остальные поля отражают набор ожидающих сигналов, которые непосредственно направляются нити (SigPnd), а также набор ожидающих сигналов, которые направляются непосредственно процессу (ShdPnd). Соответствующие поля в /proc/[pid]/status содержат информацию для главной нити. Дополнительную информацию смотрите в proc(5).

## СМОТРИТЕ ТАКЖЕ
kill(1), clone(2), getrlimit(2), kill(2), restart_syscall(2), rt_sigqueueinfo(2), setitimer(2), setrlimit(2), sgetmask(2), sigaction(2), sigaltstack(2), signal(2), signalfd(2), sigpending(2), sigprocmask(2), sigreturn(2), sigsuspend(2), sigwaitinfo(2), abort(3), bsd_signal(3), killpg(3), longjmp(3), pthread_sigqueue(3), raise(3), sigqueue(3), sigset(3), sigsetops(3), sigvec(3), sigwait(3), strsignal(3), sysv_signal(3), core(5), proc(5), nptl(7), pthreads(7), sigevent(7)


signal-safety

package: man-pages-ru

title: signal-safety(7)

summary: функции async\-signal\-safe

text:
# signal-safety(7)

## ИМЯ
signal-safety - функции async-signal-safe

## ОПИСАНИЕ
Функцией async-signal-safe называется функция, которую безопасно вызывать внутри обработчика сигналов. Многие функции не являются async-signal-safe. В частности, нереентерабельные функции, обычно, небезопасно вызывать в обработчиках сигналов.

Виды проблем, которые делают функцию небезопасной, можно быстро понять на примере реализации библиотеки stdio, все функции которой являются не async-signal-safe.

При выполнении буферизируемого ввода-вывода в файл функции stdio должны вести статически выделенный буфер и связанные с ним счётчики и индексы (или указатели), содержащие количество данных и текущее положение в буфере. Предположим, что основная программа находится в середине вызова функции stdio, например printf(3), которая обновляет часть буфера и связанных переменных. Если в этот момент программа прервётся обработчиком сигнала, который также вызывает printf(3), то второй вызов printf(3) будет работать с не целостными данными и результат будет непредсказуем.

Чтобы не возникало проблем с небезопасными функциями есть два варианта:

1.

Следить, чтобы (а) обработчик сигнала вызывал только функции async-signal-safe, и (б) сам обработчик сигнала был реентерабельным по отношению к глобальным переменным основной программы.

2.

Блокировать доставку сигнала в основной программе при вызове небезопасных функций или при работе с глобальными данными, доступными из обработчика сигнала.

Обычно, второй вариант труден для программ любой сложности, поэтому используется первый вариант.

В POSIX.1 определён набор функций, реализация которых должна быть async-signal-safe (реализация может предоставлять безопасную реализацию и других функций, но это не требуется стандартом и другие реализации могут не предоставлять те же гарантии) Обычно, функция является async-signal-safe или потому что она реентерабельная, или из-за её атомарности по отношению к сигналам (т. е., её выполнение не может быть прервано обработчиком сигнала).

Набор функций async-signal-safe по POSIX.1 показан в таблице далее. Функции, если не указано обратное, являются async-signal-safe и по POSIX.1-2001; в таблице отмечены изменения в последующих стандартах.

функция

Примечания

abort(3)

Добавлена в POSIX.1-2003

accept(2)

access(2)

aio_error(3)

aio_return(3)

aio_suspend(3)

смотрите замечания далее

alarm(2)

bind(2)

cfgetispeed(3)

cfgetospeed(3)

cfsetispeed(3)

cfsetospeed(3)

chdir(2)

chmod(2)

chown(2)

clock_gettime(2)

close(2)

connect(2)

creat(2)

dup(2)

dup2(2)

execl(3)

Добавлена в POSIX.1-2008; смотрите замечания ниже

execle(3)

смотрите замечания далее

execv(3)

Добавлена в POSIX.1-2008

execve(2)

_exit(2)

_Exit(2)

faccessat(2)

Добавлена в POSIX.1-2008

fchdir(2)

Добавлена в POSIX.1-2013

fchmod(2)

fchmodat(2)

Добавлена в POSIX.1-2008

fchown(2)

fchownat(2)

Добавлена в POSIX.1-2008

fcntl(2)

fdatasync(2)

fexecve(3)

Добавлена в POSIX.1-2008

ffs(3)

Добавлена в POSIX.1-2016

fork(2)

смотрите замечания далее

fstat(2)

fstatat(2)

Добавлена в POSIX.1-2008

fsync(2)

ftruncate(2)

futimens(3)

Добавлена в POSIX.1-2008

getegid(2)

geteuid(2)

getgid(2)

getgroups(2)

getpeername(2)

getpgrp(2)

getpid(2)

getppid(2)

getsockname(2)

getsockopt(2)

getuid(2)

htonl(3)

Добавлена в POSIX.1-2016

htons(3)

Добавлена в POSIX.1-2016

kill(2)

link(2)

linkat(2)

Добавлена в POSIX.1-2008

listen(2)

longjmp(3)

Добавлена в POSIX.1-2016; смотрите замечания ниже

lseek(2)

lstat(2)

memccpy(3)

Добавлена в POSIX.1-2016

memchr(3)

Добавлена в POSIX.1-2016

memcmp(3)

Добавлена в POSIX.1-2016

memcpy(3)

Добавлена в POSIX.1-2016

memmove(3)

Добавлена в POSIX.1-2016

memset(3)

Добавлена в POSIX.1-2016

mkdir(2)

mkdirat(2)

Добавлена в POSIX.1-2008

mkfifo(3)

mkfifoat(3)

Добавлена в POSIX.1-2008

mknod(2)

Добавлена в POSIX.1-2008

mknodat(2)

Добавлена в POSIX.1-2008

ntohl(3)

Добавлена в POSIX.1-2016

ntohs(3)

Добавлена в POSIX.1-2016

open(2)

openat(2)

Добавлена в POSIX.1-2008

pause(2)

pipe(2)

poll(2)

posix_trace_event(3)

pselect(2)

pthread_kill(3)

Добавлена в POSIX.1-2013

pthread_self(3)

Добавлена в POSIX.1-2013

pthread_sigmask(3)

Добавлена в POSIX.1-2013

raise(3)

read(2)

readlink(2)

readlinkat(2)

Добавлена в POSIX.1-2008

recv(2)

recvfrom(2)

recvmsg(2)

rename(2)

renameat(2)

Добавлена в POSIX.1-2008

rmdir(2)

select(2)

sem_post(3)

send(2)

sendmsg(2)

sendto(2)

setgid(2)

setpgid(2)

setsid(2)

setsockopt(2)

setuid(2)

shutdown(2)

sigaction(2)

sigaddset(3)

sigdelset(3)

sigemptyset(3)

sigfillset(3)

sigismember(3)

siglongjmp(3)

Добавлена в POSIX.1-2016; смотрите замечания ниже

signal(2)

sigpause(3)

sigpending(2)

sigprocmask(2)

sigqueue(2)

sigset(3)

sigsuspend(2)

sleep(3)

sockatmark(3)

Добавлена в POSIX.1-2004

socket(2)

socketpair(2)

stat(2)

stpcpy(3)

Добавлена в POSIX.1-2016

stpncpy(3)

Добавлена в POSIX.1-2016

strcat(3)

Добавлена в POSIX.1-2016

strchr(3)

Добавлена в POSIX.1-2016

strcmp(3)

Добавлена в POSIX.1-2016

strcpy(3)

Добавлена в POSIX.1-2016

strcspn(3)

Добавлена в POSIX.1-2016

strlen(3)

Добавлена в POSIX.1-2016

strncat(3)

Добавлена в POSIX.1-2016

strncmp(3)

Добавлена в POSIX.1-2016

strncpy(3)

Добавлена в POSIX.1-2016

strnlen(3)

Добавлена в POSIX.1-2016

strpbrk(3)

Добавлена в POSIX.1-2016

strrchr(3)

Добавлена в POSIX.1-2016

strspn(3)

Добавлена в POSIX.1-2016

strstr(3)

Добавлена в POSIX.1-2016

strtok_r(3)

Добавлена в POSIX.1-2016

symlink(2)

symlinkat(2)

Добавлена в POSIX.1-2008

tcdrain(3)

tcflow(3)

tcflush(3)

tcgetattr(3)

tcgetpgrp(3)

tcsendbreak(3)

tcsetattr(3)

tcsetpgrp(3)

time(2)

timer_getoverrun(2)

timer_gettime(2)

timer_settime(2)

times(2)

umask(2)

uname(2)

unlink(2)

unlinkat(2)

Добавлена в POSIX.1-2008

utime(2)

utimensat(2)

Добавлена в POSIX.1-2008

utimes(2)

Добавлена в POSIX.1-2008

wait(2)

waitpid(2)

wcpcpy(3)

Добавлена в POSIX.1-2016

wcpncpy(3)

Добавлена в POSIX.1-2016

wcscat(3)

Добавлена в POSIX.1-2016

wcschr(3)

Добавлена в POSIX.1-2016

wcscmp(3)

Добавлена в POSIX.1-2016

wcscpy(3)

Добавлена в POSIX.1-2016

wcscspn(3)

Добавлена в POSIX.1-2016

wcslen(3)

Добавлена в POSIX.1-2016

wcsncat(3)

Добавлена в POSIX.1-2016

wcsncmp(3)

Добавлена в POSIX.1-2016

wcsncpy(3)

Добавлена в POSIX.1-2016

wcsnlen(3)

Добавлена в POSIX.1-2016

wcspbrk(3)

Добавлена в POSIX.1-2016

wcsrchr(3)

Добавлена в POSIX.1-2016

wcsspn(3)

Добавлена в POSIX.1-2016

wcsstr(3)

Добавлена в POSIX.1-2016

wcstok(3)

Добавлена в POSIX.1-2016

wmemchr(3)

Добавлена в POSIX.1-2016

wmemcmp(3)

Добавлена в POSIX.1-2016

wmemcpy(3)

Добавлена в POSIX.1-2016

wmemmove(3)

Добавлена в POSIX.1-2016

wmemset(3)

Добавлена в POSIX.1-2016

write(2)

Замечания:

- В POSIX.1-2001 и POSIX.1-2004 требуется, чтобы функции fpathconf(3), pathconf(3) и sysconf(3) были async-signal-safe, но это требование удалено в POSIX.1-2008.

- Если обработчик сигнала прерывает выполнение небезопасной функции и обработчик завершается вызовом longjmp(3) или siglongjmp(3) и далее программа вызывает небезопасную функцию, то поведение программы непредсказуемо.

- В POSIX.1-2003 уточнено, что если приложение вызывает fork(2) из обработчика сигнала и и зарегистрированный обработчик fork (с помощью pthread_atfork(3)) вызывает не async-signal-safe функцию, то поведение непредсказуемо. Вероятно, в будущих версиях стандарта вызов fork(2) будет удалён из списка функций async-signal-safe.

### Отклонения в библиотеке GNU C
В библиотеке GNU C есть следующие известные отклонения от стандарта:

- До glibc 2.24 внутри execl(3) и execle(3) использовалась realloc(3) и поэтому они были не безопасны для асинхронных сигналов. Это было исправлено в glibc 2.24.

- Реализация aio_suspend(3) в glibc не является безопасной для асинхронных сигналов, так как в ней используется pthread_mutex_lock(3).

## СМОТРИТЕ ТАКЖЕ
sigaction(2), signal(7), standards(7)

branch: sisyphus


title: sock_diag(7)

summary: возвращает информацию о сокетах

text:
# sock_diag(7)

## ИМЯ
sock_diag - возвращает информацию о сокетах

## ОБЗОР

```
#include <sys/socket.h>
#include <linux/sock_diag.h>
#include <linux/unix_diag.h> /* для доменных сокетов UNIX */
#include <linux/inet_diag.h> /* для сокетов IPv4 и IPv6 */
```

```
diag_socket = socket(AF_NETLINK, socket_type, NETLINK_SOCK_DIAG);
```

## ОПИСАНИЕ
Подсистема sock_diag netlink предоставляет механизм получения информации о сокетах различных семейств адресов из ядра. Данная подсистема может использоваться для получения информации об отдельных сокетах или запрашивать список сокетов.

В запросе вызывающий может указать дополнительную информацию, которую хочется узнать о сокетах, например, информацию о памяти или характерную семейству адресов.

Когда запрашивается список сокетов вызывающий может задать фильтры, которые будут применены ядром для выбора возвращаемого набора сокетов. В настоящее время, фильтровать сокеты можно только по состоянию (соединён, слушает и т. д.).

Заметим, что sock_diag возвращает только сокеты с именем; то есть, явно привязанные сокеты с помощью bind(2) или автоматически привязанные к адресу сокеты (например, с помощью connect(2)). Данный набор сокетов совпадает со списком в /proc/net/unix, /proc/net/tcp, /proc/net/udp и т. п.

### Запрос
Запрос начинается с заголовка struct nlmsghdr, описанного в netlink(7), в котором поле nlmsg_type равно SOCK_DIAG_BY_FAMILY. За ним следует заголовок, соответствующий семейству адресов, начинающийся с общей части, используемой для всех семейств адресов:

```
struct sock_diag_req {

    __u8 sdiag_family;

    __u8 sdiag_protocol;
};
```

Поля этой структуры имеют следующее назначение:

sdiag_family

Семейство адресов. Должна быть указана соответствующая константа AF_*.

sdiag_protocol

Зависит от sdiag_family. Должна быть указана соответствующая константа IPPROTO_* при AF_INET и AF_INET6, и 0 в остальных случаях.

Если в поле nlmsg_flags заголовка struct nlmsghdr установлен флаг NLM_F_DUMP, то это означает, что запрашивается список сокетов; в противном случае запрашивается информация об конкретном сокете.

### Ответ
Ответ начинается с заголовка struct nlmsghdr, за которым следует массив объектов, соответствующих семейству адресов. Массив доступен через стандартные макросы из NLMSG_* программного интерфейса netlink(3).

Каждый объект представляет собой список NLA (атрибутов netlink), которые доступны через макросы RTA_* программного интерфейса rtnetlink(3).

### Доменные сокеты UNIX
Запрос доменных сокетов UNIX описывается в следующей структуре:

```
struct unix_diag_req {

    __u8    sdiag_family;

    __u8    sdiag_protocol;

    __u16   pad;

    __u32   udiag_states;

    __u32   udiag_ino;

    __u32   udiag_show;

    __u32   udiag_cookie[2];
};
```

Поля этой структуры имеют следующее назначение:

sdiag_family

Семейство адресов; должно быть равно AF_UNIX.

sdiag_protocol

pad

Эти поля должны быть равны 0.

udiag_states

Битовая маска, описывающая фильтр состояний сокетов. Будут возвращены только сокеты с состояниями из этой маски. Игнорируется, если запрашивается конкретный сокет. Поддерживаемые значения:

1 << TCP_ESTABLISHED 1 << TCP_LISTEN

udiag_ino

Номер иноды при запросе конкретного сокета. Игнорируется, если запрашивается список сокетов.

udiag_show

Набор флагов, определяющий тип возвращаемой информации. Каждый запрашиваемый тип информации возвращается в виде атрибута netlink, описанного ниже:

UDIAG_SHOW_NAME

Атрибут, возвращаемый в ответе на этот запрос — UNIX_DIAG_NAME. Полезные данные, связанные с этим атрибутом — путь, с которым был связан сокет (последовательность байт длиной до UNIX_PATH_MAX).

UDIAG_SHOW_VFS

Атрибут, возвращаемый в ответе на этот запрос — UNIX_DIAG_VFS. Полезные данные, связанные с этим атрибутом представляются следующей структурой:

```
struct unix_diag_vfs {

    __u32 udiag_vfs_dev;

    __u32 udiag_vfs_ino;
};

```

Поля этой структуры имеют следующее назначение:

udiag_vfs_dev

Номер устройства, соответствующего иноде сокета на диске.

udiag_vfs_ino

Номер иноды, соответствующей иноде сокета на диске.

UDIAG_SHOW_PEER

Атрибут, возвращаемый в ответе на этот запрос — UNIX_DIAG_PEER. Полезные данные, связанные с этим атрибутом — значение __u32, представляющее номер иноды ответной стороны. Данный атрибут возвращается только для соединённых сокетов.

UDIAG_SHOW_ICONS

Атрибут, возвращаемый в ответе на этот запрос — UNIX_DIAG_ICONS. Полезные данные, связанные с этим атрибутом — значения __u32, представляющие номера инод сокетов, которые переданы вызову connect(2), но ещё не были обработаны accept(2). Данный атрибут возвращается, если запрашивается список сокетов.

UDIAG_SHOW_RQLEN

Атрибут, возвращаемый в ответе на этот запрос — UNIX_DIAG_RQLEN. Полезные данные, связанные с этим атрибутом представляются следующей структурой:

```
struct unix_diag_rqlen {

    __u32 udiag_rqueue;

    __u32 udiag_wqueue;
};

```

Поля этой структуры имеют следующее назначение:

udiag_rqueue

Для слушающих сокетов: количество ожидающих подключений. Этому значению равна длина массива, связанного с атрибутом ответа UNIX_DIAG_ICONS.

Для сокетов с установленным соединением: количество данных во входящей очереди.

udiag_wqueue

Для слушающих сокетов: длина недодела (backlog), равная значению, переданному во втором аргументе listen(2).

Для сокетов с установленным соединением: количество памяти, доступной при отправке.

UDIAG_SHOW_MEMINFO

Атрибут, возвращаемый в ответе на этот запрос — UNIX_DIAG_MEMINFO. Полезные данные, связанные с этим атрибутом представляют собой массив значений с типом __u32,описанный далее в подразделе «Информация о памяти сокетов».

Следующие атрибуты возвращаются для любого запроса:

UNIX_DIAG_SHUTDOWN

Полезные данные, связанные с этим атрибутом, имеют тип __u8 и представляют биты состояния из shutdown(2).

udiag_cookie

Массив скрытых идентификаторов, которые можно использовать вместе с udiag_ino для указания определённого сокета. Игнорируется при запросе списка сокетов, а также когда все его элементы равны -1.

Ответ на запрос о доменных сокетах UNIX представляется в виде массива

```
struct unix_diag_msg {

    __u8    udiag_family;

    __u8    udiag_type;

    __u8    udiag_state;

    __u8    pad;

    __u32   udiag_ino;

    __u32   udiag_cookie[2];
};
```

и следует за атрибутами netlink.

Поля этой структуры имеют следующее назначение:

udiag_family

Данное поле имеет то же значение что в struct unix_diag_req.

udiag_type

Может быть SOCK_PACKET, SOCK_STREAM или SOCK_SEQPACKET.

udiag_state

Может быть TCP_LISTEN или TCP_ESTABLISHED.

pad

Это поле равно 0.

udiag_ino

Номер иноды сокета.

udiag_cookie

Массив скрытых идентификаторов, которые можно использовать в последующих запросах.

### Сокеты IPv4 и IPv6
Запрос сокетов IPv4 и IPv6 описывается в следующей структуре:

```
struct inet_diag_req_v2 {

    __u8    sdiag_family;

    __u8    sdiag_protocol;

    __u8    idiag_ext;

    __u8    pad;

    __u32   idiag_states;

    struct inet_diag_sockid id;
};
```

где struct inet_diag_sockid определена как:

```
struct inet_diag_sockid {

    __be16  idiag_sport;

    __be16  idiag_dport;

    __be32  idiag_src[4];

    __be32  idiag_dst[4];

    __u32   idiag_if;

    __u32   idiag_cookie[2];
};
```

Поля struct inet_diag_req_v2:

sdiag_family

Должно быть равно AF_INET или AF_INET6 для сокетов IPv4 или IPv6, соответственно.

sdiag_protocol

Должно быть равно IPPROTO_TCP, IPPROTO_UDP или IPPROTO_UDPLITE.

idiag_ext

Набор флагов, определяющий тип возвращаемой расширенной информации. Каждый запрашиваемый тип информации возвращается в виде атрибута netlink, описанного ниже:

INET_DIAG_TOS

Полезные данные, связанные с этим атрибутом, имеют тип __u8 и представляют TOS сокета.

INET_DIAG_TCLASS

Полезные данные, связанные с этим атрибутом, имеют тип __u8 и представляют TClass сокета. Только для сокетов IPv6. Для сокетов LISTEN и CLOSE эти данные следуют за атрибутом INET_DIAG_SKV6ONLY с значением полезных данных (тип __u8), описывающим является ли сокет только IPv6 или нет.

INET_DIAG_MEMINFO

Полезные данные, связанные с этим атрибутом представляются следующей структурой:

```
struct inet_diag_meminfo {

    __u32 idiag_rmem;

    __u32 idiag_wmem;

    __u32 idiag_fmem;

    __u32 idiag_tmem;
};

```

Поля этой структуры имеют следующее назначение:

idiag_rmem

Количество данных в приёмной очереди.

idiag_wmem

Количество данных, помещённых в очередь TCP и ещё не отправленных.

idiag_fmem

Объём памяти, запланированной для использования в будущем (только TCP).

idiag_tmem

Количество данных в очереди отправки.

INET_DIAG_SKMEMINFO

Полезные данные, связанные с этим атрибутом представляют собой массив значений с типом __u32,описанный далее в подразделе «Информация о памяти сокетов».

INET_DIAG_INFO

Полезные данные, связанные с этим атрибутом, относятся к определённому семейству адресов. Для сокетов TCP объект имеет тип struct tcp_info.

INET_DIAG_CONG

Полезные данные, связанные с этим атрибутом, представляют собой строку, описывающую используемый алгоритм контроля перегрузки. Только для сокетов TCP.

pad

Должно равняться 0.

idiag_states

Битовая маска, описывающая фильтр состояний сокета. Будут возвращены только сокеты с состояниями из этой маски. Игнорируется, если запрашивается конкретный сокет.

id

Идентификатор объекта сокета, использующийся при запросах дампа, в опросах отдельных сокетов и возвращается в каждом ответе. В отличие от доменных сокетов UNIX, сокеты IPv4 и IPv6 опознаются по адресам и портам. Все значения указываются в сетевом порядке байт.

Поля struct inet_diag_sockid:

idiag_sport

Порт отправителя.

idiag_dport

Порт получателя.

idiag_src

Адрес отправителя.

idiag_dst

Адрес получателя.

idiag_if

Интерфейсный номер к которому привязан сокет.

idiag_cookie

Массив скрытых идентификаторов, которые можно использовать вместе с другими полями этой структуры для указания определённого сокета. Игнорируется при запросе списка сокетов, а также когда все его элементы равны -1.

Ответ на запрос о сокетах IPv4 или IPv6 представляется в виде массива

```
struct inet_diag_msg {

    __u8    idiag_family;

    __u8    idiag_state;

    __u8    idiag_timer;

    __u8    idiag_retrans;

    struct inet_diag_sockid id;

    __u32   idiag_expires;

    __u32   idiag_rqueue;

    __u32   idiag_wqueue;

    __u32   idiag_uid;

    __u32   idiag_inode;
};
```

и следует за атрибутами netlink.

Поля этой структуры имеют следующее назначение:

idiag_family

Это тоже поле что и в struct inet_diag_req_v2.

idiag_state

Обозначает состояние сокета как в struct inet_diag_req_v2.

idiag_timer

Для сокетов TCP это поле описывает тип активного в данный момент таймера сокета. Задаётся одной из следующих констант:

0

таймер не активен

1

таймер повторной передачи

2

таймер поддержания соединения

3

таймер TIME_WAIT

4

таймер проверки нулевым окном

Для сокетов не TCP, значение этого поля равно 0.

idiag_retrans

Если idiag_timer содержит 1, 2 и 4, то это поле содержит количество повторных передач. При других значениях idiag_timer это поле равно 0.

idiag_expires

Для сокетов TCP, имеющих активный таймер, это поле описывает его время окончания в миллисекундах. Для других сокетов значение этого поля равно 0.

idiag_rqueue

Для слушающих сокетов: количество ожидающих подключений.

Для других сокетов: количество данных во входящей очереди.

idiag_wqueue

Для слушающих сокетов: длина недодела (backlog).

Для других сокетов: количество памяти, доступной при отправке.

idiag_uid

Идентификатор пользователя, владеющего сокетом.

idiag_inode

Номер иноды сокета.

### Информация о памяти сокетов
Полезные данные, связанные с атрибутами netlink UNIX_DIAG_MEMINFO и INET_DIAG_SKMEMINFO, представляют собой массив следующих значений с типом __u32:

SK_MEMINFO_RMEM_ALLOC

Количество данных в приёмной очереди.

SK_MEMINFO_RCVBUF

Приёмный буфер сокета, заданный SO_RCVBUF.

SK_MEMINFO_WMEM_ALLOC

Количество данных в очереди отправки.

SK_MEMINFO_SNDBUF

Буфер отправки сокета, заданный SO_SNDBUF.

SK_MEMINFO_FWD_ALLOC

Объём памяти, запланированной для использования в будущем (только TCP).

SK_MEMINFO_WMEM_QUEUED

Количество данных, помещённых в очередь TCP, но ещё не отправленных.

SK_MEMINFO_OPTMEM

Объем памяти, выделенный для служебных нужд сокета (например, для сокетного фильтра).

SK_MEMINFO_BACKLOG

Количество пакетов в памяти недодела (не обработанных).

## ВЕРСИИ
Программный интерфейс NETLINK_INET_DIAG появился в Linux 2.6.14 и поддерживал только сокеты AF_INET и AF_INET6. В Linux 3.3 он был переименован в NETLINK_SOCK_DIAG и появилась поддержка сокетов AF_UNIX.

Программный интерфейс UNIX_DIAG_MEMINFO и INET_DIAG_SKMEMINFO появился в Linux 3.6.

## СООТВЕТСТВИЕ СТАНДАРТАМ
Программный интерфейс NETLINK_SOCK_DIAG есть только в Linux.

## ПРИМЕР
Следующий пример программы печатает номер иноды, номер иноды противоположной стороны и имена всех доменных сокетов UNIX в текущем пространстве имён.

```
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <linux/sock_diag.h>
#include <linux/unix_diag.h>
static int
send_query(int fd)
{

    struct sockaddr_nl nladdr = {

        .nl_family = AF_NETLINK

    };

    struct

    {

        struct nlmsghdr nlh;

        struct unix_diag_req udr;

    } req = {

        .nlh = {

            .nlmsg_len = sizeof(req),

            .nlmsg_type = SOCK_DIAG_BY_FAMILY,

            .nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP

        },

        .udr = {

            .sdiag_family = AF_UNIX,

            .udiag_states = -1,

            .udiag_show = UDIAG_SHOW_NAME | UDIAG_SHOW_PEER

        }

    };

    struct iovec iov = {

        .iov_base = &req,

        .iov_len = sizeof(req)

    };

    struct msghdr msg = {

        .msg_name = (void *) &nladdr,

        .msg_namelen = sizeof(nladdr),

        .msg_iov = &iov,

        .msg_iovlen = 1

    };

    for (;;) {

        if (sendmsg(fd, &msg, 0) < 0) {

            if (errno == EINTR)

                continue;

            perror("sendmsg");

            return -1;

        }

        return 0;

    }
}
static int
print_diag(const struct unix_diag_msg *diag, unsigned int len)
{

    if (len < NLMSG_LENGTH(sizeof(*diag))) {

        fputs("короткий ответ\n", stderr);

        return -1;

    }

    if (diag->udiag_family != AF_UNIX) {

        fprintf(stderr, "неожиданное семейство %u\n", diag->udiag_family);

        return -1;

    }

    struct rtattr *attr;

    unsigned int rta_len = len - NLMSG_LENGTH(sizeof(*diag));

    unsigned int peer = 0;

    size_t path_len = 0;

    char path[sizeof(((struct sockaddr_un *) 0)->sun_path) + 1];

    for (attr = (struct rtattr *) (diag + 1);

             RTA_OK(attr, rta_len); attr = RTA_NEXT(attr, rta_len)) {

        switch (attr->rta_type) {

        case UNIX_DIAG_NAME:

            if (!path_len) {

                path_len = RTA_PAYLOAD(attr);

                if (path_len > sizeof(path) - 1)

                    path_len = sizeof(path) - 1;

                memcpy(path, RTA_DATA(attr), path_len);

                path[path_len] = '\0';

            }

            break;

        case UNIX_DIAG_PEER:

            if (RTA_PAYLOAD(attr) >= sizeof(peer))

                peer = *(unsigned int *) RTA_DATA(attr);

            break;

        }

    }

    printf("инода=%u", diag->udiag_ino);

    if (peer)

        printf(", другая сторона=%u", peer);

    if (path_len)

        printf(", имя=%s%s", *path ? "" : "@",

                *path ? path : path + 1);

    putchar('\n');

    return 0;
}
static int
receive_responses(int fd)
{

    long buf[8192 / sizeof(long)];

    struct sockaddr_nl nladdr = {

        .nl_family = AF_NETLINK

    };

    struct iovec iov = {

        .iov_base = buf,

        .iov_len = sizeof(buf)

    };

    int flags = 0;

    for (;;) {

        struct msghdr msg = {

            .msg_name = (void *) &nladdr,

            .msg_namelen = sizeof(nladdr),

            .msg_iov = &iov,

            .msg_iovlen = 1

        };

        ssize_t ret = recvmsg(fd, &msg, flags);

        if (ret < 0) {

            if (errno == EINTR)

                continue;

            perror("recvmsg");

            return -1;

        }

        if (ret == 0)

            return 0;

        const struct nlmsghdr *h = (struct nlmsghdr *) buf;

        if (!NLMSG_OK(h, ret)) {

            fputs("!NLMSG_OK\n", stderr);

            return -1;

        }

        for (; NLMSG_OK(h, ret); h = NLMSG_NEXT(h, ret)) {

            if (h->nlmsg_type == NLMSG_DONE)

                return 0;

            if (h->nlmsg_type == NLMSG_ERROR) {

                const struct nlmsgerr *err = NLMSG_DATA(h);

                if (h->nlmsg_len < NLMSG_LENGTH(sizeof(*err))) {

                    fputs("NLMSG_ERROR\n", stderr);

                } else {

                    errno = -err->error;

                    perror("NLMSG_ERROR");

                }

                return -1;

            }

            if (h->nlmsg_type != SOCK_DIAG_BY_FAMILY) {

                fprintf(stderr, "неожиданный nlmsg_type %u\n",

                        (unsigned) h->nlmsg_type);

                return -1;

            }

            if (print_diag(NLMSG_DATA(h), h->nlmsg_len))

                return -1;

        }

    }
}
int
main(void)
{

    int fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_SOCK_DIAG);

    if (fd < 0) {

        perror("socket");

        return 1;

    }

    int ret = send_query(fd) || receive_responses(fd);

    close(fd);

    return ret;
}
```

## СМОТРИТЕ ТАКЖЕ
netlink(3), rtnetlink(3), netlink(7), tcp(7)


socket

title: socket(7)

summary: интерфейс сокетов Linux

text:
# socket(7)

## ИМЯ
socket - интерфейс сокетов Linux

## ОБЗОР
\#include <sys/socket.h>

sockfd = socket(int socket_family, int socket_type, int protocol);

## ОПИСАНИЕ
В этой справочной странице описывается пользовательский интерфейс уровня сетевых сокетов Linux. Совместимый с сокетами BSD, он предоставляет унифицированный интерфейс между пользовательскими процессами и стеком сетевых протоколов в ядре. Модули протоколов группируются по семействам протоколов, такими, как AF_INET, AF_IPX и AF_PACKET, и типам сокетов, такими, как SOCK_STREAM или SOCK_DGRAM. Более подробная информация о семействах и типах приведена в socket(2).

### Функции уровня сокетов
Эти функции используются пользовательскими процессами для отправки или приёма пакетов и выполнения других операций над сокетами. Более подробная информация приведена в соответствующих справочных страницах.

Вызов socket(2) создаёт сокет, connect(2) соединяет сокет с удалённым сокетным адресом, bind(2) привязывает сокет к локальному адресу, listen(2) сообщает сокету, что должны приниматься новые соединения, а accept(2) используется для получения нового сокета для нового входящего соединения. Вызов socketpair(2) возвращает два соединённых анонимных сокета (реализовано только для некоторых локальных семейств, например AF_UNIX).

Вызовы send(2), sendto(2) и sendmsg(2) отправляют данные в сокет, а recv(2), recvfrom(2) и recvmsg(2) принимают данные из сокета. Вызовы poll(2) и select(2) ожидают поступления данных или готовятся к передаче данных. Кроме того, для чтения и записи данных могут использоваться стандартные операции ввода-вывода: write(2), writev(2), sendfile(2), read(2) и readv(2).

Вызов getsockname(2) возвращает адрес локального сокета, а getpeername(2) возвращает адрес удалённого сокета. Вызовы getsockopt(2) и setsockopt(2) используются для установки или считывания параметров протокола или уровня сокетов. Вызов ioctl(2) может быть использован для установки или чтения некоторых других параметров.

Вызов close(2) используется для закрытия сокета. Вызов shutdown(2) закрывает части полнодуплексного сокетного соединения.

Перемещение (seeking), или вызовы pread(2) и pwrite(2) с ненулевой позицией, для сокетов не поддерживается.

Для сокетов возможно создание неблокирующего ввода/вывода путём установки в файловый дескриптор сокета флага O_NONBLOCK с помощью вызова fcntl(2). При этом все блокировавшие раньше операции, будут возвращать EAGAIN (операция должна быть повторена позднее); connect(2) возвратит ошибку EINPROGRESS. Пользователь может подождать наступления различных событий через poll(2) или select(2).

События ввода-вывода

Событие

Флаг poll

Когда происходит

Чтение

POLLIN

Поступили новые данные.

Чтение

POLLIN

Установка соединения выполнена (для сокетов с установлением соединения)

Чтение

POLLHUP

Другая сторона инициировала запрос на разъединение.

Чтение

POLLHUP

Соединение разорвано (только для протоколов с установлением соединения). Если производится запись в сокет, то также посылается сигнал SIGPIPE.

Запись

POLLOUT

Сокет имеет достаточно места в буфере отправки для записи в него новых данных.

Чтение/Запись

POLLIN | POLLOUT

Исходящий connect(2) завершён.

Чтение/Запись

POLLERR

Произошла асинхронная ошибка.

Чтение/Запись

POLLHUP

Другая сторона закрыла (shut down) одно направление.

Исключение

POLLPRI

Пришли неотложные данные. После посылается сигнал SIGURG.

Альтернативе poll(2) и select(2) в ядре существует возможность информировать приложение о событиях с помощью сигнала SIGIO. Для этого необходимо установить с помощью fcntl(2) в файловом дескрипторе сокета флаг O_ASYNC, а также назначить с помощью sigaction(2) корректный обработчик сигнала SIGIO. Смотрите ниже раздел Сигналы.

### Структуры адреса сокета
Каждый сокетный домен имеет свой формат сокетных адресов, выраженный в отдельной адресной структуре. Каждая из этих структур начинается с целочисленного поля «семейства» (с типом sa_family_t), в котором указывается тип адресной структуры. Это позволяет различным системным вызовам (например, connect(2), bind(2), accept(2), getsockname(2), getpeername(2)), которые являются общими для всех сокетов, определить домен конкретного сокетного адреса.

Для передачи сокетного адреса любого типа через программный интерфейс сокетов служит тип struct sockaddr. Целью данного типа является приведение типов сокетных адресов определённого домена к «общему» типу, что позволяет избежать предупреждений компилятора о несовпадении типов в вызовах API сокетов.

Также, программный интерфейс сокетов предоставляет тип данных struct sockaddr_storage. Данный тип удобен для размещения всех поддерживаемых структур сокетных адресов определённого домена; он достаточно большой и имеет корректное выравнивание (в частности, он позволяет хранить сокетные адреса IPv6). Для определения типа сокетного адреса, который хранится в структуре, служит следующее поле:

```
    sa_family_t ss_family;
```

Структура sockaddr_storage полезна для программ, которые должны работать с сокетными адресами единообразно (например, в программах, использующих одновременно сокетные адреса IPv4 и IPv6).

### Параметры сокетов
Следующие параметры сокета могут быть установлены с помощью setsockopt(2) или прочитаны с помощью getsockopt(2) с уровнем сокета, равным SOL_SOCKET для всех сокетов:

SO_ACCEPTCONN

Определить, был или не был данный сокет помечен для прослушивания и приёма соединений с помощью listen(2). Возвращаемое значение 0 обозначает, что это не прослушивающий сокет. Значение 1 обозначает, что это прослушивающий сокет. Данный параметр сокета доступен только для чтения.

SO_ATTACH_FILTER (начиная с Linux 2.2), SO_ATTACH_BPF (начиная с Linux 3.19)

Присоединить классическую (SO_ATTACH_FILTER) или расширенную (SO_ATTACH_BPF) программу BPF к сокету, которая будет использоваться как фильтр входящих пакетов. Пакет будет отброшен, если фильтрующая программа возвращает ноль. Если фильтрующая программа возвращает ненулевое значение, меньше длины данных пакета, то пакет будет обрезан до возвращаемой длины. Если возвращаемое фильтром значение больше или равно длине данных пакета, то пакет разрешён к обработке без изменений.

Для SO_ATTACH_FILTER аргументом является структура sock_fprog, определяемая в <linux/filter.h>:

```
struct sock_fprog {

    unsigned short      len;

    struct sock_filter *filter;
};

```

Для SO_ATTACH_BPF аргументом является файловый дескриптор, возвращаемый системным вызовом bpf(2), он должен указывать на программу с типом BPF_PROG_TYPE_SOCKET_FILTER.

Эти параметры могут быть назначены заданному сокету несколько раз, если перед этим заменять фильтрующую программу. Для одного сокета могут вызываться классическая и расширенная версии, но предыдущий фильтр всегда будет заменён, так как для сокета допускается определять не более одного фильтра.

Классический и расширенный BPF описаны в файле исходного кода ядра Documentation/networking/filter.txt.

SO_ATTACH_REUSEPORT_CBPF, SO_ATTACH_REUSEPORT_EBPF

При использовании вместе с SO_REUSEPORT эти параметры позволяют пользователю задавать классическую (SO_ATTACH_REUSEPORT_CBPF) или расширенную (SO_ATTACH_REUSEPORT_EBPF) программу BPF, которая определяет как пакеты назначаются сокетам в группе reuseport (то есть всем сокетам, у которых установлен SO_REUSEPORT, и использующим один локальный адрес для приёма пакетов).

Программа BPF должна возвращать индекс от 0 до N-1, представляющий сокет, который должен получить пакет (где N — количество сокетов в группе). Если программа BPF возвращает некорректный индекс, то выбор сокета будет выполнен с помощью простого механизма SO_REUSEPORT.

Сокеты нумеруются в порядке их добавления в группу (то есть, в порядке вызовов bind(2) для сокетов UDP и в порядке вызовов listen(2) для сокетов TCP). Новые сокеты, добавляемые в группу reuseport, будут наследовать программу BPF. Когда сокет удаляется из группы reuseport (с помощью close(2)), последний сокет в группе будет перемещён в позицию закрытого сокета.

Эти параметры могут быть повторно назначены в любое время любому сокету в группе для замены текущей программы BPF, используемой всеми сокетами в группе.

Для SO_ATTACH_REUSEPORT_CBPF учитывается тот же тип аргумента как у SO_ATTACH_FILTER, а для SO_ATTACH_REUSEPORT_EBPF учитывается тот же тип аргумента как у SO_ATTACH_BPF.

Поддержка этого свойства для UDP доступна начиная с Linux 4.5; Поддержка этого свойства для TCP доступна начиная с Linux 4.6.

SO_BINDTODEVICE

Привязать сокет к определённому устройству, например, к «eth0», в соответствии с переданным именем интерфейса. Если имя является пустой строкой или длина параметра равна нулю, то привязка сокета к устройству будет удалена. В качестве параметра передаётся оканчивающаяся null строка переменной длины с именем интерфейса, максимальная длина которого не превышает IFNAMSIZ. Если сокет привязан к интерфейсу, то сокетом обрабатываются только пакеты этого интерфейса. Заметим, что это работает только для некоторых типов сокетов, в частности, для сокетов AF_INET. Это не поддерживается для сокетов пакетной передачи (для них используйте обычный bind(2)).

До Linux 3.8, данный параметр сокета можно было устанавливать, но нельзя прочитать с помощью getsockopt(2). Начиная с Linux 3.8 он доступен для чтения. Аргумент optlen должен содержать размер буфера, способного разместить имя устройства; рекомендуемое значение — IFNAMSIZ байт. Реальная длина имени устройства возвращается обратно через аргумент optlen.

SO_BROADCAST

Задать или считать флаг широковещания. Если он установлен, то через датаграммные сокеты разрешено отправлять пакеты на широковещательный адрес. Этот параметр не действует на потоковые сокеты.

SO_BSDCOMPAT

Разрешить совместимость по ошибкам с BSD. Используется модулем протокола UDP в Linux версии 2.0 и 2.2. Если включено, то полученные UDP-сокетом ошибки ICMP не будут передаваться пользовательской программе. В последний версиях ядер поддержка этого параметра удалена: в Linux 2.4 он игнорируется, а в Linux 2.6 при использовании в программе для него генерируется предупреждение ядра (printk()). В Linux 2.0 также включён параметр совместимости по ошибкам с BSD и для неструктурированных сокетов (произвольное изменение заголовка, пропуск флага широковещательной передачи), но в Linux 2.2 это было удалено.

SO_DEBUG

Включить отладку сокета. Разрешено только процессам с мандатом CAP_NET_ADMIN или имеющим нулевой идентификатор эффективного пользователя.

SO_DETACH_FILTER (начиная с Linux 2.2), SO_DETACH_BPF (начиная с Linux 3.19)

Эти два параметра, синонимы, можно использовать для удаления классической или расширенной программы BPF, присоединённой к сокету с помощью SO_ATTACH_FILTER или SO_ATTACH_BPF. Значение параметра игнорируется.

SO_DOMAIN (начиная с Linux 2.6.32)

Получить доменный сокет в виде целого числа; пример возвращаемого значения: AF_INET6. Подробней смотрите в socket(2). Этот параметр сокета доступен только для чтения.

SO_ERROR

Получить и очистить ожидающую обработки ошибку сокета. Этот параметр сокета доступен только для чтения. Ожидает целое число.

SO_DONTROUTE

Не выполнять отправку через шлюз, посылать только на машины, соединенные напрямую. Тот же эффект может быть достигнут путём установки для сокета флага MSG_DONTROUTE во время вызова send(2). В качестве параметра ожидается целочисленный логический флаг.

SO_INCOMING_CPU (чтение, начиная с Linux 3.19; запись, начиная с Linux 4.4)

Изменяет или возвращает привязку сокета к ЦП. В качестве параметра ожидается целочисленный логический флаг.

```
int cpu = 1;
setsockopt(fd, SOL_SOCKET, SO_INCOMING_CPU, &cpu, sizeof(cpu));

```

Так как все пакеты одного потока (т. е., все пакеты одной связки 4-х значений (4-tuple)) поступают в одно очередь RX, которая связана с определённым ЦП, обычно, это используется для привязки слушающего процесса к очереди RX, чтобы входящий поток, обрабатываемый слушающим, был на том же ЦП, который обслуживает очередь RX. Это предоставляет оптимальное поведение NUMA и поддерживает кэши ЦП в актуальном состоянии.

SO_KEEPALIVE

Включить отправку «поддерживающих» (keep-alive) сообщений для сокетов, ориентированных на соединение. Ожидается целочисленный логический флаг.

SO_LINGER

Задать или считать параметр SO_LINGER. Аргументом является структура linger.

```
struct linger {

    int l_onoff;    /* задержка активна */

    int l_linger;   /* величина задержки в секундах */
};

```

Если этот параметр установлен, то close(2) или shutdown(2) не вернут управление до тех пор, пока не будут отправлены все сообщения в очереди сокета или до истечения времени задержки (linger). В противном случае вызовы вернут управление немедленно и закрытие будет произведено в фоновом режиме. Если сокет закрывается как часть вызова exit(2), то задержка всегда происходит в фоновом режиме.

SO_LOCK_FILTER

Если указан, то это запрещает изменять фильтры, связанные с сокетом. К фильтрам относятся любые, добавленные с помощью параметров сокета SO_ATTACH_FILTER SO_ATTACH_BPF SO_ATTACH_REUSEPORT_CBPF и SO_ATTACH_REUSEPORT_EBPF.

Обычно, он используется так: настраивается неструктурированный сокет привилегированного процесса (операция требует мандата CAP_NET_RAW), применяется ограничивающий фильтр, назначается параметр SO_LOCK_FILTER, а затем сбрасываются привилегии или файловый дескриптор сокета передаётся непривилегированного процессу через доменный сокет UNIX.

После установки параметра SO_LOCK_FILTER, все попытки изменить, удалить присоединённый к сокету фильтр или отключить с помощью параметра SO_LOCK_FILTER, будут завершаться с ошибкой EPERM.

SO_MARK (начиная с Linux 2.6.25)

Устанавливать метку на каждый пакет, отправленный через сокет (похоже на цель netfilter MARK, но для сокетов). Изменение метки можно использовать для маршрутизации на основе меток не задействуя netfilter или для фильтрации пакетов. Для установки этого параметра требуется мандат CAP_NET_ADMIN.

SO_OOBINLINE

Если включён этот параметр, то внепоточные данные помещаются непосредственно во входной поток данных. В противном случае внепоточные данные передаются только, если во время приёма установлен флаг MSG_OOB.

SO_PASSCRED

Включить или выключить приём управляющего сообщения SCM_CREDENTIALS. Подробней смотрите в unix(7).

SO_PASSSEC

Включить или выключить приём управляющего сообщения SCM_SECURITY. Подробней смотрите в unix(7).

SO_PEEK_OFF (начиная с Linux 3.4)

Этот параметр, который пока поддерживается только для сокетов unix(7), устанавливает значение «смещения выборки» (peek offset) для системного вызова recv(2), когда он используется с флагом MSG_PEEK.

Если этому параметру присваивается отрицательное значение (равен -1 для всех новых сокетов), то действует обычное правило: recv(2) с флагом MSG_PEEK выбирает данные из начала (front) очереди.

Если этому параметру присваивается положительное значение или ноль, то следующая выборка данных из очереди сокета произойдёт по байтовому смещению, определяемому значением этого параметра. В то же время, «смещение выборки» будет увеличено на количество байт, выбранных из очереди, то есть последовательные операции выборки возвращают следующие данные из очереди.

Если данные удалены из начала очереди с помощью вызова recv(2) (или подобного) без флага MSG_PEEK, то «смещение выборки» будет уменьшено на количество удалённых байт. Другими словами, приём данных без флага MSG_PEEK корректирует «смещение выборки» относительно поддерживаемого относительного положения данных в очереди, и последующая выборка возвратит данные, которые были бы получены, если бы данные не удалялись.

Для датаграммных сокетов, если «смещение выборки» указывает в середину пакета, то возвращаемые данные маркируются флагом MSG_TRUNC.

В следующем примере показано использование SO_PEEK_OFF. Предположим, в очереди потокового сокета есть входные данные:

aabbccddeeff

Следующая последовательность вызовов recv(2) выполнила бы то, что описано в комментариях:

```
int ov = 4;        // установка смещения выборки равной 4
setsockopt(fd, SOL_SOCKET, SO_PEEK_OFF, &ov, sizeof(ov));
recv(fd, buf, 2, MSG_PEEK);  // выборка «cc»; смещение 6
recv(fd, buf, 2, MSG_PEEK);  // выборка «dd»; смещение 8
recv(fd, buf, 2, 0);         // выборка «aa»; смещение 6
recv(fd, buf, 2, MSG_PEEK);  // выборка «ee»; смещение 8

```

SO_PEERCRED

Возвращает учётные данные (credentials) ответного процесса, подключённого к сокету. Дополнительную информацию смотрите в unix(7).

SO_PRIORITY

Установить определяемый протоколом приоритет для всех пакетов, отправляемых из этого сокета. Linux использует это значение для управления сетевыми очередями: пакеты с более высоким приоритетом могут быть обработаны раньше (в зависимости от выбранного для устройства способа постановки в очередь). Установка значения приоритета не из диапазона 0 до 6 требует мандата CAP_NET_ADMIN.

SO_PROTOCOL (начиная с Linux 2.6.32)

Получить протокол сокета в виде целого числа; пример возвращаемого значения: IPPROTO_SCTP. Подробней смотрите в socket(2). Этот параметр сокета доступен только для чтения.

SO_RCVBUF

Задать или получить максимальный размер буфера приёма сокета (в байтах). Ядро удваивает это значение (для пространства под учёт ресурсов (bookkeeping overhead)) при установке этого параметра с помощью setsockopt(2), и это удвоенное значение возвращается getsockopt(2). Значение по умолчанию устанавливается через файл /proc/sys/net/core/rmem_default, а максимальное возможное значение устанавливается через файл /proc/sys/net/core/rmem_max. Минимальное (удвоенное) значение для этого параметра равно 256.

SO_RCVBUFFORCE (начиная с Linux 2.6.14)

С помощью этого параметра сокета привилегированный (CAP_NET_ADMIN) процесс может выполнить ту же работу, что и с помощью SO_RCVBUF, но возможно превысить ограничение rmem_max.

SO_RCVLOWAT и SO_SNDLOWAT

Задать минимальное количество байт в буфере до которого уровень сокета будет отправлять данные протоколу (SO_SNDLOWAT) или получать их от пользователя (SO_RCVLOWAT). Начальное значение этих двух элементов равно 1. Для SO_SNDLOWAT значение в Linux изменить нельзя (setsockopt(2) завершает выполнение с ошибкой ENOPROTOOPT). Значение для SO_RCVLOWAT можно изменить начиная с Linux версии 2.4.

До Linux 2.6.28 select(2), poll(2) и epoll(7) не учитывают настройку SO_RCVLOWAT, и помечают сокет как доступный для чтения даже когда доступен только 1 байт данных. Последующее чтение из сокета будет заблокировано до тех пор, пока не будет доступно SO_RCVLOWAT байт.

SO_RCVTIMEO и SO_SNDTIMEO

Задать время ожидания (при отправке или приёме) до генерации сообщения об ошибке. Аргументом является структура struct timeval. Если вводящая или выводящая функция блокируется на этот период времени, и данные был отправлены или получены, то возвращаемое значение этой функции будет равно количеству переданных данных; если данные не проходили и время ожидания истекло, то возвращается -1 и errno устанавливается в EAGAIN, EWOULDBLOCK или EINPROGRESS (для connect(2)) — также как, если был сокет был заблокирован. Если время ожидания установлено в 0 (по умолчанию), то операция не будет ждать. Время ожидания учитывается только в системных вызовах, которые выполняют ввод-вывод из сокета (например, read(2), recvmsg(2), send(2), sendmsg(2)); время ожидания не учитывается в select(2), poll(2), epoll_wait(2) и подобных.

SO_REUSEADDR

Указать, что правила проверки адресов, передаваемых с помощью вызова bind(2), должны позволять повторное использование локальных адресов. В случае с сокетами AF_INET это означает, что сокет может быть привязан (bind), за исключением случаев, когда активному слушающему сокету присвоен адрес. Если слушающий сокет привязан к INADDR_ANY с определённым портом, то к этому порту невозможно будет привязать любой локальный адрес. Аргументом является целочисленный логический флаг.

SO_REUSEPORT (начиная с Linux 3.9)

Разрешить многократную привязку сокета AF_INET или AF_INET6 к одинаковому адресу сокета. Данный параметр должен быть указан на каждом сокете (включая первый сокет) до вызова bind(2). Чтобы предотвратить захват порта все привязки процессов к одному адресу должны иметь один эффективный UID. Данный параметр можно применять к сокетам TCP и UDP.

Для сокетов TCP данный параметр позволяет accept(2) распределить нагрузку в многонитевом сервере, назначая разные слушатели сокета в каждой нити. Это улучшает распределение нагрузки по сравнении с обычными методами, например с одной принимающей нитью accept(2), которая распределяет соединения, или с несколькими нитями, которые конкурируют за accept(2) единого сокета.

Для сокетов UDP использование данного параметра может улучшить распределение входящих датаграмм по нескольким процессам (или нитям) по сравнении с обычным методом с несколькими процессами, которые конкурируют при приёме датаграмм из единого сокета.

SO_RXQ_OVFL (начиная с Linux 2.6.33)

Указывает, что к принятым skbs должно быть прикреплено вспомогательное сообщение (cmsg) с беззнаковым 32-битным значением, которое обозначает количество пакетов, отброшенных сокетом с момента его создания.

SO_SNDBUF

Задать или считать максимальный размер буфера отправки сокета (в байтах). Ядро удваивает это значение (для пространства под учёт ресурсов (bookkeeping overhead)) при установке этого параметра с помощью setsockopt(2), и это удвоенное значение возвращается getsockopt(2). Значение по умолчанию устанавливается через файл /proc/sys/net/core/wmem_default, а максимальное возможное значение устанавливается через файл /proc/sys/net/core/wmem_max. Минимальное (удвоенное) значение для этого параметра равно 2048.

SO_SNDBUFFORCE (начиная Linux 2.6.14)

С помощью этого параметра сокета привилегированный (CAP_NET_ADMIN) процесс может выполнить ту же работу, что и с помощью SO_SNDBUF, но возможно превысить ограничение wmem_max.

SO_TIMESTAMP

Включить или выключить приём управляющего сообщения SO_TIMESTAMP. Управляющее сообщение метки времени посылается с уровнем SOL_SOCKET, а поле cmsg_data выражено структурой struct timeval, обозначающей время приёма последнего пакета, переданного пользователю в этом вызове. Подробней об управляющих сообщениях смотрите в cmsg(3).

SO_TYPE

Получить тип сокета в виде целого числа (например, SOCK_STREAM). Этот параметр сокета доступен только для чтения.

SO_BUSY_POLL (начиная с Linux 3.11)

Задаёт приблизительный интервал в микросекундах для задержки опроса при блокирующем приёме при отсутствии данных. Увеличение этого значения требует мандата CAP_NET_ADMIN. Значение по умолчанию данного параметра управляется через файл /proc/sys/net/core/busy_read.

Значение в файле /proc/sys/net/core/busy_poll определяет как долго select(2) и poll(2) задержат опрос, если они работают с сокетами с установленным SO_BUSY_POLL и отсутствуют события для извещения.

В обоих случаях опрос с задержкой (busy polling) будет завершён только, когда сокет примет все данные из сетевого устройства, которое поддерживает этот параметр.

Хотя опрос с задержкой может уменьшить время ожидания в некоторых приложениях, этим нужно пользоваться с осторожностью, так как его использование увеличит нагрузку на ЦП и энергопотребление.

### Сигналы
При записи в сокет, ориентированный на соединение, который был выключен (shutdown) локальной или удалённой стороной, записывающему процессу посылается сигнал SIGPIPE и возвращается EPIPE. Сигнал не посылается, если вызов записи был сделан с флагом MSG_NOSIGNAL.

Если был произведён вызов fcntl(2) с FIOSETOWN или ioctl(2) с SIOCSPGRP, то при появлении событий ввода/вывода посылается сигнал SIGIO. Для определения сокета, в котором произошло событие, в обработчике можно воспользоваться вызовом poll(2) или select(2). Альтернативным способом (в Linux 2.2) является установка сигнала реального времени с помощью вызова fcntl(2) с F_SETSIG; будет вызван обработчик сигнала реального времени и в его структуре siginfo_t поле si_fd будет содержать значение файлового дескриптора. Дополнительная информация приведена в fcntl(2).

В некоторых случаях (например, при наличии доступа нескольких процессов к одному сокету) условие, вызвавшее SIGIO, может исчезнуть на момент обработки процессом сигнала. Если это происходит, то процесс должен подождать сигнала ещё какое-то время, так как Linux снова пошлёт его позже.

### Интерфейсы /proc
Основные сетевые параметры сокета доступны через файлы в каталоге /proc/sys/net/core/.

rmem_default

устанавливаемый по умолчанию размер буфера приёма сокета (в байтах)

rmem_max

максимальный размер буфера приёма сокета (в байтах), который может установить пользователь с помощью параметра сокета SO_RCVBUF

wmem_default

устанавливаемый по умолчанию размер буфера отправки сокета (в байтах)

wmem_max

максимальный размер буфера отправки сокета (в байтах), который может установить пользователь с помощью параметра сокета SO_SNDBUF

message_cost и message_burst

фильтр корзины токенов, используемый для ограничения нагрузки сети предупреждающими сообщениями, вызванными внешними сетевыми событиями

netdev_max_backlog

максимальное количество пакетов в глобальной входящей очереди

optmem_max

максимальная длина вспомогательных данных и управляющих данных пользователя, таких, как iovec (для каждого сокета)

### Вызовы ioctl
Следующие операции доступны через ioctl(2):

```
error = ioctl(ip_socket, ioctl_type, &value_result);
```

SIOCGSTAMP

Возвращает структуру struct timeval с меткой времени принятого последнего пакета, переданного пользователю. Это полезно для точного вычисления времени. Описание struct timeval приведено в setitimer(2). Данный ioctl нужно использовать только, если для сокета не задан параметр SO_TIMESTAMP. В противном случае возвращается метка времени последнего пакета, который был получен в то время, когда не был установлен SO_TIMESTAMP, или возвращается ошибка, если такой пакет вообще никогда не принимался (т.е. ioctl(2) возвращает -1 и устанавливает errno равной ENOENT).

SIOCSPGRP

Назначает процесс или группу процессов, которым будут посылаться сигналы SIGIO или SIGURG при появлении возможности ввода-вывода или при появлении срочных данных. Аргумент является указателем на pid_t. Дополнительная информация приведена в описании на F_SETOWN в fcntl(2).

FIOASYNC

Изменяет флаг O_ASYNC для включения или отключения асинхронного режима ввода/вывода сокета. В асинхронном режиме при появлении событий ввода/вывода посылается сигнал SIGIO или сигнал, установленный с помощью F_SETSIG.

Аргументом является целочисленный логический флаг. Данная операция аналогична вызову fcntl(2) с установленным флагом O_ASYNC.

SIOCGPGRP

Возвращает процесс или группу процессов, получающих сигналы SIGIO или SIGURG. Если такой процесс не задан, то возвращается нулевое значение.

Возможные операции fcntl(2):

FIOGETOWN

То же, что и вызов ioctl(2) SIOCGPGRP.

FIOSETOWN

То же, что и вызов ioctl(2) SIOCSPGRP.

## ВЕРСИИ
Параметр SO_BINDTODEVICE появился в Linux 2.0.30. Параметр SO_PASSCRED появился в Linux 2.2. Интерфейсы /proc появились в Linux 2.2. Параметры SO_RCVTIMEO и SO_SNDTIMEO начали поддерживаться в Linux 2.3.41. До этого, времена ожидания были жёстко прописаны в настройках протокола и недоступны для чтения или записи.

## ЗАМЕЧАНИЯ
В Linux предполагается, что половина буфера приёма/передачи используется для размещения внутренних структур ядра; поэтому соответствующие файлы /proc в два раза больше, чем кажутся.

В Linux разрешено повторное использование порта с параметром SO_REUSEADDR только, когда этот параметр установлен и в программе, уже выполнившей bind(2) и в программе, которая хочет использовать порт. Такое поведение отличается от некоторых реализаций (например, FreeBSD), в которых только последняя программа должна устанавливать параметр SO_REUSEADDR. Обычно, это отличие незаметно, так как, например, в серверных программах всегда устанавливают этот параметр.

## СМОТРИТЕ ТАКЖЕ
wireshark(1), bpf(2), connect(2), getsockopt(2), setsockopt(2), socket(2), pcap(3), address_families(7), capabilities(7), ddp(7), ip(7), packet(7), tcp(7), udp(7), unix(7), tcpdump(8)


spufs

title: spufs(7)

summary: файловая система SPU

text:
# spufs(7)

## ИМЯ
spufs - файловая система SPU

## ОПИСАНИЕ
Файловая система SPU используется на машинах PowerPC, на которых реализована Cell Broadband Engine Architecture для доступа к cинергичным процессорным блокам (Synergistic Processor Unit, SPU).

Файловая система предоставляет пространство имён похожее на общую память POSIX или очереди сообщений. Пользователи, имеющие права на запись в файловую систему, могут использовать вызов spu_create(2) для организации контекстов SPU в корневом каталоге spufs.

Каждый контекст SPU представлен каталогом с постоянным набором файлов. Эти файлы можно использовать для управления состоянием логического SPU. Пользователи могут изменять права на файлы, но не могут добавлять или удалять файлы.

### Параметры монтирования
uid=<uid>

Назначает пользователя-владельца точки монтирования; по умолчанию 0 (root).

gid=<gid>

Назначает группу-владельца точки монтирования; по умолчанию 0 (root).

mode=<права>

Назначает права на каталог верхнего уровня в spufs, задаётся как строка-число прав в восьмеричной системе счисления. По умолчанию 0775.

### Файлы
При вызовах read(2) или write(2) файлы в spufs, в основном, ведут себя как обычно, но часто поддерживают только ограниченный набор операций. В данном списке перечислены поддерживаемые операции, а отклонения от стандартного поведения описаны в соответствующих справочных страницах.

Все файлы, поддерживающие операцию read(2), также поддерживают readv(2), а все файлы, поддерживающие операцию write(2), также поддерживают writev(2). Все файлы поддерживают семейство операций access(2) и stat(2), но у последней операции в возвращаемой структуре stat достоверную информацию содержат только поля st_mode, st_nlink, st_uid и st_gid.

Все файлы поддерживают операции chmod(2)/fchmod(2) и chown(2)/fchown(2), но они не могут предоставить права, которые противоречат возможным операциям (например, возможность чтения файла wbox).

Текущий список файлов:

/capabilities

Содержит строку мандатов (перечисляемых через запятую) этого контекста SPU. Возможные мандаты:

sched

Данный контекст может быть запланирован.

step

Данный контекст может выполняться в пошаговом режиме, для отладки.

В будущем могут быть добавлены новые флаги мандатов.

/mem

Содержимое хранилища локальной памяти SPU. Оно может быть доступно как обычный файл общей памяти и содержит код и данные в адресном пространстве SPU. Возможные операции после открытия файла mem:

read(2), pread(2), write(2), pwrite(2), lseek(2)

Эти операции работают как обычно, за исключением того, что lseek(2), write(2) и pwrite(2) не поддерживают доступ за конец файла. Размер файла — это размер локального хранилища SPU, обычно 256 килобайт.

mmap(2)

Отображает mem в адресное пространство процесса, предоставляя доступ к локальному хранилищу SPU внутри адресного пространства процесса. Разрешено только отображение MAP_SHARED.

/regs

Содержит сохранённые регистры общего назначения контекста SPU. Этот файл содержит 128-битное значение каждого регистра, начиная с регистра 0 и кончая 127, в этом порядке. Это позволяет просматривать регистры общего назначения при отладке.

Для чтения или записи в этот файл требуется, чтобы контекст был запланирован, поэтому использовать этот файл не рекомендуется при нормальной работе программы.

Файл regs отсутствует в контекстах, которые были созданы с флагом SPU_CREATE_NOSCHED.

/mbox

Первый буфер обмена (communication mailbox) SPU-в-CPU. Этот файл доступен только для чтения и может быть прочитан по 4 байта за раз. Его можно использовать только в неблокирующем режиме — для блокировки нельзя даже использовать poll(2). Единственно возможная операция над открытым файлом mbox:

read(2)

Если count меньше четырёх, то read(2) возвращает -1 и присваивает errno значение EINVAL. Если данные в буфере отсутствуют (т. е., SPU не отправлял сообщений), то возвращается значение -1, а errno присваивается значение EAGAIN. При успешном чтении данных четыре байта помещаются в буфер данных и возвращается значение 4.

/ibox

Второй буфер обмена SPU-в-CPU. Этот файл подобен первому буферу обмена, но может открываться в блокирующем режиме ввода-вывода, то есть вызов read(2) с открытым файлом ibox заблокирует выполнение до тех пор, пока SPU не запишет данные в свой канал прерываний буфера (если файл не открыт с флагом O_NONBLOCK, смотрите далее). Также можно использовать poll(2) и подобные системные вызовы для отслеживания наличия данных в буфере.

Возможные операции над открытым файлом ibox:

read(2)

Если count меньше четырёх, то read(2) возвращает -1 и присваивает errno значение EINVAL. Если данные в буфере отсутствуют и файловый дескриптор открыт с флагом O_NONBLOCK, то возвращается значение -1, а errno присваивается значение EAGAIN.

Если в буфере данных нет и файловый дескриптор был открыт без O_NONBLOCK, то вызов блокируется до тех пор, пока SPU не запишет в свой канал прерываний буфера. При успешном чтении данных четыре байта помещаются в буфер данных и возвращается значение 4.

poll(2)

Опрос файла ibox показывает (POLLIN | POLLRDNORM) есть ли данные для чтения.

/wbox

Буфер обмена CPU-в-SPU. Доступен только для записи, которую можно производить по четыре байта за раз. Если буфер полон, то write(2) блокируется; для слежения за возможностью записи можно использовать вызов poll(2). Возможные операции с открытым файлом wbox:

write(2)

Если count меньше четырёх, то write(2) возвращает -1 и присваивает errno значение EINVAL. Если в буфере нет места и файловый дескриптор открыт с флагом O_NONBLOCK, то возвращается значение -1, а errno присваивается значение EAGAIN.

Если в буфере нет места и файловый дескриптор был открыт без флага O_NONBLOCK, то вызов заблокирует выполнение до тех пор, пока SPU не выполнит чтение из своего буферного канала PPE (PowerPC Processing Element). После успешного чтения данных, системный вызов вернёт значение 4 как результат функции.

poll(2)

Опрос файла wbox показывает (POLLOUT | POLLWRNORM) есть ли свободное место для записи.

/mbox_stat, /ibox_stat, /wbox_stat

Эти файлы доступны только для чтения и содержат размер текущей очереди каждого буфера — то есть сколько слов можно прочитать из mbox или ibox, или сколько слов можно записать в wbox без блокировки. Файлы можно читать только по четыре байта за раз и возвращается целое двоичное число с прямым порядком байт. С открытыми файлами *box_stat возможна только операция:

read(2)

Если count меньше четырёх, то read(2) возвращает -1 и присваивает errno значение EINVAL. В противном случае четырёхбайтное значение помещается в буфер данных. Это значение — количество элементов, которые можно прочитать (для mbox_stat и ibox_stat) или записать (для wbox_stat) из соответствующего буфера без блокировки, иначе возвращается ошибка EAGAIN.

/npc, /decr, /decr_status, /spu_tag_mask, /event_mask, /event_status, /srr0, /lslr

Внутренние регистры SPU. В этих файлах содержатся строки ASCII, представляющие значение регистра в виде шестнадцатеричного числа. Для чтения и записи в эти файлы (кроме npc, смотрите далее) требуется, чтобы выполнялся контекст SPU, поэтому частый доступ к этим файлам не рекомендуется при обычной работе программы.

Содержимое этих файлов:

npc

Счётчик следующей команды — доступен только когда SPU в остановленном состоянии.

decr

Декрементный счётчик SPU

decr_status

Состояние декрементного счётчика

spu_tag_mask

Маска тега MFC для SPU DMA

event_mask

Маска событий прерываний SPU

event_status

Количество ожидающих событий SPU (только для чтения)

srr0

Регистр адреса возврата из прерывания

lslr

Ограничительный регистр локального хранилища

Возможные операции над этими файлами:

read(2)

Читает текущее значение регистра. Если значение не вмещается в буфер, переданный в системный вызов read(2), то последующие чтения продолжат чтение из этого же буфера пока не будет достигнут его конец.

После прочтения всей строки, все последующие операции чтения будут возвращать ноль байт и для чтения нового значения нужно открыть новый файловый дескриптор.

write(2)

Операция write(2) над файлом устанавливает в регистр значение, передаваемое в строке. Строка анализируется от начала до первого не числового символа или до конца буфера. Последующие операции записи в тот же файловый дескриптор перезаписывают предыдущее значение.

За исключением файла npc, эти файлы отсутствуют в контекстах, которые были созданы с флагом SPU_CREATE_NOSCHED.

/fpcr

Данный файл предоставляет доступ к регистру управления и состояния операций с плавающей запятой (fcpr). Это четырёхбайтный файл с двоичным значением регистра. Операции с fpcr:

read(2)

Если count меньше четырёх, то read(2) возвращает -1 и присваивает errno значение EINVAL. В противном случае четырёхбайтное значение помещается в буфер данных; это текущее значение регистра fpcr.

write(2)

Если count меньше четырёх, то write(2) возвращает -1 и присваивает errno значение EINVAL. В противном случае четырёхбайтное значение копируется из буфера данных, обновляя значение регистра fpcr.

/signal1, /signal2

Эти файлы предоставляют доступ к двум сигнальным каналам уведомления SPU. Они доступны на чтение-запись четырёхбайтными словами. Запись в один из файлов возбуждает прерывание на SPU. Значение, записанное в сигнальные файлы, можно прочитать из SPU через канал чтения или из пользовательского пространства узла через файл. После чтения SPU этого значения, оно сбрасывается в ноль. Возможные операции с открытым файлом signal1 или signal2:

read(2)

Если count меньше четырёх, то read(2) возвращает -1 и присваивает errno значение EINVAL. В противном случае четырёхбайтное значение помещается в буфер данных; это текущее значение указанного сигнального регистра уведомления.

write(2)

Если count меньше четырёх, то write(2) возвращает -1 и присваивает errno значение EINVAL. В противном случае четырёхбайтное значение копируется из буфера данных, обновляя значение указанного сигнального регистра уведомления. Данные в сигнальном регистре уведомления или будут перезаписаны входными данными или обновлены с помощью побитной операции ИЛИ, в зависимости от содержимого файла signal1_type или signal2_type, соответственно.

/signal1_type, /signal2_type

Эти файлы изменяют поведение файлов уведомлений signal1 и signal2. В них содержится число в виде строки ASCII, которое читается как «1» или «0». В режиме 0 (перезапись) аппаратное обеспечение заменяет содержимое сигнального канала данными, которые в него записываются. В режиме 1 (логическое ИЛИ) аппаратное обеспечение складывает биты, которые в него последовательно поступают. Возможные операции с открытым файлом signal1_type или signal2_type:

read(2)

Если счётчик, переданный в вызов read(2), короче требуемой длины для цифры (плюс символ новой строки), последующие чтения из того же файлового дескриптора дополнят строку. После чтения всей строки все последующие операции чтения будут возвращать ноль байт, а для повторного чтения значения нужно открыть новый файловый дескриптор.

write(2)

Операция write(2) над файлом устанавливает в регистр значение, передаваемое в строке. Строка анализируется от начала до первого не числового символа или до конца буфера. Последующие операции записи в тот же файловый дескриптор перезаписывают предыдущее значение.

/mbox_info, /ibox_info, /wbox_info, /dma_into, /proxydma_info

Эти файлы, доступные только для чтения, содержат сохранённое состояние буферов обмена SPU и очередей DMA. Это позволяет просматривать состояние SPU, полезно при отладке. Файлы mbox_info и ibox_info содержат четырёхбайтное сообщение, которое было записано SPU. Если сообщения не было записано в эти буферы обмена, то содержимое этих файлов не определено. Файлы mbox_stat, ibox_stat и wbox_stat содержат счётчик доступных сообщений.

Файл wbox_info содержит массив четырёхбайтных сообщений, которые посылались в SPU. В существующих машинах CBEA размер массива равен четырём элементам, поэтому 4 * 4 = 16 байт можно прочитать из этого файла. Если какой-то элемент очереди пуст, то содержимое прочитанных байтов из этого положения не определено.

Файл dma_info содержит данные очереди SPU MFC DMA, которые представлены следующей структурой:

```
struct spu_dma_info {

    uint64_t         dma_info_type;

    uint64_t         dma_info_mask;

    uint64_t         dma_info_status;

    uint64_t         dma_info_stall_and_notify;

    uint64_t         dma_info_atomic_command_status;

    struct mfc_cq_sr dma_info_command_data[16];
};

```

Последний элемент структуры — действующая очередь DMA, содержащая 16 элементов. Структура mfc_cq_sr определена следующим образом:

```
struct mfc_cq_sr {

    uint64_t mfc_cq_data0_RW;

    uint64_t mfc_cq_data1_RW;

    uint64_t mfc_cq_data2_RW;

    uint64_t mfc_cq_data3_RW;
};

```

В файле proxydma_info содержится подобная информация, но она описывает очередь прокси-DMA (т. е., DMA, инициируемые элементами вне SPU). Файл имеет следующий формат:

```
struct spu_proxydma_info {

    uint64_t         proxydma_info_type;

    uint64_t         proxydma_info_mask;

    uint64_t         proxydma_info_status;

    struct mfc_cq_sr proxydma_info_command_data[8];
};

```

Для доступа к этим файлам требуется, чтобы выполнялся контекст SPU, частое использование может быть неэффективным. Эти файлы не должны использоваться в обычной работе.

Эти файлы отсутствуют в контекстах, которые были созданы с флагом SPU_CREATE_NOSCHED.

/cntl

Данный файл предоставляет доступ к регистрам управления работой SPU (Run Control) и состояния SPU, содержит строки ASCII. Поддерживаются следующие операции:

read(2)

При попытке чтения файла cntl возвращается строка ASCII, представляющая содержимое регистра состояния SPU в виде шестнадцатеричного значения.

write(2)

Запись в файл cntl изменяет значение контекстного регистра управления работой SPU.

/mfc

Предоставляет доступ к Memory Flow Controller, находящийся в SPU. При чтении из файла возвращается содержимое регистра SPU MFC Tag Status, а при записи в файл запускается DMA из MFC. Поддерживаются следующие операции:

write(2)

Для записи в файл данные должны быть в формате команды MFC DMA:

```
struct mfc_dma_command {

    int32_t  pad;    /* зарезервировано */

    uint32_t lsa;    /* адрес локального хранилища */

    uint64_t ea;     /* эффективный адрес */

    uint16_t size;   /* размер передачи */

    uint16_t tag;    /* тег команды */

    uint16_t class;  /* ID класса */

    uint16_t cmd;    /* opcode команды */
};

```

Данные записи должны иметь размер ровно sizeof(struct mfc_dma_command) байт. Команда будет послана в очередь прокси MFC SPU, а тег сохранён в ядре (смотрите далее).

read(2)

Читает содержимое регистра состояния тега. Если файл открыт в блокирующем режиме (т. е., без O_NONBLOCK), то чтение заблокирует выполнение до тех пор, пока не выполнится тег DMA (который задан предыдущей записью). В неблокирующем режиме сразу же возвращается регистр состояния тега MFC.

poll(2)

Вызов poll(2) с файлом mfc заблокирует выполнение до тех пор, пока не будет запущен новый DMA (проверяется по POLLOUT) или пока не будет завершён уже выполняющийся DMA (проверяется по POLLIN).

/mss Предоставляет доступ к свойству MFC MultiSource Synchronization (MSS). При выполнении mmap(2) процесс может получить доступ к области MSS из SPU.

Поддерживаются следующие операции:

mmap(2)

Отображает mss в адресное пространство процесса, предоставляя доступ к области MSS SPU внутри адресного пространства процесса. Разрешено только отображение MAP_SHARED.

/psmap

Предоставляет доступ к полному отображению проблемного состояния (problem-state mapping) SPU. В приложениях эту область можно использовать для обмена с SPU вместо записи в отдельные регистровые файлы spufs.

Поддерживаются следующие операции:

mmap(2)

Отображение psmap предоставляет процессу прямое отображение к области проблемного состояния SPU. Поддерживаются только отображения MAP_SHARED.

/phys-id

Доступный только для чтения файл содержит номер физического SPU, на котором выполняется контекст SPU. Когда контекст не выполняется этот файл содержит строку «-1».

Номер физического SPU описывается строкой ASCII числом в шестнадцатеричной системе счисления.

/object-id

Позволяет приложениям хранить (или получать) одиночный 64-битный ID в контекст. Позднее данный ID используется инструментами профилирования как уникальный идентификатор контекста.

write(2)

Записью строки ASCII с шестнадцатеричным числом приложение может назначать ID объекта контекста SPU. Любое предыдущее значение объекта ID перезаписывается.

read(2)

При чтении из файла возвращается строка ASCII с шестнадцатеричным числом, представляющим ID объекта этого контекста SPU.

## ПРИМЕР
запись в /etc/fstab

none /spu spufs gid=spu 0 0

## СМОТРИТЕ ТАКЖЕ
close(2), spu_create(2), spu_run(2), capabilities(7)

The Cell Broadband Engine Architecture (CBEA) specification


standards

title: standards(7)

summary: стандарты Си и UNIX

text:
# standards(7)

## ИМЯ
standards - стандарты Си и UNIX

## ОПИСАНИЕ
В разделе СООТВЕТСТВИЕ СТАНДАРТАМ, который имеется во многих справочных страницах, перечисляются различные стандарты, которым соответствует описываемый интерфейс. В следующем списке кратко описаны эти стандарты.

V7

Version 7 (также известная как седьмая редакция) UNIX, выпущена AT&T/Bell Labs в 1979 году. После этого системы UNIX разделились на два основных диалекта: BSD и System V.

4.2BSD

Так называется реализация стандарта, определённого выпуском 4.2 Berkeley Software Distribution, выпущенном Калифорнийским университетом в Беркли. Это первый выпуск Berkeley со стеком TCP/IP и программным интерфейсом сокетов. 4.2BSD выпущена 1983 году.

Предыдущие основные версии BSD: 3BSD (1980 год), 4BSD (1980 год) и 4.1BSD (1981 год).

4.3BSD

Преемник 4.2BSD, выпущен в 1986 году.

4.4BSD

Преемник 4.3BSD, выпущен в 1993 году. Это был последний крупный выпуск от Университета Беркли.

System V

Так называется реализация стандарта, определённого выпуском AT&T в 1983 году своего коммерческого выпуска System V (пять). Предыдущий основной выпуск AT&T называется System III и выпущен в 1981 году.

System V release 2 (SVr2)

Это следующий выпуск System V, выпущенный в 1985 году. SVr2 формально описан в System V Interface Definition version 1 (SVID 1), опубликованном в 1985 году.

System V release 3 (SVr3)

Это следующий выпуск SVr2, выпущен в 1986 году. Данный выпуск формально описан в System V Interface Definition version 2 (SVID 2).

System V release 4 (SVr4)

Это следующий выпуск SVr3, выпущен в 1989 году. Эта версия System V описана в «Programmer's Reference Manual: Operating System API (Intel processors)» (Prentice-Hall 1992, ISBN 0-13-951294-2). Данный выпуск формально описан в System V Interface Definition version 3 (SVID 3) и считается определяющим выпуском System V.

SVID 4

Определение интерфейса System V, версия 4, выпущено в 1995 году. Доступно по адресу http://www.sco.com/developers/devspecs/.

C89

Это первая версия стандарта языка Си, одобрена ANSI (Американский национальный институт стандартов) в 1989 году (X3.159-1989). Иногда её называют ANSI C, но так как C99 также является стандартом ANSI, этот термин противоречив. Данный стандарт также одобрен ISO (Международная организация по стандартизации) в 1990 году (ISO/IEC 9899:1990) и поэтому изредка называется ISO C90.

C99

Данная редакция стандарта языка Си была одобрена ISO в 1999 году (ISO/IEC 9899:1999). Доступна по адресу http://www.open-std.org/jtc1/sc22/wg14/www/standards.

C11

Данная редакция стандарта языка Си была одобрена ISO в 2011 году (ISO/IEC 9899:2011).

POSIX.1-1990

«Переносимый интерфейс операционных систем для вычислительных сред». IEEE 1003.1-1990 часть 1 одобрена ISO в 1990 году (ISO/IEC 9945-1:1990). Термин «POSIX» был предложен Ричардом Столлманом.

POSIX.2

IEEE Std 1003.2-1992 описывает команды и утилиты, одобрен ISO в 1993 году (ISO/IEC 9945-2:1993).

POSIX.1b (ранее известен как POSIX.4)

IEEE Std 1003.1b-1993 описывает средства реального времени в переносимых операционных системах, одобрен ISO в 1996 году (ISO/IEC 9945-1:1996).

POSIX.1c

IEEE Std 1003.1c-1995 описывает интерфейс нитей POSIX.

POSIX.1d

IEEE Std 1003.1c-1999 описывает дополнительные расширения реального времени.

POSIX.1g

IEEE Std 1003.1g-2000 описывает сетевые программные интерфейсы (включая сокеты).

POSIX.1j

IEEE Std 1003.1j-2000 описывает развитые расширения реального времени.

POSIX.1-1996

Ревизия POSIX.1 1996 года с включёнными POSIX.1b и POSIX.1c.

XPG3

Выпущен в 1989 году, первый существенный выпуск X/Open Portability Guide, разработанный X/Open Company — консорциумом производителей. Данное многотомное руководство основано на стандартах POSIX.

XPG4

Ревизия X/Open Portability Guide, выпущенная в 1992 году.

XPG4v2

Ревизия XPG4, выпущенная в 1994 году. Также называется Spec 1170, где 1170 — количество интерфейсов, определённых в этом стандарте.

SUS (SUSv1)

Single UNIX Specification. Перепакованный вариант XPG4v2 и других стандартов X/Open (X/Open Curses Issue 4 version 2, X/Open Networking Service (XNS) Issue 4). Системы, удовлетворяющие этому стандарту, могут маркироваться как UNIX 95.

SUSv2

Single UNIX Specification, версия 2. Иногда называется XPG5. Данный стандарт появился в 1997 году. Системы, удовлетворяющие этому стандарту, могут маркироваться как UNIX 98. Смотрите также http://www.UNIX-systems.org/version2/.)

POSIX.1-2001, SUSv3

Это выпуск 2001 года и объединение стандартов POSIX.1, POSIX.2 и SUS в один документ, проводимый под покровительством Austin Group http://www.opengroup.org/austin/. Стандарт доступен в сети по адресу http://www.unix-systems.org/version3/, а интерфейсы, которые он описывает, также доступны в пакете справочных страниц Linux в разделах 1p и 3p (например, «man 3p open»).

В стандарте определено два уровня соответствия: POSIX conformance — базовый набор интерфейсов, требуемых в системе для соответствия и XSI Conformance — дополнительный набор интерфейсов («расширение XSI»), которые не являются обязательными для соответствия POSIX. Системы, удовлетворяющие XSI, могут маркироваться как UNIX 03. (соответствием XSI определяется Single UNIX Specification version 3 (SUSv3)).

Документ POSIX.1-2001 разделён на четыре части:

XBD: Определения, обозначения и положения, описание заголовочных файлов.

XSH: Описание функций (т. е., реальные реализации системных вызовов и библиотечных функций).

XCU: Описания команд и утилит (т. е., то, что описывалось ранее в POSIX.2).

XRAT: Справочные данные на другие части стандарта.

POSIX.1-2001 выверен с C99, поэтому все библиотечные функции, стандартизованные в C99, также стандартизованы в POSIX.1-2001.

Было проведено две технические поправки (небольшие исправления и улучшения) оригинального стандарта 2001 года: TC1 в 2003 году (известна как POSIX.1-2003) и TC2 в 2004 году (известна как POSIX.1-2004).

POSIX.1-2008, SUSv4

Следующий выпуск POSIX.1/SUS, утверждён в 2008 году.

Изменения в этом выпуске не столь велики как в POSIX.1-2001/SUSv3, но добавлено несколько новых интерфейсов и внесены изменения в описание существующих. Многие необязательные в POSIX.1-2001 интерфейсы стали обязательными в выпуске стандарта 2008 года. Некоторые интерфейсы из POSIX.1-2001 помечены как устаревшие в POSIX.1-2008, или удалены вообще.

Выпуск стандарта делится на те же части что и POSIX.1-2001 и также существует два уровня соответствия: основной POSIX Conformance и XSI Conformance, который описывает дополнительный набор интерфейсов вне основного.

В общем, если в разделе справочных страниц «СООТВЕТСТВИЕ СТАНДАРТАМ» указан POSIX.1-2001, то можно считать, что интерфейс также соответствует POSIX.1-2008, если не указано обратного.

Техническая поправка 1 (небольшие исправления и улучшения) данного стандарта была выпущена в 2013 году (также известна как POSIX.1-2013).

Техническая поправка 2 данного стандарта вошла в выпуск 2016 года (также известна как POSIX.1-2016).

Дополнительную информацию можно найти на веб-сайте Austin Group по адресу: http://www.opengroup.org/austin/.

## СМОТРИТЕ ТАКЖЕ
getconf(1), confstr(3), pathconf(3), sysconf(3), attributes(7), feature_test_macros(7), libc(7), posixoptions(7)