title: subpage_prot(2)

text:
# subpage_prot(2)

## ИМЯ
subpage_prot - определяет подстраничную защиту адресного диапазона

## ОБЗОР

```
long subpage_prot(unsigned long addr, unsigned long len,
                  uint32_t *map);
```

Замечание: В glibc нет обёрточной функции для данного системного вызова; смотрите ЗАМЕЧАНИЯ.

## ОПИСАНИЕ
Системный вызов (есть только для PowerPC) subpage_prot() предоставляет возможность контроля доступа к отдельным 4 КБ подстраницам в системах, где размер страницы равен 64 КБ.

Карта защиты налагается на страницы памяти для области, начинающейся с addr и имеющей размер len байт. Значения обоих аргументов должны быть выровнены на 64-КБ границу.

Карта защиты задаётся в буфере, на который указывает map. В карте на каждую 4-килобайтную подстраницу выделяется 2 бита; таким образом, в каждом 32-битном слове задаётся защита для 16 4-килобайтных подстраниц внутри 64-килобайтной страницы (поэтому количество 32-битных слов, на которые указывает map, должно быть равно количеству 64-килобайтных страниц, указанному в len). Каждое 2-битное поле в карте защиты может быть: 0 — полный доступ, 1 — защита от записи, 2 или 3 — запрет на любой доступ.

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении subpage_prot() возвращается 0. В противном случае возвращается один из кодов ошибок, описанных далее.

## ОШИБКИ
EFAULT

Буфер, на который ссылается map, недоступен.

EINVAL

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

ENOMEM

Не хватает памяти.

## ВЕРСИИ
Данный системный вызов предоставляется для архитектуры PowerPC начиная с Linux 2.6.25. Для его сборки в ядре должен быть указан параметр CONFIG_PPC_64K_PAGES. В библиотеке поддержка данного вызова отсутствует.

## СООТВЕТСТВИЕ СТАНДАРТАМ
Данный вызов есть только в Linux.

## ЗАМЕЧАНИЯ
В glibc нет обёртки для данного системного вызова; запускайте его с помощью syscall(2).

Обычная страничная защита также работает (на уровне 64-килобайтных страниц); механизм подстраничной защиты является дополнительным ограничением, поэтому указание 0 в 2-битном поле не разрешит запись в страницу, которая защищена от записи другим способом.

### Обоснование
Данный системный вызов предоставляется для облегчения написания эмуляторов, которые работают с 64-КБ страницами в системах PowerPC. При эмуляции систем, в которых используется меньший размер страницы (таких как x86), эмулятор не может использовать блок управления памятью (MMU) и обычные системные вызовы управления защитой страниц (эмулятор может эмулировать MMU с помощью ПО проверяя и, возможно, перераспределяя адрес при каждом обращении к памяти, но это медленно). Идея в том, что эмулятор задаёт массив защитных масок для указанного диапазона виртуальных адресов. Эти маски накладываются в месте, где аппаратные табличные записи страниц (PTE) вставляются в аппаратную таблицу страниц на основе Linux PTE, при этом Linux PTE не затрагиваются. В этом случае для защищённых областей адресного пространства начинают неявно использоваться 4-килобайтные аппаратные страницы, а не 64-килобайтные аппаратные страницы (на машинах с аппаратной поддержкой 64-килобайтных страниц).

## СМОТРИТЕ ТАКЖЕ
mprotect(2), syscall(2)

Documentation/admin-guide/mm/hugetlbpage.rst в дереве исходного кода ядра Linux


swapon

package: man-pages-ru

title: swapon(2)

text:
# swapon(2)

## ИМЯ
swapon, swapoff - запускает/останавливает подкачку данных в файл/устройство

## ОБЗОР
\#include <unistd.h>

\#include <sys/swap.h>

int swapon(const char *path, int swapflags);

int swapoff(const char *path);

## ОПИСАНИЕ
swapon() включает использование файла или блочного устройства, указанного в path, в качестве подкачки данных. swapoff() выключает использование файла или блочного устройства, указанного в path, в качестве подкачки данных.

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

```
(prio << SWAP_FLAG_PRIO_SHIFT) & SWAP_FLAG_PRIO_MASK
```

Если в аргументе swapflags вызова swapon() указан флаг SWAP_FLAG_DISCARD, то освобождаемые страницы подкачки будут исключены (discard) до того как они задействуются повторно (если устройство подкачки поддерживает операцию исключения или обрезки). Это может улучшить производительность на некоторых твердотельных накопителях, но, чаще всего, нет. Также смотрите ЗАМЕЧАНИЯ.

Эти функции могут использоваться только привилегированным процессом (имеющим мандат CAP_SYS_ADMIN).

### Приоритет
Каждое пространство подкачки имеет приоритет, высокий или низкий. По умолчанию задается низкий приоритет. Внутри пространств с низким приоритетом, новые пространства имеют ещё меньший приоритет, чем старые.

Все приоритеты, установленные с помощью swapflags, выше используемого по умолчанию. Приоритет может быть любым неотрицательным числом (определяется вызывающим). Большее значение соответствует большему приоритету.

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

В Linux 1.3.6 работа ядра обычно следует этим правилам, но существуют исключения.

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении возвращается 0. В случае ошибки возвращается -1, а errno устанавливается в соответствующее значение.

## ОШИБКИ
EBUSY

(для swapon()) Указанный path уже используется в качестве пространства подкачки.

EINVAL

Файл path существует, но не ссылается на обычный файл или блочное устройство;

EINVAL

(swapon()) Указанный путь не содержит правильной сигнатуры подкачки или располагается в файловой системе, работающей в памяти, например, tmpfs(5).

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

(swapon()) В flags указано неверное значение флага.

EINVAL

(swapoff()) В настоящее время path не является областью подкачки.

ENFILE

Достигнуто максимальное количество открытых файлов в системе.

ENOENT

Файл path не существует.

ENOMEM

Не хватает памяти ядра для запуска процесса подкачки.

EPERM

Вызывающий не имеет мандата CAP_SYS_ADMIN. Или превышен лимит количества используемых пространств подкачки; см. ЗАМЕЧАНИЯ далее.

## СООТВЕТСТВИЕ СТАНДАРТАМ
Эти функции предназначены только для работы в Linux и не должны использоваться в переносимых программах. Второй параметр swapflags впервые появился в Linux 1.3.2.

## ЗАМЕЧАНИЯ
Раздел или путь должны быть подготовлены к подкачке при помощи mkswap(8).

Есть верхний предел на количество используемых файлов подкачки, он определяется константой ядра MAX_SWAPFILES. До ядра версии 2.4.10 значение MAX_SWAPFILES было равно 8; начиная с ядра 2.4.10, значение стало 32. Начиная с ядра 2.6.18, предел уменьшается на 2 (то есть стало 30), если ядро собирается с параметром CONFIG_MIGRATION (который резервирует 2 элемента таблицы подкачки для возможности переноса страниц mbind(2) и migrate_pages(2)). Начиная с ядра 2.6.32, предел ещё сокращается на 1, если ядро собирается с параметром CONFIG_MEMORY_FAILURE.

Исключение (discard) страниц подкачки появилось в ядре версии 2.6.29, флаг условия SWAP_FLAG_DISCARD появился в ядре версии 2.6.36, но пока при вызове swapon() исключается вся область подкачки, даже если этот флаг не задан.

## СМОТРИТЕ ТАКЖЕ
mkswap(8), swapoff(8), swapon(8)

branch: sisyphus


symlink

title: symlink(2)

summary: создаёт новое имя для файла

text:
# symlink(2)

## ИМЯ
symlink, symlinkat - создаёт новое имя для файла

## ОБЗОР

```
#include <unistd.h>
```

```
int symlink(const char *target, const char *linkpath);
#include <fcntl.h>           /* определения констант of AT_* */
#include <unistd.h>
```

```
int symlinkat(const char *target, int newdirfd, const char *linkpath);
```

```

```

Требования макроса тестирования свойств для glibc (см. feature_test_macros(7)):

symlink():

_XOPEN_SOURCE >= 500 || _POSIX_C_SOURCE >= 200112L

|| /* в версии glibc <= 2.19: */ _BSD_SOURCE

symlinkat():

Начиная с glibc 2.10:

_POSIX_C_SOURCE >= 200809L

До glibc 2.10:

_ATFILE_SOURCE

## ОПИСАНИЕ
Вызов symlink() создаёт символьную ссылку с именем linkpath, которая содержит строку target.

Символьные ссылки интерпретируются «на лету», как будто бы содержимое ссылки было подставлено вместо пути, по которому идёт поиск файла или каталога.

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

Символьная ссылка (также известная как «мягкая ссылка») может указывать как на существующий, так и на несуществующий файлы; в последнем случае такая ссылка называется повисшей (dangling).

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

Если linkpath существует, то он не будет перезаписан.

### symlinkat()
Системный вызов symlinkat() работает также как системный вызов symlink(), за исключением случаев, описанных здесь.

Если в linkpath задан относительный путь, то он считается относительно каталога, на который ссылается файловый дескриптор newdirfd (а не относительно текущего рабочего каталога вызывающего процесса, как это делается в symlink()).

Если в linkpath задан относительный путь и значение newdirfd равно AT_FDCWD, то linkpath рассматривается относительно текущего рабочего каталога вызывающего процесса (как symlink()).

Если в linkpath задан абсолютный путь, то newdirfd игнорируется.

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении возвращается 0. В случае ошибки возвращается -1, а errno устанавливается в соответствующее значение.

## ОШИБКИ
EACCES

Нет прав на запись в каталог, содержащийся в linkpath, или в одном из каталогов в linkpath не разрешён поиск (смотрите также path_resolution(7)).

EDQUOT

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

EEXIST

linkpath уже существует.

EFAULT

Значение target или linkpath указывают за пределы доступного адресного пространства.

EIO

Произошла ошибка ввода-вывода.

ELOOP

Во время определения linkpath встретилось слишком много символьных ссылок.

ENAMETOOLONG

Слишком длинное значение аргумента target или linkpath.

ENOENT

Компонент пути linkpath не существует или является повисшей символьной ссылкой или значение target или linkpath равно пустой строке.

ENOMEM

Недостаточное количество памяти ядра.

ENOSPC

На устройстве, содержащем файл, нет места для создания нового элемента каталога.

ENOTDIR

Компонент пути, использованный как каталог в linkpath, в действительности таковым не является.

EPERM

Файловая система, содержащая linkpath, не поддерживает создание символьных ссылок.

EROFS

linkpath расположен в файловой системе, доступной только для чтения.

В symlinkat() дополнительно могут возникнуть следующие ошибки:

EBADF

Значение newdirfd не является правильным файловым дескриптором.

ENOENT

Значение linkpath является относительным путём и newdirfd ссылается на каталог, который был удалён.

ENOTDIR

Значение linkpath содержит относительный путь и newdirfd содержит файловый дескриптор, указывающий на файл, а не на каталог.

## ВЕРСИИ
Системный вызов symlinkat() был добавлен в ядро Linux версии 2.6.16; поддержка в glibc доступна с версии 2.4.

## СООТВЕТСТВИЕ СТАНДАРТАМ
symlink(): SVr4, 4.3BSD, POSIX.1-2001, POSIX.1-2008.

symlinkat(): POSIX.1-2008.

## ЗАМЕЧАНИЯ
Не выполняется проверка target.

При удаление имени, на который ссылается символьная ссылка, произойдёт удаление файла (если только у него нет других жёстких ссылок). Если такое поведение нежелательно, используйте link(2).

### Замечания по glibc
В старых ядрах, где symlinkat() отсутствует, обёрточная функция glibc использует symlink(). Если linkpath является относительным путём, то glibc собирает путь относительно символической ссылки в /proc/self/fd, которая соответствует аргументу newdirfd.

## СМОТРИТЕ ТАКЖЕ
ln(1), namei(1), lchown(2), link(2), lstat(2), open(2), readlink(2), rename(2), unlink(2), path_resolution(7), symlink(7)


sync

title: sync(2)

summary: записывает кэши файловых систем на диск

text:
# sync(2)

## ИМЯ
sync, syncfs - записывает кэши файловых систем на диск

## ОБЗОР
\#include <unistd.h>

void sync(void);

int syncfs(int fd);

Требования макроса тестирования свойств для glibc (см. feature_test_macros(7)):

sync():

_XOPEN_SOURCE >= 500

|| /* начиная с glibc 2.19: */ _DEFAULT_SOURCE

|| /* версии glibc <= 2.19: */ _BSD_SOURCE

syncfs():

_GNU_SOURCE

## ОПИСАНИЕ
Вызов sync() приводит к записи в файловую систему всех отложенных изменений метаданных файловой системы и кэшированных файловых данных.

Вызов syncfs() подобен sync(), но синхронизирует только файловую систему, содержащую файл, на который указывает открытый файловый дескриптор fd.

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При нормальном завершении работы syncfs() возвращает 0. В случае ошибки возвращается -1, а errno устанавливается в соответствующее значение.

## ОШИБКИ
Вызов sync() всегда выполняется без ошибок.

Вызов syncfs() может завершиться с ошибкой, по крайней мере, по следующей причине:

EBADF

Значение fd не является правильным файловым дескриптором.

## ВЕРСИИ
Системный вызов syncfs() впервые появился в Linux 2.6.39; поддержка в glibc добавлена в версии 2.14.

## СООТВЕТСТВИЕ СТАНДАРТАМ
sync(): POSIX.1-2001, POSIX.1-2008, SVr4, 4.3BSD.

syncfs() есть только в Linux.

## ЗАМЕЧАНИЯ
Начиная с glibc 2.2.2 Linux-прототип sync() стал соответствовать различным стандартам. В glibc 2.21 и старее он объявлялся как «int sync(void)» и вызов sync() всегда возвращал 0.

В соответствии со стандартной спецификацией (например POSIX.1-2001), sync() только планирует запись, и может закончить работу до того как запись будет на самом деле произведена. Однако в Linux выполняется ожидание завершения операций ввода-вывода и поэтому sync() или syncfs() предоставляют такие же гарантии как fsync при вызове для каждого файла в системе или файловой системы, соответственно.

## ДЕФЕКТЫ
До версии 1.3.20 Linux не ждёт завершения операций ввода-вывода перед возвращением.

## СМОТРИТЕ ТАКЖЕ
sync(1), fdatasync(2), fsync(2)


title: sync_file_range(2)

summary: синхронизирует сегмент файла на диске

text:
# sync_file_range(2)

## ИМЯ
sync_file_range - синхронизирует сегмент файла на диске

## ОБЗОР

```
#define _GNU_SOURCE         /* см. feature_test_macros(7) */
#include <fcntl.h>
```

```
int sync_file_range(int fd, off64_t offset, off64_t nbytes,
                    unsigned int flags);
```

## ОПИСАНИЕ
Вызов sync_file_range() позволяет точно контролировать синхронизацию открытого файла, задаваемого файловым дескриптором fd, с диском.

В offset задаётся начальный байт диапазона файла, который нужно синхронизировать. В nbytes указывается длина синхронизируемого диапазона (в байтах); если nbytes равно нулю, то синхронизируются все байты, начиная с offset и до конца файла. Синхронизация выполняется в единицах размера системной страницы: значение offset округляется к меньшей границе страницы; (offset+nbytes-1) округляется к большей границе страницы.

В битовую маску аргумент flags можно включать следующие значения:

SYNC_FILE_RANGE_WAIT_BEFORE

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

SYNC_FILE_RANGE_WRITE

Начать перезапись всех изменённых страниц в указанном диапазоне, которые к настоящему моменту не были перезаписаны. Заметим, что это может привести к блокировке, если вы пытаетесь записать больше размера очереди запросов.

SYNC_FILE_RANGE_WAIT_AFTER

После выполнения записи ждать, пока не перезапишутся все страницы в диапазоне.

Указание 0 в flags допустимо; никаких действий выполнено не будет.

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

### Некоторые подробности
При SYNC_FILE_RANGE_WAIT_BEFORE и SYNC_FILE_RANGE_WAIT_AFTER будут обнаруживаться все ошибки ввода-вывода или условия ENOSPC, и они будут возвращены вызвавшему.

Полезные комбинации битов в flags:

SYNC_FILE_RANGE_WAIT_BEFORE | SYNC_FILE_RANGE_WRITE

Гарантировать, что все изменённые страницы в указанном диапазоне при вызове sync_file_range() помещаются для записи. Это начало операции по целостной записи данных.

SYNC_FILE_RANGE_WRITE

Начать запись всех изменённых страниц указанного диапазона, которые ещё не были размещены для записи. Это анонимная операция сброса данных на диск. Она не подходит для операций целостности данных.

SYNC_FILE_RANGE_WAIT_BEFORE (или SYNC_FILE_RANGE_WAIT_AFTER)

Ждать завершения записи всех страниц указанного диапазона. Можно использовать после операции SYNC_FILE_RANGE_WAIT_BEFORE | SYNC_FILE_RANGE_WRITE, дождаться завершения этой операции и получить её результат.

SYNC_FILE_RANGE_WAIT_BEFORE | SYNC_FILE_RANGE_WRITE | SYNC_FILE_RANGE_WAIT_AFTER

Это операция по целостной записи данных, которая позволит быть уверенным, что все изменённые на момент вызова sync_file_range() страницы указанного диапазона записаны на диск.

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении sync_file_range() возвращает 0. При ошибке возвращается -1, и errno устанавливается в соответствующее значение.

## ОШИБКИ
EBADF

Значение fd не является правильным файловым дескриптором.

EINVAL

В flags указан некорректный бит; или некорректное значение в offset или nbytes.

EIO

Ошибка ввода-вывода.

ENOMEM

Не хватает памяти.

ENOSPC

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

ESPIPE

Значение fd ссылается не на обычный файл, блочное устройство, или каталог.

## ВЕРСИИ
Вызов sync_file_range() появился в Linux в ядре версии 2.6.17.

## СООТВЕТСТВИЕ СТАНДАРТАМ
Данный системный вызов есть только в Linux, и не должен использоваться в переносимых приложениях.

## ЗАМЕЧАНИЯ

### sync_file_range2()
Для некоторых архитектур (например, PowerPC, ARM) требуется, чтобы 64-битные аргументы были выровнены в нужных парах регистров. На таких архитектурах для объявления вызова sync_file_range(), показанного в СИНТАКСИСЕ, для заполнения между аргументами fd и offset расходовался бы ещё один регистр впустую (подробности смотрите в syscall(2)). Поэтому в этих архитектурах определён другой системный вызов с подходящим порядком аргументов:

```
int sync_file_range2(int fd, unsigned int flags,
                     off64_t offset, off64_t nbytes);
```

Поведение данного системного вызова такое же как sync_file_range().

Системный вызов с таких объявлением впервые появился для архитектуры ARM в Linux 2.6.20 под именем arm_sync_file_range(). В Linux 2.6.22 он был переименован, так как аналогичный системный вызов был добавлен для PowerPC. Для архитектур, поддерживаемых glibc, glibc прозрачно обёртывает sync_file_range2() именем sync_file_range().

## СМОТРИТЕ ТАКЖЕ
fdatasync(2), fsync(2), msync(2), sync(2)


syscall

title: syscall(2)

summary: непрямой системный вызов

text:
# syscall(2)

## ИМЯ
syscall - непрямой системный вызов

## ОБЗОР

```
#define _GNU_SOURCE         /* см. feature_test_macros(7) */
#include <unistd.h>
#include <sys/syscall.h>   /* для определений SYS_xxx */
```

```
long syscall(long number, ...);
```

## ОПИСАНИЕ
syscall() — это маленькая библиотечная функция, которая делает системный вызов, чей интерфейс ассемблерного языка указывается в number, с дополнительными аргументами. Выполнение syscall() нужно, например, для запуска системного вызова, у которого нет обёрточной функции в библиотеке C.

При вызове syscall() сохраняет регистры ЦП до выполнения системного вызова, восстанавливает регистры при возврате из системного вызова и если возникла ошибка, то сохраняет любой код, полученный от системного вызова, в errno(3).

Символьные константы для системных вызовов можно найти в заголовочном файле <sys/syscall.h>.

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
Возвращаемое значение определяется вызываемым системным вызовом. При успешном выполнении обычно возвращается 0. При ошибке возвращается -1, при этом код ошибки сохраняется в errno.

## ЗАМЕЧАНИЯ
Вызов syscall() впервые появился в 4BSD.

### Требования, зависящие от архитектуры
Каждый ABI архитектуры имеет свои собственные требования по передаче аргументов системного вызова в ядро. Для системных вызовов, имеющих обёртку в glibc (большинство системных вызовов), копирование аргументов в правильные регистры с учётом архитектуры выполняется в самой glibc. Однако при выполнении системного вызова через syscall(), вызывающий сам должен учитывать особенности архитектуры; чаще всего это относится к 32-битным архитектурам.

Например, на архитектуре ARM Embedded ABI (EABI) 64-битное значение (long long) должно быть выровнено по чётной паре регистров. То есть, при использовании syscall() вместо обёрточной функции glibc системный вызов readahead() на ARM вызывался бы с учётом EABI (режим с обратным порядком байт) следующим образом:

```
syscall(SYS_readahead, fd, 0,

        (unsigned int) (offset & 0xFFFFFFFF),

        (unsigned int) (offset >> 32),

        count);
```

Так как смещение аргумента 64 бита, и первый аргумент (fd) передаётся в регистре r0, вызывающий должен разделить и выровнять 64-битное значение так, чтобы оно передавалось в паре регистров r2/r3. Это выполняется вставкой пустого значения в r1 (второго аргумент 0). Также нужно не забывать о преобразовании порядка байт (в соответствии с C ABI платформы).

Подобные сложности можно видеть на MIPS с O32 ABI, на PowerPC и parisc с 32-битным ABI и на Xtensa.

Заметим, что хотя в parisc C ABI также используется выравнивание пары регистров, в нём используется слой shim, который прячет проблему от пространства пользователя.

Это относится к системным вызовам fadvise64_64(2), ftruncate64(2), posix_fadvise(2), pread64(2), pwrite64(2), readahead(2), sync_file_range(2) и truncate64(2).

Это не влияет на syscall-ы, который самостоятельно разделяют и собирают 64-битные значения, например _llseek(2), preadv(2), preadv2(2), pwritev(2) и pwritev2(2). Добро пожаловать в чудесную страну исторического наследия.

### Архитектурные соглашения по вызовам
В каждой архитектуре есть собственный способ передачи аргументов вызову ядра. Особенности различных архитектур перечислены в двух таблицах ниже.

Поля первой таблицы: инструкция для перехода в режим ядра (может быть не быстрым или лучшим способом перехода в ядро, лучше использовать vdso(7)), регистр для указания номера системного вызова, регистр(ы) возврата результата работы системного вызова и регистр сигнализации ошибки.

Арх/ABI

Инструкция

Система

Ret

Ret

Ошибка

замечания

call #

знач

знач2

_

alpha

callsys

v0

v0

a4

a3

1, 6

arc

trap0

r8

r0

-

-

arm/OABI

swi NR

-

a1

-

-

2

arm/EABI

swi 0x0

r7

r0

r1

-

arm64

svc #0

x8

x0

x1

-

blackfin

excpt 0x0

P0

R0

-

-

i386

int $0x80

eax

eax

edx

-

ia64

break 0x100000

r15

r8

r9

r10

1, 6

m68k

trap #0

d0

d0

-

-

microblaze

brki r14,8

r12

r3

-

-

mips

syscall

v0

v0

v1

a3

1, 6

nios2

trap

r2

r2

-

r7

parisc

ble 0x100(%sr2, %r0)

r20

r28

-

-

powerpc

sc

r0

r3

-

r0

1

powerpc64

sc

r0

r3

-

cr0.SO

1

riscv

ecall

a7

a0

a1

-

s390

svc 0

r1

r2

r3

-

3

s390x

svc 0

r1

r2

r3

-

3

superh

trap #0x17

r3

r0

r1

-

4, 6

sparc/32

t 0x10

g1

o0

o1

psr/csr

1, 6

sparc/64

t 0x6d

g1

o0

o1

psr/csr

1, 6

tile

swint1

R10

R00

-

R01

1

x86-64

syscall

rax

rax

rdx

-

5

x32

syscall

rax

rax

rdx

-

5

xtensa

syscall

a2

a2

-

-

Замечания:

[1]

На некоторых архитектурах для показа отказа системного вызова используется регистр с простым логическим значением (0 — нет ошибки, -1 — ошибка). Настоящее значение ошибки всё равно содержится в регистре возврата. На sparc, вместо полного регистра используется бит переноса (csr) в регистре состояния процессора (psr). На powerpc64, используется бит общего переполнения (SO) в поле 0 регистра условия (cr0).

[2]

NR — номер системного вызова.

[3]

Для s390 и s390x NR (номер системного вызова) может передаваться напрямую с помощью svc NR, если он меньше 256.

[4]

На SuperH, номер ловушки (trap number) контролирует максимальное количество передаваемых аргументов.trap #0x10 можно использовать только с системными вызовами без аргументов, trap #0x11 можно использовать только с системными вызовами без или с одним аргументом и так далее до trap #0x17 (7 аргументов в системном вызове).

[5]

Для x32 ABI используется общая с x86-64 ABI таблица syscall, но есть несколько отличий:

- Чтобы показать, что системный вызов запрошен из x32 ABI, введёндополнительный бит __X32_SYSCALL_BIT, который побитно складывается с номером системного вызова. ABI, используемый процессом, частично влияет на поведение процесса, включая обработку сигналов или перезапуск или системного вызова.

- Так как на x32 размеры типа long и указателя различаются, то различны раскладки некоторых (но не всех; например, struct timeval или struct rlimit 64-битные) структур. Для их обработки в таблицу системных вызовов добавлены дополнительные системные вызовы; они начинаются с номера 512 (без __X32_SYSCALL_BIT). Например, __NR_readv определён как 19 в x86-64 ABI и как __X32_SYSCALL_BIT | 515 в x32 ABI. Большинство этих дополнительных системных вызовов на самом деле одинаковы с системными вызовами, используемыми для предоставления совместимости с i386. Однако есть исключения, например, preadv2(2), который использует элементы struct iovec с 4-байтовыми указателями и размерами (в терминах ядра — «compat_iovec»), но передаёт 8-байтовый аргумент pos в одном регистре, а не в двух, как это делается в других ABI.

[6]

Некоторые архитектуры (Alpha, IA-64, MIPS, SuperH, sparc/32 sparc/64) используют дополнительный регистр ("Retval2" в таблице выше) для обратной передачи второго возвращаемого значения из системного вызова pipe(2); в Alpha это также используется в зависимых от архитектуры системных вызовах getxpid(2), getxuid(2) и getxgid(2). На других архитектурах в интерфейсе системных вызовов второй регистр для возвращаемого значения не используется, даже если он определён в System V ABI.

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

Арх/ABI

арг1

арг2

арг3

арг4

арг5

арг6

арг7

замечания

_

alpha

a0

a1

a2

a3

a4

a5

-

arc

r0

r1

r2

r3

r4

r5

-

arm/OABI

a1

a2

a3

a4

v1

v2

v3

arm/EABI

r0

r1

r2

r3

r4

r5

r6

arm64

x0

x1

x2

x3

x4

x5

-

blackfin

R0

R1

R2

R3

R4

R5

-

i386

ebx

ecx

edx

esi

edi

ebp

-

ia64

out0

out1

out2

out3

out4

out5

-

m68k

d1

d2

d3

d4

d5

a0

-

microblaze

r5

r6

r7

r8

r9

r10

-

mips/o32

a0

a1

a2

a3

-

-

-

1

mips/n32,64

a0

a1

a2

a3

a4

a5

-

nios2

r4

r5

r6

r7

r8

r9

-

parisc

r26

r25

r24

r23

r22

r21

-

powerpc

r3

r4

r5

r6

r7

r8

r9

powerpc64

r3

r4

r5

r6

r7

r8

-

riscv

a0

a1

a2

a3

a4

a5

-

s390

r2

r3

r4

r5

r6

r7

-

s390x

r2

r3

r4

r5

r6

r7

-

superh

r4

r5

r6

r7

r0

r1

r2

sparc/32

o0

o1

o2

o3

o4

o5

-

sparc/64

o0

o1

o2

o3

o4

o5

-

tile

R00

R01

R02

R03

R04

R05

-

x86-64

rdi

rsi

rdx

r10

r8

r9

-

x32

rdi

rsi

rdx

r10

r8

r9

-

xtensa

a6

a3

a4

a5

a8

a9

-

Замечания:

[1]

По соглашению в mips/o32 аргументы системных вызовов с 5 по 8 передаются через пользовательский стек.

Заметим, что эти таблицы не описывают полное соглашение о вызове — некоторые архитектуры могут затирать другие регистры и это здесь не описано.

## ПРИМЕР

```
#define _GNU_SOURCE
#include <unistd.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <signal.h>
int
main(int argc, char *argv[])
{

    pid_t tid;

    tid = syscall(SYS_gettid);

    syscall(SYS_tgkill, getpid(), tid, SIGHUP);
}
```

## СМОТРИТЕ ТАКЖЕ
_syscall(2), intro(2), syscalls(2), errno(3), vdso(7)


syscalls

title: syscalls(2)

summary: системные вызовы Linux

text:
# syscalls(2)

## ИМЯ
syscalls - системные вызовы Linux

## ОБЗОР
Системные вызовы Linux.

## ОПИСАНИЕ
Системный вызов — это основной интерфейс между приложением и ядром Linux.

### Системные вызовы и обёрточные библиотечные функции
Обычно, системные вызовы не вызываются напрямую, это делается через обёрточную функцию из glibc (или другой библиотеки). Подробней о непосредственном вызове системного вызова, смотрите intro(2). Часто, но не всегда, имя обёрточной функции совпадает с именем системного вызова, который она вызывает. Например, в glibc есть функция chdir(), которая вызывает делающий всё работу системный вызов «chdir».

Часто, обёрточная функция glibc очень маленькая, она просто копирует аргументы в нужные регистры перед запуском системного вызова, а затем присваивает переменной errno значение, которое было возвращено системным вызовом. (Эти те же шаги выполняет syscall(2), её можно использовать для осуществления системных вызовов, для которых нет обёрточных функций.) Замечание: системные вызовы указывают, что произошла ошибка возвращая отрицательное целое число вызывающей стороне (если в архитектуре нет отдельного регистра/флага ошибки, смотрите syscall(2)); когда это происходит, обёрточная функция меняет знак у возвращённого значения (на положительный), копирует его в errno и возвращает -1 вызвавшей обёртку функции.

Иногда, однако, обёрточная функция производит дополнительную работу до осуществления системного вызова. Например, в настоящее время существует (по причинам, описанным далее) два похожих системных вызова — truncate(2) и truncate64(2); обёрточная функция glibc truncate() проверяет какой из системных вызовов предоставляет ядро и решает какой нужно задействовать.

### Список системных вызовов
Далее приведён список список системных вызовов Linux. В колонке Ядро указана версия ядра для системных вызовов, которые появились в Linux 2.2, и с какой именно версии. Также заметим следующее:

- Если версия ядра не указана, то системный вызов появился в ядре 1.0 или более раннем.

- Системные вызовы, помеченные "1.2", скорее всего появились в в версиях ядра 1.1.x, и впервые появились в стабильном ядре 1.2. (Разработка ядра 1.2 началась с ответвления от ядра 1.0.6 и прошла несколько выпусков ядер 1.1.x.)

- Системные вызовы, помеченные "1.2", скорее всего появились в в версиях ядра 1.3.x, и впервые появились в стабильном ядре 2.0. (Разработка ядра 2.0 началась с ответвления от ядра 1.2.x, начиная, приблизительно, с 1.2.10, и прошла несколько выпусков ядер 1.3.x.)

- Системные вызовы, помеченные "2.2", скорее всего появились в в версиях ядра 2.1.x, и впервые появились в стабильном ядре 2.2.0. (Разработка ядра 2.2 началась с ответвления от ядра 2.0.21, и прошла несколько выпусков ядер 2.1.x.)

- Системные вызовы, помеченные "2.4", скорее всего появились в в версиях ядра 2.3.x, и впервые появились в стабильном ядре 2.4.0. (Разработка ядра 2.4 началась с ответвления от ядра 2.2.8, и прошла несколько выпусков ядер 2.3.x.)

- Системные вызовы, помеченные "2.6", скорее всего появились в в версиях ядра 2.5.x, и впервые появились в стабильном ядре 2.6.0. (Разработка ядра 2.6 началась с ответвления от ядра 2.4.15, и прошла несколько выпусков ядер 2.5.x.)

- Начиная с ядра 2.6.0 порядок разработки был изменён, и новые системные вызовы могут появляться в каждом выпуске 2.6.x. В этом случае для системного вызова указан точный номер версии. 2.6.39. Это соглашение продолжает действовать и в ядрах серии 3.x, которая началась с ядра 2.6.39, и в ядрах серии 4.х, которая началась с ядра 3.19.

- Иногда системный вызов, добавленный в текущую на тот момент стабильную ветвь ядра, переносился в предыдущие стабильные ветви ядра. Например, некоторые системные вызовы, которые появились в в 2.6.x были перенесены и в выпуски 2.4.x, начиная с 2.4.15. Если это производилось, будут показаны основные версии обеих ветвей ядра.

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

System call

Kernel

Notes

_llseek(2)

1.2

_newselect(2)

2.0

_sysctl(2)

2.0

accept(2)

2.0

смотрите замечания по socketcall(2)

accept4(2)

2.6.28

access(2)

1.0

acct(2)

1.0

add_key(2)

2.6.10

adjtimex(2)

1.0

alarm(2)

1.0

alloc_hugepages(2)

2.5.36

удалён из Linux 2.5.44

arc_gettls(2)

3.9

только на ARC

arc_settls(2)

3.9

только на ARC

arc_usr_cmpxchg(2)

4.9

только на ARC

arch_prctl(2)

2.6

x86_64, x86 начиная с 4.12

atomic_barrier(2)

2.6.34

только на m68k

atomic_cmpxchg_32(2)

2.6.34

только на m68k

bdflush(2)

1.2

устарел (ничего не делает) начиная с 2.6

bfin_spinlock(2)

2.6.22

только на Blackfin (перенос удалён в Linux 4.17)

bind(2)

2.0

смотрите замечания по socketcall(2)

bpf(2)

3.18

brk(2)

1.0

breakpoint(2)

2.2

только в ARM OABI, определён с префиксом __ARM_NR

cacheflush(2)

1.2

не для x86

capget(2)

2.2

capset(2)

2.2

chdir(2)

1.0

chmod(2)

1.0

chown(2)

2.2

смотрите в chown(2) подробности о версии

chown32(2)

2.4

chroot(2)

1.0

clock_adjtime(2)

2.6.39

clock_getres(2)

2.6

clock_gettime(2)

2.6

clock_nanosleep(2)

2.6

clock_settime(2)

2.6

clone2(2)

2.4

только на IA-64

clone(2)

1.0

clone3(2)

5.3

close(2)

1.0

cmpxchg_badaddr(2)

2.6.36

только на Tile (перенос удалён в Linux 4.17)

connect(2)

2.0

смотрите замечания по socketcall(2)

copy_file_range(2)

4.5

creat(2)

1.0

create_module(2)

1.0

удалён из Linux 2.6

delete_module(2)

1.0

dma_memcpy(2)

2.6.22

только на Blackfin (перенос удалён в Linux 4.17)

dup(2)

1.0

dup2(2)

1.0

dup3(2)

2.6.27

epoll_create(2)

2.6

epoll_create1(2)

2.6.27

epoll_ctl(2)

2.6

epoll_pwait(2)

2.6.19

epoll_wait(2)

2.6

eventfd(2)

2.6.22

eventfd2(2)

2.6.27

execv(2)

2.0

только на SPARC/SPARC64, для совместимости с SunOS

execve(2)

1.0

execveat(2)

3.19

exit(2)

1.0

exit_group(2)

2.6

faccessat(2)

2.6.16

fadvise64(2)

2.6

fadvise64_64(2)

2.6

fallocate(2)

2.6.23

fanotify_init(2)

2.6.37

fanotify_mark(2)

2.6.37

fchdir(2)

1.0

fchmod(2)

1.0

fchmodat(2)

2.6.16

fchown(2)

1.0

fchown32(2)

2.4

fchownat(2)

2.6.16

fcntl(2)

1.0

fcntl64(2)

2.4

fdatasync(2)

2.0

fgetxattr(2)

2.6; 2.4.18

finit_module(2)

3.8

flistxattr(2)

2.6; 2.4.18

flock(2)

2.0

fork(2)

1.0

free_hugepages(2)

2.5.36

удалён из Linux 2.5.44

fremovexattr(2)

2.6; 2.4.18

fsconfig(2)

5.2

fsetxattr(2)

2.6; 2.4.18

fsmount(2)

5.2

fsopen(2)

5.2

fspick(2)

5.2

fstat(2)

1.0

fstat64(2)

2.4

fstatat64(2)

2.6.16

fstatfs(2)

1.0

fstatfs64(2)

2.6

fsync(2)

1.0

ftruncate(2)

1.0

ftruncate64(2)

2.4

futex(2)

2.6

futimesat(2)

2.6.16

get_kernel_syms(2)

1.0

удалён из Linux 2.6

get_mempolicy(2)

2.6.6

get_robust_list(2)

2.6.17

get_thread_area(2)

2.6

get_tls(2)

4.15

только в ARM OABI, есть префиксом __ARM_NR

getcpu(2)

2.6.19

getcwd(2)

2.2

getdents(2)

2.0

getdents64(2)

2.4

getdomainname(2)

2.2

SPARC, SPARC64; доступен как osf_getdomainname(2) на Alpha начиная с Linux 2.0

getdtablesize(2)

2.0

SPARC (удалён в 2.6.26), доступен начиная с Linux 2.0 на Alpha как osf_getdtablesize(2)

getegid(2)

1.0

getegid32(2)

2.4

geteuid(2)

1.0

geteuid32(2)

2.4

getgid(2)

1.0

getgid32(2)

2.4

getgroups(2)

1.0

getgroups32(2)

2.4

gethostname(2)

2.0

Alpha, был доступен на SPARC до Linux 2.6.26

getitimer(2)

1.0

getpeername(2)

2.0

смотрите замечания по socketcall(2)

getpagesize(2)

2.0

не для x86

getpgid(2)

1.0

getpgrp(2)

1.0

getpid(2)

1.0

getppid(2)

1.0

getpriority(2)

1.0

getrandom(2)

3.17

getresgid(2)

2.2

getresgid32(2)

2.4

getresuid(2)

2.2

getresuid32(2)

2.4

getrlimit(2)

1.0

getrusage(2)

1.0

getsid(2)

2.0

getsockname(2)

2.0

смотрите замечания по socketcall(2)

getsockopt(2)

2.0

смотрите замечания по socketcall(2)

gettid(2)

2.4.11

gettimeofday(2)

1.0

getuid(2)

1.0

getuid32(2)

2.4

getunwind(2)

2.4.8

только IA-64; устарел

getxattr(2)

2.6; 2.4.18

getxgid(2)

2.0

только на Alpha; смотрите ЗАМЕЧАНИЯ

getxpid(2)

2.0

только на Alpha; смотрите ЗАМЕЧАНИЯ

getxuid(2)

2.0

только на Alpha; смотрите ЗАМЕЧАНИЯ

init_module(2)

1.0

inotify_add_watch(2)

2.6.13

inotify_init(2)

2.6.13

inotify_init1(2)

2.6.27

inotify_rm_watch(2)

2.6.13

io_cancel(2)

2.6

io_destroy(2)

2.6

io_getevents(2)

2.6

io_pgetevents(2)

4.18

io_setup(2)

2.6

io_submit(2)

2.6

io_uring_enter(2)

5.1

io_uring_register(2)

5.1

io_uring_setup(2)

5.1

ioctl(2)

1.0

ioperm(2)

1.0

iopl(2)

1.0

ioprio_get(2)

2.6.13

ioprio_set(2)

2.6.13

ipc(2)

1.0

kcmp(2)

3.5

kern_features(2)

3.7

только на SPARC64

kexec_file_load(2)

3.17

kexec_load(2)

2.6.13

keyctl(2)

2.6.10

kill(2)

1.0

lchown(2)

1.0

смотрите в chown(2) подробности о версии

lchown32(2)

2.4

lgetxattr(2)

2.6; 2.4.18

link(2)

1.0

linkat(2)

2.6.16

listen(2)

2.0

смотрите замечания по socketcall(2)

listxattr(2)

2.6; 2.4.18

llistxattr(2)

2.6; 2.4.18

lookup_dcookie(2)

2.6

lremovexattr(2)

2.6; 2.4.18

lseek(2)

1.0

lsetxattr(2)

2.6; 2.4.18

lstat(2)

1.0

lstat64(2)

2.4

madvise(2)

2.4

mbind(2)

2.6.6

memory_ordering(2)

2.2

только на SPARC64

metag_get_tls(2)

3.9

только на Metag (перенос удалён в Linux 4.17)

metag_set_fpu_flags(2)

3.9

только на Metag (перенос удалён в Linux 4.17)

metag_set_tls(2)

3.9

только на Metag (перенос удалён в Linux 4.17)

metag_setglobalbit(2)

3.9

только на Metag (перенос удалён в Linux 4.17)

membarrier(2)

3.17

memfd_create(2)

3.17

migrate_pages(2)

2.6.16

mincore(2)

2.4

mkdir(2)

1.0

mkdirat(2)

2.6.16

mknod(2)

1.0

mknodat(2)

2.6.16

mlock(2)

2.0

mlock2(2)

4.4

mlockall(2)

2.0

mmap(2)

1.0

mmap2(2)

2.4

modify_ldt(2)

1.0

mount(2)

1.0

move_mount(2)

5.2

move_pages(2)

2.6.18

mprotect(2)

1.0

mq_getsetattr(2)

2.6.6

mq_notify(2)

2.6.6

mq_open(2)

2.6.6

mq_timedreceive(2)

2.6.6

mq_timedsend(2)

2.6.6

mq_unlink(2)

2.6.6

mremap(2)

2.0

msgctl(2)

2.0

смотрите замечания по ipc(2)

msgget(2)

2.0

смотрите замечания по ipc(2)

msgrcv(2)

2.0

смотрите замечания по ipc(2)

msgsnd(2)

2.0

смотрите замечания по ipc(2)

msync(2)

2.0

munlock(2)

2.0

munlockall(2)

2.0

munmap(2)

1.0

name_to_handle_at(2)

2.6.39

nanosleep(2)

2.0

newfstatat(2)

2.6.16

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

nfsservctl(2)

2.2

удалён из Linux 3.1

nice(2)

1.0

old_adjtimex(2)

2.0

только на Alpha; смотрите ЗАМЕЧАНИЯ

old_getrlimit(2)

2.4

старый вариант getrlimit(2), использующий другое значение для RLIM_INFINITY

oldfstat(2)

1.0

oldlstat(2)

1.0

oldolduname(2)

1.0

oldstat(2)

1.0

oldumount(2)

2.4.116

название старого umount(2) syscall на Alpha

olduname(2)

1.0

open(2)

1.0

open_by_handle_at(2)

2.6.39

open_tree(2)

5.2

openat(2)

2.6.16

or1k_atomic(2)

3.1

только на OpenRISC 1000

pause(2)

1.0

pciconfig_iobase(2)

2.2.15; 2.4

не для x86

pciconfig_read(2)

2.0.26; 2.2

не для x86

pciconfig_write(2)

2.0.26; 2.2

не для x86

perf_event_open(2)

2.6.31

был perf_counter_open() в 2.6.31; переименован в 2.6.32

personality(2)

1.2

perfctr(2)

2.2

только на SPARC; удалён в 2.6.34

perfmonctl(2)

2.4

только на IA-64

pidfd_send_signal(2)

5.1

pidfd_open(2)

5.3

pipe(2)

1.0

pipe2(2)

2.6.27

pivot_root(2)

2.4

pkey_alloc(2)

4.8

pkey_free(2)

4.8

pkey_mprotect(2)

4.8

poll(2)

2.0.36; 2.2

ppoll(2)

2.6.16

prctl(2)

2.2

pread(2)

используется для pread64(2) на AVR32 (перенос удалён в Linux 4.12) и Blackfin (перенос удалён в Linux 4.17)

pread64(2)

добавлен под именем «pread» в 2.2 переименован в «pread64» в 2.6

preadv(2)

2.6.30

preadv2(2)

4.6

prlimit64(2)

2.6.36

process_vm_readv(2)

3.2

process_vm_writev(2)

3.2

pselect6(2)

2.6.16

ptrace(2)

1.0

pwrite(2)

используется для pwrite64(2) на AVR32 (перенос удалён в Linux 4.12) и Blackfin (перенос удалён в Linux 4.17)

pwrite64(2)

добавлен под именем «pwrite» в 2.2 переименован в «pwrite64» в 2.6

pwritev(2)

2.6.30

pwritev2(2)

4.6

query_module(2)

2.2

удалён из Linux 2.6

quotactl(2)

1.0

read(2)

1.0

readahead(2)

2.4.13

readdir(2)

1.0

readlink(2)

1.0

readlinkat(2)

2.6.16

readv(2)

2.0

reboot(2)

1.0

recv(2)

2.0

смотрите замечания по socketcall(2)

recvfrom(2)

2.0

смотрите замечания по socketcall(2)

recvmsg(2)

2.0

смотрите замечания по socketcall(2)

recvmmsg(2)

2.6.33

remap_file_pages(2)

2.6

устарел начиная с 3.16

removexattr(2)

2.6; 2.4.18

rename(2)

1.0

renameat(2)

2.6.16

renameat2(2)

3.15

request_key(2)

2.6.10

restart_syscall(2)

2.6

riscv_flush_icache(2)

4.15

только на RISC-V

rmdir(2)

1.0

rseq(2)

4.18

rt_sigaction(2)

2.2

rt_sigpending(2)

2.2

rt_sigprocmask(2)

2.2

rt_sigqueueinfo(2)

2.2

rt_sigreturn(2)

2.2

rt_sigsuspend(2)

2.2

rt_sigtimedwait(2)

2.2

rt_tgsigqueueinfo(2)

2.6.31

rtas(2)

2.6.2

только на PowerPC/PowerPC64

s390_runtime_instr(2)

3.7

только для s390

s390_pci_mmio_read(2)

3.19

только для s390

s390_pci_mmio_write(2)

3.19

только для s390

s390_sthyi(2)

4.15

только для s390

s390_guarded_storage(2)

4.12

только для s390

sched_get_affinity(2)

2.6

название sched_getaffinity(2) на SPARC и SPARC64

sched_get_priority_max(2)

2.0

sched_get_priority_min(2)

2.0

sched_getaffinity(2)

2.6

sched_getattr(2)

3.14

sched_getparam(2)

2.0

sched_getscheduler(2)

2.0

sched_rr_get_interval(2)

2.0

sched_set_affinity(2)

2.6

название sched_setaffinity(2) на SPARC и SPARC64

sched_setaffinity(2)

2.6

sched_setattr(2)

3.14

sched_setparam(2)

2.0

sched_setscheduler(2)

2.0

sched_yield(2)

2.0

seccomp(2)

3.17

select(2)

1.0

semctl(2)

2.0

смотрите замечания по ipc(2)

semget(2)

2.0

смотрите замечания по ipc(2)

semop(2)

2.0

смотрите замечания по ipc(2)

semtimedop(2)

2.6; 2.4.22

send(2)

2.0

смотрите замечания по socketcall(2)

sendfile(2)

2.2

sendfile64(2)

2.6; 2.4.19

sendmmsg(2)

3.0

sendmsg(2)

2.0

смотрите замечания по socketcall(2)

sendto(2)

2.0

смотрите замечания по socketcall(2)

set_mempolicy(2)

2.6.6

set_robust_list(2)

2.6.17

set_thread_area(2)

2.6

set_tid_address(2)

2.6

set_tls(2)

2.6.11

только в ARM OABI/EABI (константа с префиксом __ARM_NR)

setdomainname(2)

1.0

setfsgid(2)

1.2

setfsgid32(2)

2.4

setfsuid(2)

1.2

setfsuid32(2)

2.4

setgid(2)

1.0

setgid32(2)

2.4

setgroups(2)

1.0

setgroups32(2)

2.4

sethae(2)

2.0

только на Alpha; смотрите ЗАМЕЧАНИЯ

sethostname(2)

1.0

setitimer(2)

1.0

setns(2)

3.0

setpgid(2)

1.0

setpgrp(2)

2.0

дополнительное имя для setpgid(2) на Alpha

setpriority(2)

1.0

setregid(2)

1.0

setregid32(2)

2.4

setresgid(2)

2.2

setresgid32(2)

2.4

setresuid(2)

2.2

setresuid32(2)

2.4

setreuid(2)

1.0

setreuid32(2)

2.4

setrlimit(2)

1.0

setsid(2)

1.0

setsockopt(2)

2.0

смотрите замечания по socketcall(2)

settimeofday(2)

1.0

setuid(2)

1.0

setuid32(2)

2.4

setup(2)

1.0

удалён в 2.2

setxattr(2)

2.6; 2.4.18

sgetmask(2)

1.0

shmat(2)

2.0

смотрите замечания по ipc(2)

shmctl(2)

2.0

смотрите замечания по ipc(2)

shmdt(2)

2.0

смотрите замечания по ipc(2)

shmget(2)

2.0

смотрите замечания по ipc(2)

shutdown(2)

2.0

смотрите замечания по socketcall(2)

sigaction(2)

1.0

sigaltstack(2)

2.2

signal(2)

1.0

signalfd(2)

2.6.22

signalfd4(2)

2.6.27

sigpending(2)

1.0

sigprocmask(2)

1.0

sigreturn(2)

1.0

sigsuspend(2)

1.0

socket(2)

2.0

смотрите замечания по socketcall(2)

socketcall(2)

1.0

socketpair(2)

2.0

смотрите замечания по socketcall(2)

spill(2)

2.6.13

только на Xtensa

splice(2)

2.6.17

spu_create(2)

2.6.16

только на PowerPC/PowerPC64

spu_run(2)

2.6.16

только на PowerPC/PowerPC64

sram_alloc(2)

2.6.22

Blackfin (перенос удалён в Linux 4.17)

sram_free(2)

2.6.22

Blackfin (перенос удалён в Linux 4.17)

ssetmask(2)

1.0

stat(2)

1.0

stat64(2)

2.4

statfs(2)

1.0

statfs64(2)

2.6

statx(2)

4.11

stime(2)

1.0

subpage_prot(2)

2.6.25

только на PowerPC/PowerPC64

swapcontext(2)

2.6.3

только на PowerPC/PowerPC64

switch_endian(2)

4.1

только для PowerPC64

swapcontext(2)

2.6.3

только для PowerPC

swapoff(2)

1.0

swapon(2)

1.0

symlink(2)

1.0

symlinkat(2)

2.6.16

sync(2)

1.0

sync_file_range(2)

2.6.17

sync_file_range2(2)

2.6.22

syncfs(2)

2.6.39

sys_debug_setcontext(2)

2.6.11

только для PowerPC

syscall(2)

1.0

ещё доступен в ARM OABI и MIPS O32 ABI

sysfs(2)

1.2

sysinfo(2)

1.0

syslog(2)

1.0

sysmips(2)

2.6.0

только на MIPS

tee(2)

2.6.17

tgkill(2)

2.6

time(2)

1.0

timer_create(2)

2.6

timer_delete(2)

2.6

timer_getoverrun(2)

2.6

timer_gettime(2)

2.6

timer_settime(2)

2.6

timerfd_create(2)

2.6.25

timerfd_gettime(2)

2.6.25

timerfd_settime(2)

2.6.25

times(2)

1.0

tkill(2)

2.6; 2.4.22

truncate(2)

1.0

truncate64(2)

2.4

ugetrlimit(2)

2.4

umask(2)

1.0

umount(2)

1.0

umount2(2)

2.2

uname(2)

1.0

unlink(2)

1.0

unlinkat(2)

2.6.16

unshare(2)

2.6.16

uselib(2)

1.0

ustat(2)

1.0

userfaultfd(2)

4.3

usr26(2)

2.4.8.1

только в ARM OABI

usr32(2)

2.4.8.1

только в ARM OABI

utime(2)

1.0

utimensat(2)

2.6.22

utimes(2)

2.2

utrap_install(2)

2.2

только на SPARC64

vfork(2)

2.2

vhangup(2)

1.0

vm86old(2)

1.0

ранее «vm86»; переименован в 2.0.28/2.2

vm86(2)

2.0.28; 2.2

vmsplice(2)

2.6.17

wait4(2)

1.0

waitid(2)

2.6.10

waitpid(2)

1.0

write(2)

1.0

writev(2)

2.0

xtensa(2)

2.6.13

только на Xtensa

Для многих платформ, включая x86-32, все сокетные вызовы мультиплексируются (с помощью обёрточных функций glibc) через socketcall(2), а подобные IPC вызовы System V мультиплексируются через ipc(2).

Хотя для них и зарезервированы места в таблице системных вызовов, следующие системные вызовы не реализованы в стандартном ядре: afs_syscall(2), break(2), ftime(2), getpmsg(2), gtty(2), idle(2), lock(2), madvise1(2), mpx(2), phys(2), prof(2), profil(2), putpmsg(2), security(2), stty(2), tuxcall(2), ulimit(2) и vserver(2) (см. также unimplemented(2)). Однако ftime(3), profil(3) и ulimit(3) есть среди библиотечных функций. Место для phys(2) занято начиная с ядра 2.1.116 под umount(2); phys(2) никогда не будет реализован. Вызовы getpmsg(2) и putpmsg(2) есть в ядрах с заплатами, обеспечивающими поддержку STREAMS, и могут никогда не появиться в стандартном ядре.

На короткое время появлялся set_zone_reclaim(2), добавленный в Linux 2.6.13 и удалённый в 2.6.16; данный системный вызов никогда не был доступен из пользовательского пространства.

## ЗАМЕЧАНИЯ
Чаще всего, код системного вызова с номером __NR_xxx, определённого в /usr/include/asm/unistdh, можно найти в исходном коде ядра Linux в функции sys_xxx(). Есть много исключений из этого правила, в основном из-за того, что большинство старых системных вызовов заменена на новые, при чём без всякой системы. На платформах с эмуляцией собственнических ОС, таких как sparc, sparc64 и alpha, существует много дополнительных системных вызовов; для mips64 также есть полный набор 32-битных системных вызовов.

С течением времени при необходимости происходили изменения в интерфейсе некоторых системных вызовов. Одной из причин таких изменений была необходимость увеличения размера структур или скалярных значений передаваемых системному вызову. Из-за этих изменений на некоторых архитектурах (а именно на старых 32-битных i386) появились различные группы похожих системных вызовов (например, truncate(2) и truncate64(2)), которые выполняют одинаковые задачи, но отличаются размером своих аргументов. (Как уже отмечалось, на приложения это не влияет: обёрточные функции glibc выполняют некоторые действия по запуску правильного системного вызова, и это обеспечивает совместимость по ABI для старых двоичных файлов.) Примеры системных вызовов, у которых есть несколько версий:

- В настоящее время есть три различные версии stat(2): sys_stat() (место __NR_oldstat), sys_newstat() (место __NR_stat) и sys_stat64() (место __NR_stat64), последняя используется в в данный момент. Похожая ситуация с lstat(2) и fstat(2).

- Похожим образом определены __NR_oldolduname, __NR_olduname и __NR_uname для вызовов sys_olduname(), sys_uname() и sys_newuname().

- В Linux 2.0 появилась новая версия vm86(2), новая и старая версии ядерных процедур называются sys_vm86old() и sys_vm86().

- В Linux 2.4 появилась новая версия getrlimit(2) новая и старая версии ядерных процедур называются sys_old_getrlimit() (место __NR_getrlimit) и sys_getrlimit() (место __NR_ugetrlimit).

- В Linux 2.4 увеличено размер поля ID пользователей и групп с 16 до 32 бит. Для поддержки этого изменения добавлено несколько системных вызовов (например, chown32(2), getuid32(2), getgroups32(2), setresuid32(2)), упраздняющих ранние вызовы с теми же именами, но без суффикса "32".

- В Linux 2.4 добавлена поддержка доступа к большим файлам (у которых размеры и смещения не умещаются в 32 бита) в приложениях на 32-битных архитектурах. Для этого потребовалось внести изменения в системные вызовы, работающие с размерами и смещениями по файлам. Были добавлены следующие системные вызовы: fcntl64(2), getdents64(2), stat64(2), statfs64(2), truncate64(2) и их аналоги, которые обрабатывают файловые дескрипторы или символьные ссылки. Эти системные вызовы упраздняют старые системные вызовы, которые, за исключением вызовов «stat», называются также, но не имеют суффикса «64».

На новых платформах, имеющих только 64-битный доступ к файлам и 32-битные UID/GID (например, alpha, ia64, s390x, x86-64), есть только одна версия системных вызовов для UID/GID и файлового доступа. На платформах (обычно это 32-битные платформы) где имеются *64 и *32 вызовы, другие версии устарели.

- Вызовы rt_sig* добавлены в ядро 2.2 для поддержки дополнительных сигналов реального времени (см. signal(7)). Эти системные вызовы упраздняют старые системные вызовы с теми же именами, но без префикса "rt_".

- В системных вызовах select(2) и mmap(2) используется пять или более аргументов, что вызывало проблемы определения способа передачи аргументов на i386(). В следствии этого, тогда как на других архитектурах вызовы sys_select() и sys_mmap() соответствуют __NR_select и __NR_mmap, на i386 они соответствуют old_select() и old_mmap() (процедуры, использующие указатель на блок аргументов). В настоящее время больше нет проблемы с передачей более пяти аргументов и есть __NR__newselect, который соответствует именно sys_select() и тоже самое с __NR_mmap2. На s390x только 64-битная архитектура имеет old_mmap.

### Специфика некоторых архитектур: Alpha

- Вызов getxgid(2) возвращает пару GID и эффективный GID через регистры r0 и r20; он предоставляется как замена getgid(2) и getegid(2).

- Вызов getxpid(2) возвращает пару PID и эффективный PID через регистры r0 и r20; он предоставляется как замена getpid(2) и getppid(2).

- Вызов old_adjtimex(2) является вариантом adjtimex(2), в котором используется struct timeval32 (для совместимости с OSF/1).

- Вызов getxuid(2) возвращает пару GID и эффективный GID через регистры r0 и r20; он предоставляется как замена getuid(2) и geteuid(2).

- Вызов sethae(2) используется для настройки регистра Host Address Extension в бюджетных Alpha, чтобы получить доступ к адресному пространству за границу первых 27 бит.

## СМОТРИТЕ ТАКЖЕ
intro(2), syscall(2), unimplemented(2), errno(3), libc(7), vdso(7)


sysctl

title: sysctl(2)

summary: читает/записывает параметры системы

text:
# sysctl(2)

## ИМЯ
sysctl - читает/записывает параметры системы

## ОБЗОР

```
#include <unistd.h>
#include <linux/sysctl.h>
```

```
int _sysctl(struct __sysctl_args *args);
```

Замечание: В glibc нет обёрточной функции для данного системного вызова; смотрите ЗАМЕЧАНИЯ.

## ОПИСАНИЕ
Не используйте этот системный вызов! Смотрите ЗАМЕЧАНИЯ.

Системный вызов _sysctl считывает и/или изменяет параметры ядра. К ним относятся, например, имя машины или максимальное количество открытых файлов. Параметр имеет следующую структуру:

```
struct __sysctl_args {

    int    *name;    /* целочисленный вектор, описывающий

                        переменную */

    int     nlen;    /* длина этого вектора */

    void   *oldval;  /* 0 или адрес старого значения */

    size_t *oldlenp; /* размер старого значения, заменяется

                        реальным размером старого значения */

    void   *newval;  /* 0 или адрес нового значения */

    size_t  newlen;  /* размер нового значения */
};
```

Этот вызов производит поиск в древовидной структуре, возможно, похожей на структуру каталогов /proc/sys, и, если запрашиваемый элемент найден, вызывает соответствующую процедуру, читающую или изменяющую значение.

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении _sysctl() возвращает 0. При ошибке возвращается -1, а переменной errno присваивается номер ошибки.

## ОШИБКИ
EACCES, EPERM

Нет прав на поиск в одном из встретившихся «каталогов» или нет прав на чтение, если oldval не равно нулю; или нет прав на запись, если newval не равно нулю.

EFAULT

Был сделан запрос предыдущего значения путём установки не-NULL значения oldval, но размер места под него в oldlenp равен нулю.

ENOTDIR

name не найден.

## СООТВЕТСТВИЕ СТАНДАРТАМ
Этот вызов есть только в Linux и не должен использоваться в переносимых программах. Вызов sysctl() впервые появился в Linux 1.3.57. Впервые он появился в 4.4BSD. Только в Linux существует зеркало /proc/sys, и схемы именования объектов в Linux и 4.4BSD различаются, но объявление функции sysctl() одинаково в обеих системах.

## ЗАМЕЧАНИЯ
В glibc отсутствует обёрточная функция для этого системного вызова; вызывайте его через syscall(2). Или лучше совсем не используйте: использование данного системного вызова уже давно не рекомендуется и он так всем не нравится, что, вероятно, исчезнет в новой версии ядра. Начиная с Linux 2.6.24, при использовании данного системного вызова записывается предупреждение в журнал ядра. Удалите вызов из своих программ прямо сейчас; вместо него используйте интерфейс /proc/sys.

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

## ДЕФЕКТЫ
Названия объектов различаются в разных версиях ядра, что делает данный вызов в приложениях бесполезным.

Не все существующие объекты описаны соответствующим образом.

В настоящее время невозможно изменить тип операционной системы путём записи в файл /proc/sys/kernel/ostype.

## ПРИМЕР

```
#define _GNU_SOURCE
#include <unistd.h>
#include <sys/syscall.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <linux/sysctl.h>
int _sysctl(struct __sysctl_args *args );
#define OSNAMESZ 100
int
main(void)
{

    struct __sysctl_args args;

    char osname[OSNAMESZ];

    size_t osnamelth;

    int name[] = { CTL_KERN, KERN_OSTYPE };

    memset(&args, 0, sizeof(struct __sysctl_args));

    args.name = name;

    args.nlen = sizeof(name)/sizeof(name[0]);

    args.oldval = osname;

    args.oldlenp = &osnamelth;

    osnamelth = sizeof(osname);

    if (syscall(SYS__sysctl, &args) == -1) {

        perror("_sysctl");

        exit(EXIT_FAILURE);

    }

    printf("Эта машина работает в %*s\n", osnamelth, osname);

    exit(EXIT_SUCCESS);
}
```

## СМОТРИТЕ ТАКЖЕ
proc(5)


sysfs

title: sysfs(2)

text:
# sysfs(2)

## ИМЯ
sysfs - получает информацию о типах файловых систем

## ОБЗОР
int sysfs(int option, const char *fsname);

int sysfs(int option, unsigned int fs_index, char *buf);

int sysfs(int option);

## ОПИСАНИЕ
Замечание: информация о файловой системе sysfs, обычно монтируемой в /sys, приведена в sysfs(5).

Системный вызов (устаревший) sysfs() возвращает информацию о типах файловой системы, которые имеются в ядре. Форма вызова sysfs() и возвращаемая информация зависят от параметра option согласно следующей таблице:

1

Преобразовать строку с идентификатором типа файловой системы fsname в индекс типа файловой системы.

2

Преобразовать индекс типа файловой системы fs_index в строку (оканчивающуюся null) с идентификатором типа файловой системы. Эта строка будет записана в буфер buf. Убедитесь в том, что в buf есть достаточно места для размещения этой строки.

3

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

Нумерация индексов типов файловой системы начинается с нуля.

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении sysfs() возвращает индекс типа файловой системы при значении option равном 1, ноль, если значение option равно 2 и количество существующих в данный момент типов файловых систем в ядре при option, равном 3. При ошибке возвращается -1, а переменная errno устанавливается соответствующим образом.

## ОШИБКИ
EFAULT

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

EINVAL

fsname не является правильным идентификатором типа файловой системы; превышены пределы fs_index; неправильный параметр option.

## СООТВЕТСТВИЕ СТАНДАРТАМ
SVr4.

## ЗАМЕЧАНИЯ
Данный вызов, унаследованный от System-V, устарел; не используйте его. В системах с /proc такую же информацию можно получить из /proc/filesystems; используйте данную возможность вместо этого вызова.

## ДЕФЕКТЫ
Нет поддержки в libc и glibc. Нет способа определить необходимый размер буфера buf.


sysinfo

title: sysinfo(2)

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

text:
# sysinfo(2)

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

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

int sysinfo(struct sysinfo *info);

## ОПИСАНИЕ
Вызов sysinfo() возвращает некоторую статистику использования памяти и области подкачки, а также среднюю загруженность.

До Linux 2.3.16 вызов sysinfo() возвращал следующую структуру:

```
struct sysinfo {

    long uptime;             /* Количество секунд, прошедшее

                                с загрузки системы */

    unsigned long loads[3];  /* средняя 1, 5 и 15-минутная загруженность

                                системы */

    unsigned long totalram;  /* Общий объём доступной оперативной памяти */

    unsigned long freeram;   /* Объём свободной памяти */

    unsigned long sharedram; /* Объём общей памяти */

    unsigned long bufferram; /* Объём памяти, использованной под буферы */

    unsigned long totalswap; /* Общий объём области подкачки */

    unsigned long freeswap;  /* Объём свободного пространства в области

                                подкачки */

    unsigned short procs;    /* Текущее количество процессов */

    char _f[22];             /* Дополнение структуры до 64 байтов */
};
```

В приведённой выше структуре размеры полей памяти и подкачки приводятся в байтах.

Начиная с Linux 2.3.23 (i386) и Linux 2.3.48 (остальные архитектуры), структура следующая:

```
struct sysinfo {

    long uptime;             /* Количество секунд, прошедшее с загрузки

                                системы */

    unsigned long loads[3];  /* средняя 1,  и 15-минутная загруженность

                                системы */

    unsigned long totalram;  /* Общий объём доступной оперативной памяти */

    unsigned long freeram;   /* Объём свободной памяти */

    unsigned long sharedram; /* Объём общей памяти */

    unsigned long bufferram; /* Объём памяти, использованной под буферы */

    unsigned long totalswap; /* Общий объём области подкачки */

    unsigned long freeswap;  /* Объём свободного пространства в области

                                подкачки */

    unsigned short procs;    /* Текущее количество процессов */

    unsigned long totalhigh; /* Общий объём дальней (high) памяти */

    unsigned long freehigh;  /* Объём свободной дальней памяти */

    unsigned int mem_unit;   /* Размер элемента памяти в байтах */

    char _f[20-2*sizeof(long)-sizeof(int)];

                             /* Дополнение до 64 байт */
};
```

В приведённой выше структуре размеры полей памяти и подкачки приводятся умноженными на mem_unit байт.

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении sysinfo() возвращается ноль. При ошибке возвращается -1, а в errno содержится код ошибки.

## ОШИБКИ
EFAULT

Аргумент info не содержит допустимого адреса.

## ВЕРСИИ
Вызов sysinfo() впервые появился в Linux 0.98.pl6.

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

## ЗАМЕЧАНИЯ
Вся информация, предоставляемая этим системным вызовом также доступна через /proc/meminfo и /proc/loadavg.

## СМОТРИТЕ ТАКЖЕ
proc(5)


syslog

title: syslog(2)

text:
# syslog(2)

## ИМЯ
syslog, klogctl - читает и/или очищает кольцевой буфер сообщений ядра; устанавливает console_loglevel

## ОБЗОР

```
int syslog(int type, char *bufp, int len);
/* не имеет обёртки в glibc */
```

```
/* интерфейс glibc */
#include <sys/klog.h>
```

```
int klogctl(int type, char *bufp, int len);
```

## ОПИСАНИЕ
Замечание: Вероятно, вы ищете библиотечную функцию Си syslog(), которая описана в syslogd(8); подробности смотрите в syslog(3).

В этой странице описана системный вызов ядра syslog(), который используется для управления буфером printk() в ядре; обёрточная функция glibc для данного системного вызова называется klogctl().

### Буфер журнала ядра
В ядре существует кольцевой буфер длиной LOG_BUF_LEN, в котором хранятся сообщения, переданные через аргументы функции ядра printk() (независимо от их уровня). В ранних версиях ядра значение LOG_BUF_LEN было равно 4096, начиная с ядра 1.3.54 оно стало 8192, а начиная с 2.1.113 — 16384. Начиная с версии 2.4.23/2.6 его значение задаётся в параметрах настройки ядра (CONFIG_LOG_BUF_SHIFT, значение по умолчанию зависит от архитектуры). Начиная с Linux 2.6.6, размер можно узнать по команде 10 (смотрите далее).

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

SYSLOG_ACTION_CLOSE (0)

Закрыть журнал. Ничего не делает.

SYSLOG_ACTION_OPEN (1)

Открыть журнал. Ничего не делает.

SYSLOG_ACTION_READ (2)

Читать из журнала. Вызов ждёт пока в буфере журнала ядра что-нибудь не появится и затем записывает максимум len байт в буфер, указанный bufp. Вызов возвращает количество прочитанных байт. Байты, прочитанные из журнала, исчезают из буфера журнала: информацию можно прочесть только один раз. Эта функция используется ядром когда пользовательская программа читает файл /proc/kmsg.

SYSLOG_ACTION_READ_ALL (3)

Читать все сообщения, оставшиеся в кольцевом буфере, помещая их в буфер, указанный в bufp. Вызов читает последние len байт из буфера журнала (не разрушая его), но не больше, чем было записано в буфер с момента вызова команды «очистка кольцевого буфера» (смотрите команду 5 далее). Вызов возвращает количество прочитанных байт.

SYSLOG_ACTION_READ_CLEAR (4)

Прочитать и стереть все сообщения, оставшиеся в кольцевом буфере. Вызов выполняет то же самое, что и при type равном 3, но ещё вызывает команду «очистка кольцевого буфера».

SYSLOG_ACTION_CLEAR (5)

Вызов просто исполняет команду «очистка кольцевого буфера». Аргументы bufp и len игнорируются.

Эта команда на самом деле не очищает кольцевой буфер. Вместо этого она изменяет переменную учёта в ядре, которая определяет результат, возвращаемый командами 3 (SYSLOG_ACTION_READ_ALL) и 4 (SYSLOG_ACTION_READ_CLEAR). Эта команда не влияет на команды 2 (SYSLOG_ACTION_READ) и 9 (SYSLOG_ACTION_SIZE_UNREAD).

SYSLOG_ACTION_CONSOLE_OFF (6)

Данная команда сохраняет текущее значение console_loglevel и затем устанавливает console_loglevel равным minimum_console_loglevel, что приводит к отключению вывода сообщений на консоль. До Linux 2.6.32, эта команда просто изменяла console_loglevel на minimum_console_loglevel. Смотрите описание /proc/sys/kernel/printk далее.

Аргументы bufp и len игнорируются.

SYSLOG_ACTION_CONSOLE_ON (7)

Если ранее выполнялась команда SYSLOG_ACTION_CONSOLE_OFF, то эта команда восстанавливает значение console_loglevel, которое было сохранено. До Linux 2.6.32 эта команда просто изменяла console_loglevel на default_console_loglevel. Смотрите описание /proc/sys/kernel/printk ниже.

Аргументы bufp и len игнорируются.

SYSLOG_ACTION_CONSOLE_LEVEL (8)

Вызов присваивает console_loglevel значение, указанное в len, которое должно быть целым числом от 1 до 8 (включительно). Ядро неявно изменяет минимальное значение minimum_console_loglevel на len. Подробности смотрите в разделе Уровень протоколирования. Аргумент bufp игнорируется.

SYSLOG_ACTION_SIZE_UNREAD (9) (начиная с Linux 2.4.10)

Вызов возвращает количество байт, доступных для чтения из буфера журнала ядра командой 2 (SYSLOG_ACTION_READ). Аргументы bufp и len игнорируются.

SYSLOG_ACTION_SIZE_BUFFER (10) (начиная с Linux 2.6.6)

Эта команда возвращает полный размер буфера журнала ядра. Аргументы bufp и len игнорируются.

Все команды кроме 3 и 10 требуют привилегий. В ядрах Linux до версии 2.6.37, команды 3 и 10 были доступны непривилегированным процессам; начиная с Linux 2.6.37, эти команды разрешены из непривилегированных процессов только, если значение /proc/sys/kernel/dmesg_restrict равно 0. До Linux 2.6.37 под «привилегиями» понималось, что вызывающий имеет мандат CAP_SYS_ADMIN. Начиная с Linux 2.6.37 «привилегией» считается, что вызывающий имеет либо мандат CAP_SYS_ADMIN (теперь устарел для такого использования), либо (новый) мандат CAP_SYSLOG.

### /proc/sys/kernel/printk
Файл /proc/sys/kernel/printk доступен на запись и содержит 4 целочисленных значения, которыми управляется поведение ядерного printk() при печати или протоколировании сообщений об ошибках. Четыре значения:

console_loglevel

На консоль выводятся только сообщения, у которых уровень протоколирования меньше этого значения. По умолчанию значение этой переменной равно DEFAULT_CONSOLE_LOGLEVEL (7), но это значение будет равно 4, если командная строка ядра содержит слово «quiet»; 10 — если командная строка ядра содержит слово «debug», и 15 — в случае ошибки ядра (10 и 15 не имеют большого смысла и аналогичны ). Значение (из диапазона от 1 до 8) console_loglevel устанавливается вызовом syslog() с type равным 8.

default_message_loglevel

Это значение будет использовано как уровень протоколирования сообщений printk(), у которых уровень не указан. До версии Linux 2.6.38 включительно это поле содержало неизменяемое значение 4 (KERN_WARNING); начиная с Linux 2.6.39, значение по умолчанию задаётся в параметре настройки ядра CONFIG_DEFAULT_MESSAGE_LOGLEVEL и по умолчанию равно 4.

minimum_console_loglevel

Значение этого поля — минимальное значение, которое может быть указано в console_loglevel.

default_console_loglevel

Это значение по умолчанию для console_loglevel.

### Уровень протоколирования
Каждое сообщение printk() имеет свой уровень протоколирования. Если уровень протоколирования явно не задан в сообщении, то по умолчанию оно равно default_message_loglevel. Для удобства имеются следующие уровни протоколирования:

Ядерные постоянные

Уровень

Смысл

KERN_EMERG

0

Система не пригодна к использованию

KERN_ALERT

1

Необходимо немедленно принять меры

KERN_CRIT

2

Условная паника

KERN_ERR

3

Условные ошибки

KERN_WARNING

4

Условные предупреждения

KERN_NOTICE

5

Обычное, но важное условие

KERN_INFO

6

Информационное сообщение

KERN_DEBUG

7

Cообщения уровня отладки

Ядерная процедура printk() печатает сообщение на консоль только, если его уровень протоколирования меньше значения console_loglevel.

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении и если type равно 2, 3 или 4, syslog() возвращает количество прочитанных байт. При type равном 9, syslog() возвращает количество байт, доступных для чтения из кольцевого буфера ядра. При type равном 10, syslog() возвращает полный размер кольцевого буфера ядра. При других значениях type и успешном выполнении возвращается 0.

При ошибке возвращается -1, а переменной errno присваивается номер ошибки.

## ОШИБКИ
EINVAL

Неправильные значения параметров (например, некорректное значение type; при type равном 2, 3, 4, значение buf равно NULL или значение len меньше нуля; при type равном 8, значение level лежит вне диапазона от 1 до 8).

ENOSYS

Системный вызов syslog() недоступен, так как ядро было собрано с отключённым параметром CONFIG_PRINTK.

EPERM

Процесс, не имеющий необходимых прав (мандата CAP_SYS_ADMIN или CAP_SYSLOG), пытался изменить console_loglevel или очистить кольцевой буфер сообщений ядра.

ERESTARTSYS

Системный вызов был прерван сигналом; ничего не было прочитано (может быть замечено только при трассировке).

## СООТВЕТСТВИЕ СТАНДАРТАМ
Данный системный вызов существует только в Linux и не должен использоваться переносимых программах.

## ЗАМЕЧАНИЯ
С самого начала многим не нравится, что вызов ядра и библиотечная функция с одинаковыми именами делают совершенно разные вещи.

## СМОТРИТЕ ТАКЖЕ
dmesg(1), syslog(3), capabilities(7)


tee

title: tee(2)

summary: повторяет содержимое канала

text:
# tee(2)

## ИМЯ
tee - повторяет содержимое канала

## ОБЗОР

```
#define _GNU_SOURCE         /* см. feature_test_macros(7) */
#include <fcntl.h>
```

```
ssize_t tee(int fd_in, int fd_out, size_t len, unsigned int flags);
```

## ОПИСАНИЕ
Вызов tee() повторяет до len байт данных из канала, на который указывает файловый дескриптор fd_in в канал, на который указывает файловый дескриптор fd_out. Он не потребляет данные, копируемые из fd_in, поэтому эти данные можно копировать последующим вызовом splice(2).

Аргумент flags представляет собой битовую маску, которая составляется логическим сложением (OR) следующих значений:

SPLICE_F_MOVE

В данный момент никак не влияет при указании в tee(); см. splice(2).

SPLICE_F_NONBLOCK

Не блокировать ввод-вывод; подробности в splice(2).

SPLICE_F_MORE

В данный момент никак не влияет при указании в tee(), но это может измениться; см. splice(2).

SPLICE_F_GIFT

Не используется для tee(); см. vmsplice(2).

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении, tee() возвращает количество байт, которые были повторены из ввода в выводе. Возвращаемое значение 0 означает, что нет данных для передачи, и блокировка не имеет смысла, так как нет процессов-писателей, подключённых к каналу для записи, на который указывает fd_in.

В случае ошибки tee() возвращает -1, а errno устанавливается в соответствующее значение.

## ОШИБКИ
EAGAIN

В flags указан SPLICE_F_NONBLOCK или один из файловых дескрипторов был помечен как неблокирующий (O_NONBLOCK), и операция вызвала бы блокировку.

EINVAL

Значение fd_in или fd_out не указывает на канал; fd_in и fd_out указывают на один и тот же канал.

ENOMEM

Не хватает памяти.

## ВЕРСИИ
Системный вызов tee() впервые появился в Linux 2.6.17; поддержка в glibc добавлена в версии 2.5.

## СООТВЕТСТВИЕ СТАНДАРТАМ
Данный вызов есть только в Linux.

## ЗАМЕЧАНИЯ
Концептуально, tee() копирует данные между двумя каналами. В реальности, данные не копируются на самом деле: внутри, tee() назначает данные на вывод просто схватывая ссылку из ввода.

## ПРИМЕР
В примере далее показана простая реализация программы tee(1) с помощью системного вызова tee(). Пример использования:

```
$ date |./a.out out.log | cat
Tue Oct 28 10:06:00 CET 2014
$ cat out.log
Tue Oct 28 10:06:00 CET 2014
```

### Исходный код программы

```
#define _GNU_SOURCE
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <limits.h>
int
main(int argc, char *argv[])
{

    int fd;

    int len, slen;

    if (argc != 2) {

        fprintf(stderr, "Использование: %s <файл>\n", argv[0]);

        exit(EXIT_FAILURE);

    }

    fd = open(argv[1], O_WRONLY | O_CREAT | O_TRUNC, 0644);

    if (fd == -1) {

        perror("open");

        exit(EXIT_FAILURE);

    }

    do {

        /*

         * перекладывать из stdin в stdout.

         */

        len = tee(STDIN_FILENO, STDOUT_FILENO,

                  INT_MAX, SPLICE_F_NONBLOCK);

        if (len < 0) {

            if (errno == EAGAIN)

                continue;

            perror("tee");

            exit(EXIT_FAILURE);

        } else

            if (len == 0)

                break;

        /*

         * Поглотить stdin, объединяя данные в файле.

         */

        while (len > 0) {

            slen = splice(STDIN_FILENO, NULL, fd, NULL,

                          len, SPLICE_F_MOVE);

            if (slen < 0) {

                perror("splice");

                break;

            }

            len -= slen;

        }

    } while (1);

    close(fd);

    exit(EXIT_SUCCESS);
}
```

## СМОТРИТЕ ТАКЖЕ
splice(2), vmsplice(2), pipe(7)


time

title: time(2)

summary: получить время в секундах

text:
# time(2)

## ИМЯ
time - получить время в секундах

## ОБЗОР
\#include <time.h>

time_t time(time_t *tloc);

## ОПИСАНИЕ
time() возвращает количество секунд, которое прошло с начала эпохи, 1970-01-01 00:00:00 +0000 (UTC).

Если tloc не равно NULL, то возвращаемое значение также сохраняется в область памяти, на которую указывает tloc.

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении возвращается время в секундах, прошедшее с начала эпохи. При ошибке возвращается ((time_t) -1), а errno устанавливается должным образом.

## ОШИБКИ
EFAULT

tloc указывает за пределы доступного адресного пространства (однако см. ОШИБКИ).

В системах, где обёрточная функция time() библиотеки C вызывает реализацию, предоставляемую vdso(7) (то есть нет ловушки в ядре), из-за некорректного адреса может генерироваться сигнал SIGSEGV.

## СООТВЕТСТВИЕ СТАНДАРТАМ
SVr4, 4.3BSD, C89, C99, POSIX.1-2001. В POSIX не определены условия возникновения ошибок.

## ЗАМЕЧАНИЯ
В POSIX.1 для определения секунд, прошедших с начала эпохи используется формула для приблизительного подсчёта количества секунд между указываемым временем и началом эпохи. Эта формула учитывает тот факт, что все годы, номер которых делится на 4, считаются високосными, но годы, которые делятся на 100 не високосные, если они также не делятся на 400 (которые нужно считать високосными). Это значение не является указанием на точное количество секунд между заданным временем и началом эпохи вследствие игнорирования високосных секунд и по причине того, что время в часах необязательно синхронизировано со временем стандартного источника. Считается, что это значение соответствует настоящему количеству секунд, прошедшему с начала эпохи. Дополнительную информацию можно найти в POSIX.1-2008 Rationale A.4.15.

В Linux, вызов time() со значением tloc равным NULL, не может завершиться ошибкой EOVERFLOW, даже с ABI, у которого time_t — знаковое 32-битное целое и количество тактов часов выходит за пределами времени 2**31 (2038-01-19 03:14:08 UTC, високосные секунды игнорируются) (в POSIX.1 допускается, но не требуется возврат ошибки EOVERFLOW в случае, когда количество секунд с начала эпохи не влезает в time_t). Вместо этого, поведение в Linux является не определённым, когда системное время выходит за границы диапазона time_t. Приложения, которые должны работать после 2038 года, должны использовать ABI, в котором тип time_t больше 32 бит.

## ДЕФЕКТЫ
Ошибка, возвращаемая из этого системного вызова неотличима от успешного выполнения в случае, когда момент времени — за несколько секунд до эпохи, поэтому обёрточная функция библиотеки C никогда не изменяет errno при возврате.

Аргумент tloc устарел и в новом коде всегда должен быть равен NULL. Если tloc равно NULL, то вызов не может завершиться ошибкой.

### Отличия между библиотекой C и ядром
На некоторых архитектурах реализация time() находится в vdso(7).

## СМОТРИТЕ ТАКЖЕ
date(1), gettimeofday(2), ctime(3), ftime(3), time(7), vdso(7)


title: timer_create(2)

text:
# timer_create(2)

## ИМЯ
timer_create - создаёт таймер POSIX для определённого процесса

## ОБЗОР

```
#include <signal.h>
#include <time.h>
```

```
int timer_create(clockid_t clockid, struct sigevent *sevp,
                 timer_t *timerid);
```

Компонуется при указании параметра -lrt.

Требования макроса тестирования свойств для glibc (см. feature_test_macros(7)):

timer_create(): _POSIX_C_SOURCE >= 199309L

## ОПИСАНИЕ
Вызов timer_create() создаёт новый таймер для процесса. Идентификатор нового таймера возвращается в буфере, указанном в timerid, его значение не должно быть равно null. Данный идентификатор уникален для процесса, пока таймер не будет удалён. Новый таймер создаётся неактивным.

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

CLOCK_REALTIME

Настраиваемые системные часы реального времени.

CLOCK_MONOTONIC

Ненастраиваемые, постоянно идущие вперёд часы, отсчитывающие время с некоторой неопределённой точки в прошлом, которая не изменяется с момент запуска системы.

CLOCK_PROCESS_CPUTIME_ID (начиная с Linux 2.6.12)

Часы, измеряющие время ЦП (пользовательское и системное), затраченное вызывающим процессом (всеми его нитями).

CLOCK_THREAD_CPUTIME_ID (начиная с Linux 2.6.12)

Часы, измеряющие время ЦП (пользовательское и системное), затраченное вызывающей нитью.

CLOCK_BOOTTIME (начиная с Linux 2.6.39)

Подобно CLOCK_MONOTONIC, представляет монотонно растущие часы. Однако, если часы CLOCK_MONOTONIC не отсчитывают время когда система находится в состоянии ожидания (suspended), а часы CLOCK_BOOTTIME учитывают время в таком состоянии системы. Это полезно приложениям, которым необходимо учитывать состояние ожидания. CLOCK_REALTIME не подходят для таких приложений, так как эти часы подвержены скачкообразным изменениям системных часов.

CLOCK_REALTIME_ALARM (начиная с Linux 3.0)

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

CLOCK_BOOTTIME_ALARM (начиная с Linux 3.0)

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

Помимо значений, перечисленных ранее, в clockid может быть указано clockid, возвращённое вызовом clock_getcpuclockid(3) или pthread_getcpuclockid(3).

Аргумент sevp указывает на структуру sigevent, которая задаёт способ уведомления вызывающего при срабатывании таймера. Определение и описание структуры смотрите в sigevent(7).

В поле sevp.sigev_notify можно указать следующие значения:

SIGEV_NONE

Выполнять синхронное уведомление при срабатывании таймера. Ход таймера можно отслеживать с помощью timer_gettime(2).

SIGEV_SIGNAL

При срабатывании таймера генерировать для процесса сигнал sigev_signo. Подробности смотрите в sigevent(7). Полю si_code структуры siginfo_t присваивается значение SI_TIMER. В любой момент времени для таймера в очередь процесса ставится не более одного сигнала; подробности смотрите в timer_getoverrun(2).

SIGEV_THREAD

При срабатывании вызвать sigev_notify_function, как если бы это была начальная функция новой нити. Подробности смотрите в sigevent(7).

SIGEV_THREAD_ID (есть только в Linux)

Как для SIGEV_SIGNAL, но сигнал нацелен на нить, чей ID указывается в sigev_notify_thread_id, который должен быть нитью того же процесса что и вызывающий. В поле sigev_notify_thread_id указывается ID ядерной нити, то есть значение, возвращаемое clone(2) или gettid(2). Этот флаг предназначен только для использования в библиотеках нитей.

Указание в sevp значения NULL эквивалентно указанию указателя на структуру sigevent, в которой sigev_notify равно SIGEV_SIGNAL, sigev_signo равно SIGALRM и sigev_value.sival_int равно ID таймера.

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении timer_create() возвращается 0 и ID нового таймера помещается в *timerid. При ошибке возвращается -1, а errno устанавливается в соответствующее значение.

## ОШИБКИ
EAGAIN

Временная ошибка, на время выделения ядром структур таймера.

EINVAL

Некорректный ID часов, sigev_notify, sigev_signo или sigev_notify_thread_id.

ENOMEM

Невозможно выделить память.

## ВЕРСИИ
Данный системный вызов появился в Linux 2.6.

## СООТВЕТСТВИЕ СТАНДАРТАМ
POSIX.1-2001, POSIX.1-2008.

## ЗАМЕЧАНИЯ
С помощью timer_create() программа может создавать несколько интервальных таймеров.

Таймеры не наследуются в потомке после fork(2), и выключаются и удаляются при execve(2).

Ядро заранее выделяет «сигнал реального времени в очереди» для каждого таймера, создаваемого timer_create(). В результате, количество таймеров ограничено ресурсом RLIMIT_SIGPENDING (смотрите setrlimit(2)).

Таймеры, созданные timer_create(), часто называют «(интервальными) таймерами POSIX». Программный интерфейс таймеров POSIX состоит из следующих интерфейсов:

- timer_create(): Создаёт таймер.

- timer_settime(2): Включает (запускает) или выключает (останавливает) таймер.

- timer_gettime(2): Возвращает время, оставшееся до следующего срабатывания таймера вместе с интервалом, заданным в таймере.

- timer_getoverrun(2): Возвращает счётчик переполнения после последнего срабатывания таймера.

- timer_delete(2): Выключает и удаляет таймер.

Начиная с Linux 3.10, файл /proc/[pid]/timers можно использовать для просмотра списка таймеров POSIX для процесса с PID равным pid. Подробности смотрите в proc(5).

Начиная с Linux 4.10, поддержка таймеров POSIX теперь необязательна и включена по умолчанию. Поддержку в ядре можно выключить через параметр CONFIG_POSIX_TIMERS.

### Отличия между библиотекой C и ядром
Частично, реализация программного интерфейса таймеров POSIX предоставляется glibc. А именно:

- Большая часть функций для SIGEV_THREAD реализована в glibc, а не в ядре (это необходимо, так как в обработку уведомления вовлечена нить, которая должна управляться библиотекой C, реализующей нити POSIX). Хотя уведомление доставляется процессу через нить, внутри реализации NPTL для SIGEV_THREAD_ID используется значение sigev_notify и сигнал реального времени, который зарезервирован для реализации (смотрите nptl(7)).

- Стандартная ситуация, когда evp равно NULL, обрабатывается в glibc, где вызывается нижележащий системный вызов с заполненной подходящим образом структурой sigevent.

- Идентификаторы таймеров, обрабатываемые на уровне пользователя, поддерживаются glibc, которая отображает эти ID в ID таймеров, созданных ядром.

Системные таймерные вызовы POSIX впервые появились в Linux 2.6. До этого в glibc была неполная реализация в пространстве пользователя (только таймеры CLOCK_REALTIME) с использованием нитей POSIX, а реализация glibc до версии 2.17 переключается на неё в системах с ядрами до Linux 2.6.

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

В следующем примере программа спит 1 секунду после создания таймера, который работает с частотой 100 наносекунд. За время разблокировки и доставки сигнала, произошло около 10 миллионов переполнений.

```
./$ ./a.out 1 100
Устанавливается обработчик сигнала 34
Блокируется сигнал 34
ID таймера — 0x804c008
Спим 1 секунду
Разблокируется сигнал 34
Пойман сигнал 34

    sival_ptr = 0xbfb174f4;     *sival_ptr = 0x804c008

    счётчик переполнения = 10004886
```

### Исходный код программы

```
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <time.h>
#define CLOCKID CLOCK_REALTIME
#define SIG SIGRTMIN
#define errExit(msg)    do { perror(msg); exit(EXIT_FAILURE); \

                        } while (0)
static void
print_siginfo(siginfo_t *si)
{

    timer_t *tidp;

    int or;

    tidp = si->si_value.sival_ptr;

    printf("    sival_ptr = %p; ", si->si_value.sival_ptr);

    printf("    *sival_ptr = 0x%lx\n", (long) *tidp);

    or = timer_getoverrun(*tidp);

    if (or == -1)

        errExit("timer_getoverrun");

    else

        printf("    счётчик переполнения = %d\n", or);
}
static void
handler(int sig, siginfo_t *si, void *uc)
{

    /* Замечание: вызов printf() из обработчика сигнала небезопасен

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

       printf() не async-signal-safe; смотрите signal-safety(7).

       Тем не менее, здесь мы используем printf(), так как это простой

       способ показать когда вызывается обработчик. */

    printf("Пойман сигнал %d\n", sig);

    print_siginfo(si);

    signal(sig, SIG_IGN);
}
int
main(int argc, char *argv[])
{

    timer_t timerid;

    struct sigevent sev;

    struct itimerspec its;

    long long freq_nanosecs;

    sigset_t mask;

    struct sigaction sa;

    if (argc != 3) {

        fprintf(stderr, "Использование: %s <secs> <nsecs>\n",

                argv[0]);

        exit(EXIT_FAILURE);

    }

    /* Устанавливаем обработчик для сигнала таймера */

    printf("Устанавливается обработчик сигнала %d\n", SIG);

    sa.sa_flags = SA_SIGINFO;

    sa.sa_sigaction = handler;

    sigemptyset(&sa.sa_mask);

    if (sigaction(SIG, &sa, NULL) == -1)

        errExit("sigaction");

    /* Временно блокируем сигнал таймера */

    printf("Блокируется сигнал %d\n", SIG);

    sigemptyset(&mask);

    sigaddset(&mask, SIG);

    if (sigprocmask(SIG_SETMASK, &mask, NULL) == -1)

        errExit("sigprocmask");

    /* Создаём таймер */

    sev.sigev_notify = SIGEV_SIGNAL;

    sev.sigev_signo = SIG;

    sev.sigev_value.sival_ptr = &timerid;

    if (timer_create(CLOCKID, &sev, &timerid) == -1)

        errExit("timer_create");

    printf("ID таймера — 0x%lx\n", (long) timerid);

    /* Запускаем таймер */

    freq_nanosecs = atoll(argv[2]);

    its.it_value.tv_sec = freq_nanosecs / 1000000000;

    its.it_value.tv_nsec = freq_nanosecs % 1000000000;

    its.it_interval.tv_sec = its.it_value.tv_sec;

    its.it_interval.tv_nsec = its.it_value.tv_nsec;

    if (timer_settime(timerid, 0, &its, NULL) == -1)

         errExit("timer_settime");

    /* Ненадолго засыпаем; за это время, таймер может сработать

       несколько раз */

    printf("Спим %d секунду\n", atoi(argv[1]));

    sleep(atoi(argv[1]));

    /* Разблокируем сигнал таймера, чтобы доставлялись

       уведомления таймера */

    printf("Разблокируется сигнал %d\n", SIG);

    if (sigprocmask(SIG_UNBLOCK, &mask, NULL) == -1)

        errExit("sigprocmask");

    exit(EXIT_SUCCESS);
}
```

## СМОТРИТЕ ТАКЖЕ
clock_gettime(2), setitimer(2), timer_delete(2), timer_getoverrun(2), timer_settime(2), timerfd_create(2), clock_getcpuclockid(3), pthread_getcpuclockid(3), pthreads(7), sigevent(7), signal(7), time(7)


title: timer_delete(2)

text:
# timer_delete(2)

## ИМЯ
timer_delete - удаляет таймер POSIX определённого процесса

## ОБЗОР

```
#include <time.h>
```

```
int timer_delete(timer_t timerid);
```

Компонуется при указании параметра -lrt.

Требования макроса тестирования свойств для glibc (см. feature_test_macros(7)):

timer_delete(): _POSIX_C_SOURCE >= 199309L

## ОПИСАНИЕ
Вызов timer_delete() удаляет таймер, чей ID указан в timerid. Если таймер на момент этого вызовы был установлен, то он сбрасывается перед удалением. Как поступать с любым ожидающим сигналом, сгенерированным удалённым таймером, стандартами не определено.

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении timer_delete() возвращается 0. При ошибке возвращается -1, а errno устанавливается в соответствующее значение.

## ОШИБКИ
EINVAL

Значение timerid не является допустимым идентификатором таймера.

## ВЕРСИИ
Данный системный вызов появился в Linux 2.6.

## СООТВЕТСТВИЕ СТАНДАРТАМ
POSIX.1-2001, POSIX.1-2008.

## СМОТРИТЕ ТАКЖЕ
clock_gettime(2), timer_create(2), timer_getoverrun(2), timer_settime(2), time(7)


title: timer_getoverrun(2)

text:
# timer_getoverrun(2)

## ИМЯ
timer_getoverrun - возвращает счётчик переполнения таймера POSIX (для каждого процесса отдельно)

## ОБЗОР

```
#include <time.h>
```

```
int timer_getoverrun(timer_t timerid);
```

Компонуется при указании параметра -lrt.

Требования макроса тестирования свойств для glibc (см. feature_test_macros(7)):

timer_getoverrun(): _POSIX_C_SOURCE >= 199309L

## ОПИСАНИЕ
Вызов timer_getoverrun() возвращает «счётчик переполнения» (overrun count) таймера, заданного в timerid. Приложение может использовать счётчик переполнения для точного вычисления количества срабатываний (expirations) таймера, которые бы произошли за указанный временной интервал. Переполнения таймера могут происходить при получении уведомлений о срабатывании (expiration notifications) посредством сигналов (SIGEV_SIGNAL) и нитей (SIGEV_THREAD).

Если уведомление о срабатывании доставляется сигналом, то переполнение может происходить следующим образом. Независимо от того, используется ли для таймерных уведомлений сигнал реального времени или нет, система ставит в очередь не более одного сигнала на таймер (так определено в POSIX.1. В противном случае, если ставить в очередь один сигнал на каждое срабатывание таймера, то легко можно превысить разрешённый размер очереди сигналов в системы). Из-за задержек системного планировщика или временной блокировки сигнала может возникать задержка между генерацией уведомляющего сигнала и его доставкой (delivered) (например, в обработчик сигнала) или приёмом (accepted) (например, с помощью sigwaitinfo(2)). В этом промежутке могут произойти дополнительные срабатывания таймера. Переполнение счётчика таймера — это количество дополнительных срабатываний таймера, которые произошли между генерацией и доставкой или принятием сигнала.

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

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении timer_getoverrun() возвращается счётчик переполнений заданного таймера; он может быть равен 0, если если переполнений не было. При ошибке возвращается -1, а errno устанавливается в соответствующее значение кода ошибки.

## ОШИБКИ
EINVAL

Значение timerid не является допустимым идентификатором таймера.

## ВЕРСИИ
Данный системный вызов появился в Linux 2.6.

## СООТВЕТСТВИЕ СТАНДАРТАМ
POSIX.1-2001, POSIX.1-2008.

## ЗАМЕЧАНИЯ
Когда уведомления таймера доставляются посредством сигналов (SIGEV_SIGNAL), в Linux также возможно узнать значение счётчика переполнения из поля si_overrun структуры siginfo_t (смотрите sigaction(2)). Это позволяет приложению не делать лишнего системного вызова для получения счётчика, но это непереносимое расширение POSIX.1.

В POSIX.1 переполнение таймера обсуждается только в контексте уведомлений таймера с помощью сигналов.

## ДЕФЕКТЫ
В POSIX.1 указано, что если счётчик переполнения таймера больше или равен максимальному значению (задаётся реализацией) DELAYTIMER_MAX, то timer_getoverrun() должен возвращать DELAYTIMER_MAX. Однако в Linux это не реализовано: вместо этого, если значение переполнения таймера превышает максимальное значение целого, то счётчик начинает увеличиваться с начала.

## ПРИМЕР
Смотрите timer_create(2).

## СМОТРИТЕ ТАКЖЕ
clock_gettime(2), sigaction(2), signalfd(2), sigwaitinfo(2), timer_create(2), timer_delete(2), timer_settime(2), signal(7), time(7)


title: timer_settime(2)

summary: запускает/останавливает и возвращает

text:
# timer_settime(2)

## ИМЯ
timer_settime, timer_gettime - запускает/останавливает и возвращает состояние таймера POSIX некоторого процесса

## ОБЗОР

```
#include <time.h>
```

```
int timer_settime(timer_t timerid, int flags,
                  const struct itimerspec *new_value,
                  struct itimerspec *old_value);
int timer_gettime(timer_t timerid, struct itimerspec *curr_value);
```

Компонуется при указании параметра -lrt.

Требования макроса тестирования свойств для glibc (см. feature_test_macros(7)):

timer_settime(), timer_gettime(): _POSIX_C_SOURCE >= 199309L

## ОПИСАНИЕ
Вызов timer_settime() запускает или останавливает таймер, указанный в timerid. Аргумент new_value — это указатель на структуру itimerspec, которая определяет новое начальное значение и новый интервал таймера. Структура itimerspec определена следующим образом:

```
struct timespec {

    time_t tv_sec;                /* секунды */

    long   tv_nsec;               /* наносекунды */
};
struct itimerspec {

    struct timespec it_interval;  /* интервал таймера */

    struct timespec it_value;     /* первое срабатывание */
};
```

Каждая подструктура структуры itimerspec представляет собой структуру timespec, которая позволяет задавать значение времени в секундах и наносекундах. Эти значения времени отсчитываются по часам, которые были указаны при создании таймера с помощью timer_create(2).

Если new_value->it_value равно ненулевому значению (т. е., любое из подполей не равно нулю), то timer_settime() запускает таймер, устанавливая ему первое время срабатывания (если таймер уже запущен, то предыдущие параметры перезаписываются). Если new_value->it_value равно нулю (т. е., оба подполя равны нулю), то таймер выключается.

В поле new_value->it_interval указывается период таймера в секундах и наносекундах. Если это поле равно нулю, то каждый раз, когда таймер срабатывает, он перезапускается со значением, указанным в new_value->it_interval. Если new_value->it_interval равно нулю, то таймер срабатывает только один раз, согласно заданному в it_value времени.

По умолчанию, начальное время срабатывания, указанное в new_value->it_value, считается относительно текущего времени на часах таймера на момент вызова. Это можно изменить, указав TIMER_ABSTIME в flags; в этом случае new_value->it_value рассматривается как абсолютное значение по часам таймера; то есть таймер сработает, когда значение часов достигнет значения, указанного в new_value->it_value. Если указанное абсолютное время уже прошло, то таймер срабатывает немедленно и счётчик переполнения изменяется соответствующим образом (смотрите timer_getoverrun(2)).

Если значение часов CLOCK_REALTIME корректируется (adjusted) и указано абсолютное значение у включённого таймера с этими часами, то срабатывание таймера будет скорректировано соответствующим образом. Корректировка часов CLOCK_REALTIME не влияет на относительные таймеры, использующие эти часы.

Если значение old_value не равно NULL, то оно указывает на буфер, который используется для возврата предыдущего интервала таймера (в old_value->it_interval) и количества времени, которое осталось таймеру до срабатывания (в old_value->it_value).

Вызов timer_gettime() возвращает время до следующего срабатывания таймера timerid и интервал в буфер curr_value. Оставшееся время до следующего срабатывания возвращается в curr_value->it_value; это всегда относительное значение, независимо от того, указывался ли флаг TIMER_ABSTIME при включении таймера. Если значение curr_value->it_value равно нулю, то таймер в данный момент выключен. Интервал таймера возвращается в curr_value->it_interval. Если значение curr_value->it_interval равно нулю, то это «одноразовый» таймер.

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении timer_settime() и timer_gettime() возвращается 0. При ошибке возвращается -1, а в errno содержится код ошибки.

## ОШИБКИ
Эти функции могут завершиться со следующими ошибками:

EFAULT

Некорректный указатель new_value, old_value или curr_value.

EINVAL

Неверное значение timerid.

timer_settime() может завершиться со следующими ошибками:

EINVAL

Значение new_value.it_value отрицательно; или new_value.it_value.tv_nsec отрицательно или больше 999999999.

## ВЕРСИИ
Данные системные вызовы появились в Linux 2.6.

## СООТВЕТСТВИЕ СТАНДАРТАМ
POSIX.1-2001, POSIX.1-2008.

## ПРИМЕР
Смотрите timer_create(2).

## СМОТРИТЕ ТАКЖЕ
timer_create(2), timer_getoverrun(2), time(7)