title: pivot_root(2)

summary: изменяет корневую файловую систему

text:
# pivot_root(2)

## ИМЯ
pivot_root - изменяет корневую файловую систему

## ОБЗОР
int pivot_root(const char *new_root, const char *put_old);

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

## ОПИСАНИЕ
Вызов pivot_root() перемещает корневую систему вызывающего процесса в каталог put_old и делает каталог new_root новой корневой файловой системой у вызывающего процесса.

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

Вызов pivot_root() может изменить (или не изменить) текущий корневой и текущий рабочий каталоги во всех процессах или нитях, использующих старый корневой каталог. Вызывающий pivot_root() должен быть уверен в том, что процессы у которых корневой или текущий рабочий каталог равен старому корневому каталогу, работают нормально в каждом случае. Самый простой способ достичь этого — сменить их корневой и текущий рабочий каталог на new_root до вызова pivot_root().

Содержимое предыдущего абзаца, на самом деле, является не совсем определённым, потому что реализация pivot_root() может измениться в будущем. На момент написания этого документа pivot_root() изменяет корневой и текущий рабочий каталоги каждого процесса или нити на new_root, если они указывают на старый корневой каталог. Это необходимо для того, чтобы нити ядра не занимали старый корневой и текущий рабочий каталог, даже если они вообще не обращались к файловой системе. В будущем, возможно, будет создан механизм, заставляющий нити ядра отказаться от доступа к файловой системе, что позволит удалить этот довольно навязчивый механизм из pivot_root().

Заметим, что всё это относится и к вызывающему процессу: pivot_root() может изменить (а может и не изменить) его текущий рабочий каталог. По этой причине рекомендуется вызывать chdir("/") сразу после вызова pivot_root().

На значения new_root и put_old накладываются следующие ограничения:

- Они должны быть каталогами.

- Аргументы new_root и put_old не могут быть в одной файловой системе с текущим корневым каталогом.

- Аргумент put_old должен быть в дереве каталогов new_root, т.е., путём добавления ненулевого количества /.. в строке, на которую указывает put_old, можно получить каталог, равный new_root.

- К put_old не должны быть подмонтированы файловые системы.

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

Если текущий корневой каталог не является точкой монтирования (например, после chroot(2) или pivot_root(), см. ниже), то к put_old подключается не старый корневой каталог, а точка монтирования этой файловой системы.

Значение new_root должно быть точкой монтирования (если это не точка монтирования, то достаточно привязать монтирование new_root поверх самой себя).

Типа распространения new_root и его родительского монтирования не должно быть MS_SHARED; схожим образом, если put_old — существующая точка монтирования, то её тип распространения не должен быть MS_SHARED.

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

## ОШИБКИ
Вызов pivot_root() может возвращать (в errno) любые ошибки, которые возвращаются stat(2). Также он может вернуть:

EBUSY

Аргумент new_root или put_old находится в текущей корневой файловой системе, или какая-то файловая система уже смонтирована в put_old.

EINVAL

Значение new_root не является точкой монтирования.

EINVAL

Аргумент put_old не находится в дереве каталогов new_root.

EINVAL

Текущий корень расположен на файловой системе rootfs (начальная ramfs).

EINVAL

Точка монтирования new_root и её родительское монтирование имеет тип распространения MS_SHARED.

EINVAL

Значение put_old является точкой монтирования и имеет тип распространения MS_SHARED.

ENOTDIR

Аргумент new_root или put_old не является каталогом.

EPERM

Вызывающий процесс не имеет мандата CAP_SYS_ADMIN.

## ВЕРСИИ
Вызов pivot_root() появился в Linux 2.3.41.

## СООТВЕТСТВИЕ СТАНДАРТАМ
Вызов pivot_root() есть только в Linux и поэтому его использование не переносимо.

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

Для rootfs (начальная ramfs) нельзя вызвать pivot_root(). Рекомендуемым методом изменения корневой файловой системы в этом случае является удаление всего в rootfs, перемонтирование в rootfs нового корня, присоединение stdin/stdout/stderr к новой /dev/console и запуск нового init(1). Для этого существуют вспомогательные программы; смотрите switch_root(8).

## ДЕФЕКТЫ
Вызов pivot_root() не должен изменять корневой и рабочий каталоги других процессов в системе.

Некорректное использование pivot_root() может привести к непредсказуемым последствиям.

## СМОТРИТЕ ТАКЖЕ
chdir(2), chroot(2), mount(2), stat(2), initrd(4), pivot_root(8), switch_root(8)


package: man-pages-ru

title: pkey_alloc(2)

summary: выделяет или освобождает ключ защиты

text:
# pkey_alloc(2)

## ИМЯ
pkey_alloc, pkey_free - выделяет или освобождает ключ защиты

## ОБЗОР

```
#define _GNU_SOURCE             /* смотрите feature_test_macros(7) */
#include <sys/mman.h>
```

```
int pkey_alloc(unsigned int flags, unsigned int access_rights);
int pkey_free(int pkey);
```

## ОПИСАНИЕ
Вызов pkey_alloc() выделяет ключ защиты (pkey), который можно передавать в pkey_mprotect(2).

Аргумент flags вызова pkey_alloc() зарезервирован для использования в будущем и в настоящее время должен равняться 0.

Аргумент access_rights вызова pkey_alloc() может содержать ноль или более запретительных операций:

PKEY_DISABLE_ACCESS

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

PKEY_DISABLE_WRITE

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

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

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

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

## ОШИБКИ
EINVAL

Неверное значение pkey, flags или access_rights.

ENOSPC

(pkey_alloc()) Все ключи защиты, доступные текущему процессу уже распределены. Количество доступных ключей зависит от архитектуры и реализации и может быть меньшим из-за использования отдельных ключей самим ядром. В настоящее время на x86 для пользовательской программы доступно 15 ключей.

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

## ВЕРСИИ
Вызовы pkey_alloc() и pkey_free() были добавлены в Linux 4.9; поддержка в glibc доступна с версии 2.27.

## СООТВЕТСТВИЕ СТАНДАРТАМ
Системные вызовы pkey_alloc() и pkey_free() есть только в Linux.

## ЗАМЕЧАНИЯ
Вызов pkey_alloc() всегда безопасен в независимости от поддержки ключей операционной системой. Его можно использовать как механизм определения поддержки pkey; он всегда просто возвращает ошибку ENOSPC, если операционная система не поддерживает pkey.

Ядро гарантирует, что содержимое аппаратных регистров прав (PKRU) будет сохранено только для выделенных ключей защиты. Пока ключ не выделен (до первого вызова, возвращающего этот ключ pkey_alloc(), или после его освобождения с помощью pkey_free()), ядро может вносить произвольные изменения в части регистров прав, относящихся к этому ключу.

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

## СМОТРИТЕ ТАКЖЕ
pkey_mprotect(2), pkeys(7)

branch: sisyphus


poll

title: poll(2)

text:
# poll(2)

## ИМЯ
poll, ppoll - ожидает некоторое событие над файловым дескриптором

## ОБЗОР

```
#include <poll.h>
```

```
int poll(struct pollfd *fds, nfds_t nfds, int timeout);
#define _GNU_SOURCE         /* смотрите feature_test_macros(7) */
#include <signal.h>
#include <poll.h>
```

```
int ppoll(struct pollfd *fds, nfds_t nfds,
        const struct timespec *tmo_p, const sigset_t *sigmask);
```

## ОПИСАНИЕ
Вызов poll() выполняет сходную с select(2) задачу: он ждёт пока один дескриптор из набора файловых дескрипторов не станет готов выполнить операцию ввода-вывода.

Отслеживаемый набор файловых дескрипторов задаётся в аргументе fds, который представляет собой массив структур:

```
struct pollfd {

    int   fd;         /* файловый дескриптор */

    short events;     /* запрашиваемые события */

    short revents;    /* возвращённые события */
};
```

Вызывающий должен указать количество элементов в массиве fds в аргументе nfds.

В поле fd содержится файловый дескриптор открытого файла. Если значение поля отрицательно, то соответствующее поле events игнорируется, а полю revents возвращает ноль (простой способ игнорирования файлового дескриптора в одиночном вызове poll(): просто сделать значение поля fd отрицательным. Заметим, что это нельзя использовать для игнорирования файлового дескриптора 0).

Поле events представляет собой входной параметр — битовую маску, указывающую на события, происходящие с файловым дескриптором fd, которые важны для приложения. Если это поле равно нулю, то возвращаемыми событиями в revents могут быть POLLHUP, POLLERR и POLLNVAL (смотрите ниже).

Поле revents представляет собой параметр-результат, в который ядро помещает информацию о произошедших событиях. В revents могут содержаться любые битовые флаги из задаваемых в events, или там может быть одно из значений: POLLERR, POLLHUP или POLLNVAL. Эти три битовых флага не имеют смысла в поле events, но будут установлены в поле revents, если соответствующее условие истинно.

Если ни одно из запрошенных событий с файловыми дескрипторами не произошло или не возникло ошибок, то poll() блокируется до их появления.

В аргументе timeout указывается количество миллисекунд, на которые будет блокироваться poll() в ожидании готовности файлового дескриптора. Вызов будет заблокирован пока:

- файловый дескриптор не станет готов;

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

- не истечёт время ожидания.

Заметим, что интервал timeout будет округлён с точностью системных часов, а из-за задержки при планировании в ядре блокирующий интервал будет немного больше. Отрицательное значение в timeout означает бесконечное ожидание. Значение timeout, равное нулю, приводит к немедленному завершению poll(), даже если ни один файловый дескриптор не готов.

Вот возможные биты, описанные в <poll.h>, которые могут быть установлены/получены в events и revents:

POLLIN

Есть данные для чтения.

POLLPRI

Исключительное состояние файлового дескриптора. Может быть из-за:

- Внеполосные данные в сокете TCP (смотрите tcp(7)).

- Мастер псевдо-терминала в пакетном режиме увидел изменение состояния подчинённого терминала (смотрите ioctl_tty(2)).

- Изменился файл cgroup.events (смотрите cgroups(7)).

POLLOUT

Теперь запись возможна, но запись данных больше, чем доступно места в сокете или канале, по-прежнему приводит к блокировке (если не указан O_NONBLOCK).

POLLRDHUP (начиная с Linux 2.6.17)

Удалённая сторона потокового сокета закрыла соединение, или отключила запись в одну сторону. Для использования данного определения должен быть определён макрос тестирования свойств _GNU_SOURCE (до включения каких-либо заголовочных файлов).

POLLERR

Состояние ошибки (возвращается только в revents; игнорируется в events). Также этот бит устанавливается для файлового дескриптора, указывающего в пишущий конец канала при закрытом читающем конце.

POLLHUP

Зависание (hang up, возвращается только в revents; игнорируется в events). Заметим, что при чтении из канала, такого как канал (pipe) или потоковый сокет, это событие всего-навсего показывает, что партнёр закрыл канал со своего конца. Дальнейшее чтение из канала будет возвращать 0 (конец файла) только после потребления всех неполученных данных в канале.

POLLNVAL

Неверный запрос: fd не открыт (возвращается только в revents; игнорируется в events).

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

POLLRDNORM

Эквивалентно POLLIN.

POLLRDBAND

Доступны для чтения приоритетные внутриполосные данные (в Linux, обычно, не используется).

POLLWRNORM

Эквивалентно POLLOUT.

POLLWRBAND

Можно писать приоритетные данные.

В Linux также есть POLLMSG, но он не используется.

### ppoll()
Отношения между poll() и ppoll() аналогичны родству select(2) и pselect(2): как pselect(2), ppoll() позволяет приложению безопасно ждать, пока файловый дескриптор не станет готов или пока не будет получен сигнал.

Кроме различия в точности аргумента timeout вызов ppoll()

```
ready = ppoll(&fds, nfds, tmo_p, &sigmask);
```

почти эквивалентен атомарному выполнению следующих вызовов:

```
sigset_t origmask;
int timeout;
timeout = (tmo_p == NULL) ? -1 :

          (tmo_p->tv_sec * 1000 + tmo_p->tv_nsec / 1000000);
pthread_sigmask(SIG_SETMASK, &sigmask, &origmask);
ready = poll(&fds, nfds, timeout);
pthread_sigmask(SIG_SETMASK, &origmask, NULL);
```

Приведённый выше сегмент кода показывает ближайший эквивалент, так как отрицательное значение timeout в poll() рассматривается как бесконечное ожидание, а отрицательное значение в *tmo_p привело бы к ошибке ppoll().

Смотрите в pselect(2) пояснения о необходимости ppoll().

Если значение аргумента sigmask равно NULL, то изменение маски сигналов не происходит (и поэтому ppoll() отличается от poll() только в точности аргумента timeout).

В аргументе tmo_p указывается верхняя граница промежутка времени, на который будет заблокирован ppoll(). Этот аргумент представляет собой указатель на структуру следующего вида:

```
struct timespec {

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

    long    tv_nsec;        /* наносекунды */
};
```

Если значение tmo_p равно NULL, то ppoll() может оставаться заблокированным бесконечно.

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

## ОШИБКИ
EFAULT

Указанный аргументом массив содержится вне адресного пространства вызывающей программы.

EINTR

Получен сигнал раньше какого-либо запрашиваемого события; смотрите signal(7).

EINVAL

Значение nfds превышает значение RLIMIT_NOFILE.

EINVAL

(ppoll()) Время ожидания в *ip некорректно (отрицательное).

ENOMEM

Нет места под таблицы файловых дескрипторов.

## ВЕРСИИ
Системный вызов poll() появился в Linux 2.1.23. Для старых ядер, в которых этот вызов отсутствует, glibc (и старая Linux libc) предоставляет обёрточную функцию poll(), которая эмулируется с помощью select(2).

Системный вызов ppoll() был добавлен в ядро Linux в версии 2.6.16. Библиотечный вызов ppoll() был добавлен в glibc 2.4.

## СООТВЕТСТВИЕ СТАНДАРТАМ
Вызов poll() соответствует POSIX.1-2001 и POSIX.1-2008. Вызов ppoll() есть только в Linux.

## ЗАМЕЧАНИЯ
На операции poll() и ppoll() флаг O_NONBLOCK не влияет.

В некоторых системах UNIX вызов poll() может завершаться с ошибкой EAGAIN, если системе не удаётся выделить внутренние ресурсы ядра, вместо ошибки ENOMEM как это происходит в Linux. В POSIX допускается такое поведение. Переносимые программы должны ожидать EAGAIN в цикле, как для EINTR.

В некоторых реализациях определена нестандартная константа INFTIM со значением -1 для использования в качестве значения timeout в poll(). Эта константа отсутствует в glibc.

Обсуждение того, что может случиться, если файловый дескриптор отслеживается poll() и при этом закрывается в другой нити, смотрите в select(2).

### Отличия между библиотекой C и ядром
В Linux системный вызов ppoll() изменяет свой аргумент tmo_p. Однако, обёрточная функция glibc скрывает это поведение с помощью локальной переменной для аргумента timeout, которая передаётся в системный вызов. Поэтому glibc функция ppoll() не изменяет свой аргумент tmo_p.

Ядерный системный вызов ppoll() имеет пятый аргумент, size_t sigsetsize, в котором указывается размер аргумента sigmask в байтах. В обёрточной функции glibc ppoll() в этом аргументе передаётся постоянная величина (равная sizeof(kernel_sigset_t)). Описание различий sigset между ядерным и библиотечным вызовом смотрите в sigprocmask(2).

## ДЕФЕКТЫ
Смотрите описание ложных уведомлений о готовности в разделе ДЕФЕКТЫ справочной страницы select(2).

## СМОТРИТЕ ТАКЖЕ
restart_syscall(2), select(2), select_tut(2), epoll(7), time(7)


title: posix_fadvise(2)

text:
# posix_fadvise(2)

## ИМЯ
posix_fadvise - предварительно декларирует вариант доступа для данных файла

## ОБЗОР

```
#include <fcntl.h>
```

```
int posix_fadvise(int fd, off_t offset, off_t len, int advice);
```

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

posix_fadvise():

_POSIX_C_SOURCE >= 200112L

## ОПИСАНИЕ
Программы могут использовать posix_fadvise() для объявления намерений осуществить доступ к файлу данных в скором будущем определённым образом, тем самым позволяя ядру выполнить некоторые операции по оптимизации.

Аргумент advice применяется к (не обязательно существующей) области, начинающейся с offset, длиной len байт (или до конца файла, если len равно 0) внутри файла, на который ссылается fd. Аргумент advice не является привязкой; он всего лишь выражает ожидание приложения.

Допустимые значения advice:

POSIX_FADV_NORMAL

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

POSIX_FADV_SEQUENTIAL

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

POSIX_FADV_RANDOM

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

POSIX_FADV_NOREUSE

Указанные данные будут запрошены только один раз.

В ядрах до версии 2.6.18, для POSIX_FADV_NOREUSE использовалась такая же семантика что и у POSIX_FADV_WILLNEED. Это, вероятно, было дефектом; начиная с ядра 2.6.18 для этого флага нет операции.

POSIX_FADV_WILLNEED

Указанные данные будут запрошены в скором будущем.

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

POSIX_FADV_DONTNEED

Указанные данные не будут запрошены в скором будущем.

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

Запросы на удаление частичных страниц игнорируются. Предпочтительней сохранять необходимые данные, а не удалять ненужные. Если приложению требуется, чтобы данные считались подходящими для удаления, то offset и len должны быть выровнены по границе страницы.

Реализация может пытаться записать неактуальные (dirty) страницы указанную область, но это не гарантируется. Все не записанные неактуальные страницы не будут освобождены. Если приложение хочет обязательно освободить неактуальные страницы, то оно сначала должно вызвать fsync(2) или fdatasync(2).

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

## ОШИБКИ
EBADF

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

EINVAL

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

ESPIPE

Указанный файловый дескриптор ссылается на канал (pipe) или FIFO (в этом случае в Linux до версии 2.6.16, возвращал EINVAL, хотя согласно POSIX ошибка должна быть ESPIPE).

## ВЕРСИИ
Поддержка в ядре впервые появилась в Linux 2.5.60; используемый системный вызов называется fadvise64(). Поддержка в библиотеке glibc появилась в версии 2.2; обёрточная функция называется posix_fadvise().

Начиная с Linux 3.18 поддержка данного системного вызова необязательна, она зависит от того, собрано ли ядро с параметром CONFIG_ADVISE_SYSCALLS.

## СООТВЕТСТВИЕ СТАНДАРТАМ
POSIX.1-2001, POSIX.1-2008. Заметим, что в POSIX.1-2003 TC1 тип аргумента len был изменён с size_t на off_t.

## ЗАМЕЧАНИЯ
В Linux POSIX_FADV_NORMAL устанавливает окно упреждающего чтения согласно используемому размеру по умолчанию для ниже лежащего устройства; POSIX_FADV_SEQUENTIAL удваивает этот размер, а POSIX_FADV_RANDOM отменяет упреждающее чтение вообще. Эти изменения влияют на весь файл, а не только на указанную его область (но другие открытые обработчики файлов на этом файле не изменяются).

Содержимое буферного кэша ядра может быть очищено через интерфейс /proc/sys/vm/drop_caches, описанный в proc(5).

Можно получить снимок страниц файла, которые располагаются в буферном кэше: открыть файл, отобразить его через mmap(2) и затем применить mincore(2) к отображению.

### Отличия между библиотекой C и ядром
Обёрточная функция в библиотеке C называется posix_fadvise(). Используемый ей системный вызов называется fadvise64() (на некоторых архитектурах — fadvise64_64()); разница между ними в том, что в библиотечной функциитип аргумента len равен size_t, а у системного вызова — loff_t.

### Варианты, зависящие от архитектуры
На некоторых архитектурах требуется, чтобы 64-битные аргументы были выровнены в подходящей паре регистров (подробности в syscall(2)). На таких архитектурах показанная в СИНТАКСИСЕ форма вызова posix_fadvise() приводила бы пустой трате регистра для заполнения между аргументами fd и offset. Поэтому на этих архитектурах определена версия системного вызова с исправленным порядком аргументов, иначе используется формат как у posix_fadvise().

Например, начиная с Linux 2.6.14, в ARM есть следующий системный вызов:

```
long arm_fadvise64_64(int fd, int advice,
                      loff_t offset, loff_t len);
```

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

## ДЕФЕКТЫ
В ядрах до версии 2.6.6, если значение len равнялось 0, то это воспринималось дословно как «ноль байт», а не как «все байты до конца файла».

## СМОТРИТЕ ТАКЖЕ
fincore(1), mincore(2), readahead(2), sync_file_range(2), posix_fallocate(3), posix_madvise(3)


prctl

title: prctl(2)

summary: операции над процессом

text:
# prctl(2)

## ИМЯ
prctl - операции над процессом

## ОБЗОР

```
#include <sys/prctl.h>
```

```
int prctl(int option, unsigned long arg2, unsigned long arg3,
          unsigned long arg4, unsigned long arg5);
```

## ОПИСАНИЕ
Первый аргумент prctl() задаёт тип операции (типы определены в <linux/prctl.h>, значения остальных аргументов зависят от указываемого типа. Первый аргумент может принимать следующие значения:

PR_CAP_AMBIENT (начиная с Linux 4.3)

Читает или изменяет наружный набор мандатов вызывающей нити согласно значению arg2, которое должно быть одним из следующих:

PR_CAP_AMBIENT_RAISE

Мандат, указанный в arg3, добавляется в наружный набор. Указанный мандат уже должен присутствовать в разрешающем и наследуемом наборе. Эта операция неприменима, если установлен бит безопасности SECBIT_NO_CAP_AMBIENT_RAISE.

PR_CAP_AMBIENT_LOWER

Мандат, указанный в arg3, удаляется из наружного набора.

PR_CAP_AMBIENT_IS_SET

Вызов prctl() возвращает 1, если мандат в arg3 присутствует в наружном наборе и 0, если нет.

PR_CAP_AMBIENT_CLEAR_ALL

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

Во всех перечисленных выше операциях значения arg4 и arg5 должны быть равны 0.

Интерфейсы высокого уровня, построенные поверх описанных выше операций, предоставляются в библиотеке libcap(3) под именами cap_get_ambient(3), cap_set_ambient(3) и cap_reset_ambient(3).

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

Возвращает 1 (как результат функции), если мандат, указанный в arg2, есть в списке мандатов вызывающей нити (capability bounding set), или 0, если нет. Константы мандатов определены в <linux/capability.h>. Значениями списка мандатов определяется, может ли процесс получить мандат через установку набора файловых прав при последующем вызове execve(2).

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

Интерфейс высокого уровня, построенный поверх описанной выше операции, предоставляется в библиотеке libcap() под именем cap_get_bound(3).

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

Если вызывающая нить имеет мандат CAP_SETPCAP в своём пользовательском пространстве имён, то мандат, указанный в arg2, удаляется из списка мандатов вызывающей нити. Любой потомок вызывающей нити унаследует новый сокращённый список мандатов.

Вызов завершается с ошибками: EPERM, если вызывающая нить не имеет мандата CAP_SETPCAP; EINVAL, если в arg2 указан недопустимый мандат; EINVAL, если файловые мандаты не включены в ядре, в этом случае списки мандатов не поддерживаются.

Интерфейс высокого уровня, построенный поверх описанной выше операции, предоставляется в библиотеке libcap() под именем cap_drop_bound(3).

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

Если значение arg2 не равно 0, то в вызвавшем процессе устанавливается атрибут «сборщика потомков» (child subreaper); если значение arg2 равно 0, то атрибут удаляется.

Сборщик потомков выполняет функцию init(1) для своих потомков. При завершении осиротевшего процесса (т. е. прямой предок уже завершил выполнение), его родителем станет ближайший действующий сборщик-предок. После этого вызов getppid() в осиротевшем процессе будет возвращать PID процесса-сборщика, и когда осиротевший процесс завершит работу, сборщик получит сигнал SIGCHLD и сможет запустить wait(2) для получения состояния завершения потомка.

Установка атрибута «сборщика потомков» не наследуется потомками, создаваемыми fork(2) и clone(2). Данное значение сохраняется после execve(2).

Назначение процесса-сборщика полезно в инфраструктуре управления сеансами, где иерархическая группа процессов управляется процессом-сборщиком, которому нужно сообщать, когда один из процессов — например, служба, выполнившая двойное создание (fork) — завершается (возможно для того, чтобы её можно было перезапустить). Некоторые инфраструктуры init(1) (например, systemd(1)) используют a процесс-сборщик для этих целей.

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

Возвращает значение атрибута «сборщика потомков» вызывающего в расположение, указанное (int *) arg2.

PR_SET_DUMPABLE (начиная с Linux 2.3.20)

Установить состояние флага «дампа», определяющего создание файла core вызывающего процесса после доставки сигнала, чьё поведение по умолчанию вызывает создание файла core.

В ядрах по 2.6.12 включительно, значение arg2 должно быть равно 0 (SUID_DUMP_DISABLE, от процесса не остаётся дампа) или 1 (SUID_DUMP_USER, после процесса остаётся дамп). Между ядрами 2.6.13 и 2.6.17, также было разрешено значение 2, означающее что от любого исполняемого файла, обычно дампа не остаётся, но суперпользователь может это сделать; для улучшения безопасности эта возможность была удалена (смотрите также описание /proc/sys/fs/suid_dumpable в proc(5)).

Обычно, значение этого флага равно 1. Однако, оно сбрасывается в текущее значение, содержащееся в файле /proc/sys/fs/suid_dumpable (которое по умолчанию равно 0), в следующих случаях:

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

- Изменён процессный идентификатор пользователя или группы файловой системы (смотрите credentials(7)).

- Процесс выполняет (execve(2)) программу с установленным битом set-user-ID или set-group-ID, что приводит к изменению идентификатора эффективного пользователя или эффективной группы.

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

Процессы, для которых невозможен дамп, нельзя присоединить через операцию ptrace2() PTRACE_ATTACH; подробности смотрите в ptrace(2).

Если для процесса невозможен дамп, то на владение файлами в каталоге процесса /proc/[pid] действуют правила, описанные в proc(5).

PR_GET_DUMPABLE (начиная с Linux 2.3.20)

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

PR_SET_ENDIAN (начиная с Linux 2.6.18, только для PowerPC)

Устанавливает порядок байт вызывающего процесса равным значению arg2, которое может быть одним из: PR_ENDIAN_BIG, PR_ENDIAN_LITTLE или PR_ENDIAN_PPC_LITTLE (для PowerPC псевдо обратный порядок (pseudo little endian)).

PR_GET_ENDIAN (начиная с Linux 2.6.18, только для PowerPC)

Записывает значение порядка байт вызывающего процесса по адресу, указанному в (int *) arg2.

PR_SET_FP_MODE (начиная с Linux 4.0, только на MIPS)

На архитектуре MIPS код пользовательского пространства можно собирать используя ABI, который позволяет компоновку с кодом, имеющем более ограничительные требования для плавающей запятой (FP). Например, код пользовательского пространства может собираться для цели O32 FPXX ABI и компоноваться с кодом, собранным с одним из более ограничительных FP32 или FP64 ABI. При этом требование всего процесса устанавливается в более ограничительный режим плавающей запятой.

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

В аргументе (unsigned int) arg2 указывается битовая маска, описывающая используемый режим плавающей запятой:

PR_FP_MODE_FR

Если это бит сброшен (так называемый режим FR=0 или FR0), то ширина 32 регистров плавающей запятой равна 32, а 64-битные регистры представляются в виде пары регистров (с чётными и нечётными номерами; регистры с чётными номерами содержат 32 младших бита, а с нечётными номерами 32 старших бита).

Если этот бит установлен (есть поддержка в оборудовании), то ширина 32 регистров плавающей запятой равна 64 (так называемый режим FR=1 или FR1). Заметим, что современные реализации MIPS (MIPS R6 и новее) поддерживают только режим FR=1.

Приложения, использующие O32 FP32 ABI, могут работать только когда этот бит сброшен (FR=0; или они могут использоваться с включённым FRE, смотрите ниже). Приложения, использующие O32 FP64 ABI (и O32 FP64A ABI, существующий для предоставления возможности работы с существующим кодом FP32; смотрите ниже), могут работать только когда этот бит установлен (FR=1). Приложения, использующие O32 FPXX ABI, могут работать и с FR=0 и с FR=1.

PR_FP_MODE_FRE

Включает эмуляцию 32-битного режима плавающей запятой. Когда этот режим включён, эмуляция 32-битных операций с плавающей запятой выполняется генерацией исключения на каждую инструкцию, использующую 32-битный формат, и ядро обрабатывает инструкцию программно (проблема заключается в несоответствии обработке регистров с нечётными номерами, которые содержатся в 32 старших битах 64-битных регистров с чётными номерами при режиме FR=0 и в 32 младших битах 64-битах регистров с нечётными номерами при режиме FR=1). При включении этого бита необходимо, чтобы код с O32 FP32 ABI работал с кодом O32 FPXX или O32 FP64A ABI (для которого требуется режим FR=1 FPU) или когда он выполняется на новой аппаратуре (MIPS R6 и новее), в которой нет поддержки режима FR=0, когда используется двоичный файл с FP32 ABI.

Заметим, что этот режим приобретает смысл только, если FPU в 64-битном режиме (FR=1).

Также заметим, что использование эмуляции по определению уменьшает производительность и её нужно, по возможности, избегать.

В N32/N64 ABI всегда используется 64-битный режим плавающей запятой, поэтому эмуляция FPU не требуется и FPU всегда работает в режиме FR=1.

Данный параметр, в основном, предназначен для динамического компоновщика (ld.so(8)).

Аргументы arg3, arg4 и arg5 игнорируются.

PR_GET_FP_MODE (начиная с Linux 4.0, только на MIPS)

Возвращает текущий режим плавающей запятой (смотрите описание PR_SET_FP_MODE).

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

Аргументы arg2, arg3, arg4 и arg5 игнорируются.

PR_SET_FPEMU (начиная с Linux 2.4.18, 2.5.9, только для ia64)

Устанавливает значение управляющих эмуляцией плавающей точки бит равным значению arg2. Для негласной (silently) эмуляции операций с плавающей точкой передайте PR_FPEMU_NOPRINT; при указании PR_FPEMU_SIGFPE операции с плавающей точкой не эмулируются, а посылается сигнал SIGFPE.

PR_GET_FPEMU (начиная с Linux 2.4.18, 2.5.9, только для ia64)

Записывает значение управляющих бит эмуляции плавающей точки по адресу, указанному в (int *) arg2.

PR_SET_FPEXC (начиная с Linux 2.4.21, 2.5.32, только для PowerPC)

Устанавливает режим исключений плавающей точки равным arg2. Значение PR_FP_EXC_SW_ENABLE включает использование FPEXC для исключений плавающей точки, PR_FP_EXC_DIV — исключение деления на ноль, PR_FP_EXC_OVF — исключение переполнения, PR_FP_EXC_UND — исключение исчерпания, PR_FP_EXC_RES — исключение неточного результата, PR_FP_EXC_INV — исключение недопустимой операции, PR_FP_EXC_DISABLED отключает исключения плавающей точки, PR_FP_EXC_NONRECOV включает режим асинхронного невосстанавливаемого исключения, PR_FP_EXC_ASYNC включает режим асинхронного восстанавливаемого исключения, PR_FP_EXC_PRECISE включает режим исключения точности.

PR_GET_FPEXC (начиная с Linux 2.4.21, 2.5.32, только для PowerPC)

Записывает значение режима исключений плавающей точки по адресу, указанному в (int *) arg2.

PR_SET_KEEPCAPS (начиная с Linux 2.2.18)

Устанавливает флаг вызывающей нити «оставить мандаты». Этот флаг описан в capabilities(7). Значение arg2 должно быть или 0 (сбросить флаг) или 1 (установить флаг). Значение флага «оставить мандаты» будет сброшено в 0 при последующих вызовах execve(2).

PR_GET_KEEPCAPS (начиная с Linux 2.2.18)

Возвращает (как результат функции) текущее состояние флага «оставить мандаты» вызывающей нити. Описание флага смотрите в capabilities(7).

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

Устанавливает политику удаления (kill) при обнаружении повреждения памяти машинной проверкой для вызывающей нити. Если значение arg равно PR_MCE_KILL_CLEAR, то политика удаления (kill) сбрасывается и используется системная установка по умолчанию. (Значение системной установки по умолчанию определено в /proc/sys/vm/memory_failure_early_kill; смотрите proc(5).) Значение arg2, равное PR_MCE_KILL_SET, указывает использовать политику удаления, заданную в нити. В этом случае значение arg3 определяет политику: раннее удаление (PR_MCE_KILL_EARLY), позднее удаление (PR_MCE_KILL_LATE) или системная установка по умолчанию (PR_MCE_KILL_DEFAULT). При раннем удалении нить получает сигнал SIGBUS сразу же при аппаратном обнаружении повреждения памяти в её адресном пространстве. В режиме позднего удаления процесс будет удалён только когда обратится к повреждённой странице. Более подробную информацию о сигнале SIGBUS смотрите в sigaction(2). Политика наследуется потомками. Значения остальных неиспользуемых аргументов prctl() должны быть равны нулю для совместимости в будущем.

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

Возвращает значение политики удаления при машинной проверке для текущего процесса. Значения всех неиспользуемых аргументов prctl() должны быть равны нулю.

PR_SET_MM (начиная с Linux 3.3)

Изменяет определённые поля дескриптора карты памяти ядра вызывающего процесса. Обычно, значения этих полей задаются ядром или динамическим загрузчиком (подробней смотрите ld.so(8)), и обычные приложения не должны использовать эту возможность. Однако, есть случаи (самоизменяющиеся программы), где для программы может оказаться полезным изменение своей карты памяти.

Вызывающий процесс должен иметь мандат CAP_SYS_RESOURCE. Значения аргумента arg2 описаны далее, а в arg3 задаётся новое значение.Аргументы, arg4 и arg5, если не используются, должны быть равно нулю.

До Linux 3.10 эта возможность доступна только, если ядро собрано с параметром CONFIG_CHECKPOINT_RESTORE.

PR_SET_MM_START_CODE

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

PR_SET_MM_END_CODE

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

PR_SET_MM_START_DATA

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

PR_SET_MM_END_DATA

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

PR_SET_MM_START_STACK

Устанавливает начальный адрес стека. Соответствующая область памяти должна быть доступна на чтение и запись.

PR_SET_MM_START_BRK

Устанавливает адрес памяти, выше которого можно расширять программную кучу с помощью вызова brk(2). Адрес должен быть больше конечного адреса текущего программного сегмента данных. Также, суммарный размер полученной кучи и сегмента данных не может превышать ограничитель ресурса RLIMIT_DATA (смотрите setrlimit(2)).

PR_SET_MM_BRK

Устанавливает текущее значение brk(2). Требования к адресу те же, что и в параметре PR_SET_MM_START_BRK.

Начиная с Linux 3.5 доступны следующие параметры:

PR_SET_MM_ARG_START

Задаёт адрес, выше которого размещена командная строка программы.

PR_SET_MM_ARG_END

Задаёт адрес, ниже которого размещена командная строка программы.

PR_SET_MM_ENV_START

Задаёт адрес, выше которого размещено окружение программы.

PR_SET_MM_ENV_END

Задаёт адрес, ниже которого размещено окружение программы.

Адрес, передаваемый с PR_SET_MM_ARG_START, PR_SET_MM_ARG_END, PR_SET_MM_ENV_START и PR_SET_MM_ENV_END, должен принадлежать области стека процесса. То есть, соответствующая память должна быть доступна на чтение, запись и (в зависимости от настройки ядра) у неё должен быть установлен атрибут MAP_GROWSDOWN (смотрите mmap(2)).

PR_SET_MM_AUXV

Задаёт новый вспомогательный вектор (auxiliary vector). В аргументе arg3 должен передаваться адрес вектора. В аргументе arg4 — размер вектора.

PR_SET_MM_EXE_FILE

Заменяет символьную ссылку /proc/pid/exe новой, указывающей на новый исполняемый файл, задаваемый файловым дескриптором в аргументе arg3. Файловый дескриптор должен быть получен с помощью обычного вызова open(2).

Для изменения символьной ссылки необходимо отключить (unmap) все существующие исполняемые области памяти, включая созданные самим ядром (например, ядро, обычно, создаёт, как минимум, исполняемую область памяти для раздела ELF .text).

В Linux 4.9 и старее операцию PR_SET_MM_EXE_FILE можно выполнить только один раз за время существования процесса; повторная попытка выполнения приводит к ошибке EPERM. Это ограничение было введено по причинам безопасности, которые впоследствии стали излишними, и ограничение было удалено в Linux 4.10, так как некоторым приложениям пользовательского пространства требуется выполнять эту операцию более одного раза.

Начиная с Linux 3.18 доступны следующие параметры:

PR_SET_MM_MAP

Предоставляет однократный доступ ко всем адресам, переданным в struct prctl_mm_map (определена в <linux/prctl.h>). В аргументе arg4 должен указываться размер структуры.

Эта возможность доступна только, если ядро собрано с параметром CONFIG_CHECKPOINT_RESTORE.

PR_SET_MM_MAP_SIZE

Возвращает размер struct prctl_mm_map, который ожидает ядро. Это позволяет пользователю подобрать совместимую структуру. Аргумент arg4 должен быть указателем на unsigned int.

Эта возможность доступна только, если ядро собрано с параметром CONFIG_CHECKPOINT_RESTORE.

PR_MPX_ENABLE_MANAGEMENT, PR_MPX_DISABLE_MANAGEMENT (начиная с Linux 3.19)

Включает или выключает управление таблицами границ Memory Protection eXtensions (MPX) из ядра. Аргументы arg2, arg3, arg4 и arg5 должны быть равно 0.

MPX — полуаппаратный механизм проверки границ указателей. Он состоит из набора регистров, хранящих информацию о границах и наборе специальных префиксов инструкций, которые указывают ЦП, в каких инструкциях нужно проверить границы. Число регистров ограничено и когда указателей становится больше чем регистров, их содержимое нужно «засыпать» в набор таблиц. Эти таблицы называются «таблицами границ» (bounds tables), а для управления их заполнением и освобождением из ядра существуют операции MPX prctl().

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

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

Эти вызовы завершаются ошибкой, если ЦП или ядро не поддерживают MPX. Поддержка MPX в ядре включается параметром настройки CONFIG_X86_INTEL_MPX. Вы можете проверить наличие поддержки MPX в ЦП прочитав бит «mpx» в CPUID следующей командой:

```
cat /proc/cpuinfo | grep ' mpx '

```

Нить может не переключиться в «длинный» режим (64-битный) при включённом MPX.

Эти вызовы влияют на все нити процесса.

Потомок fork(2) наследует состояние управления MPX. Во время execve(2) управление MPX сбрасывается в состояние, как если бы выполнился вызов PR_MPX_DISABLE_MANAGEMENT.

Дополнительную информацию по Intel MPX смотрите в файле исходного кода ядра Documentation/x86/intel_mpx.txt.

PR_SET_NAME (начиная с Linux 2.6.9)

Назначает имя вызывающей нити, используя значение памяти, переданное в указателе (char *) arg2. Имя может быть не более 16, включая завершающий байт null (если длина строки, включая завершающий null, превышает 16 байт, то строка просто обрезается). Это то же атрибут, который можно установить через pthread_setname_np(3) и получить с помощью pthread_getname_np(3). Также этот атрибут доступен через /proc/self/task/[tid]/comm, где tid — имя вызывающей нити.

PR_GET_NAME (начиная с Linux 2.6.11)

Записывает имя вызывающей нити в буфер, указанный в (char *) arg2. Буфер должен быть не более 16 байт; полученная строка будет завершаться null.

PR_SET_NO_NEW_PRIVS (начиная с Linux 3.5)

Устанавливает атрибут no_new_privs вызывающей нити равным arg2. Если значение no_new_privs равно 1, то execve(2) не выдаст прав никому, кто бы не мог это сделать без вызова execve(2) (например, без битов прав режима set-user-ID и set-group-ID и файловых мандатов). После установки атрибута no_new_privs его нельзя сбросить. Значение этого атрибута наследуется потомками, созданными с помощью fork(2) и clone(2), и сохраняется при execve(2).

Начиная с Linux 4.10, значения атрибута no_new_privs нити отражено в поле NoNewPrivs файла /proc/[pid]/status.

Дополнительную информацию смотрите в файле исходного кода ядра Documentation/userspace-api/no_new_privs.rst (или в Documentation/prctl/no_new_privstxt до Linux 4.13). Также смотрите seccomp(2).

PR_GET_NO_NEW_PRIVS (начиная с Linux 3.5)

Возвращает значение (как результат функции) атрибута no_new_privs в вызывающей нити. Значение 0 соответствует обычному поведению execve(2). Значение 1 показывает, что execve(2) будет работать в ограничивающем права режиме, как описано ранее.

PR_SET_PDEATHSIG (начиная с Linux 2.1.57)

Устанавливает значение сигнала, приходящего процессу при завершении работы родительского процесса, равным arg2 (значение может быть из диапазона 1..maxsig или 0 для снятия). Этот сигнал получит вызывающий процесс, когда его родитель завершит работу.

Предупреждение: «родителем» здесь считается нить, создавшая этот процесс. Иначе говоря, сигнал будет послан при завершении нити (например, с помощью pthread_exit(3)), а не всех нитей родительского процесса.

Сигнал отправляется после завершения родительской нити, а также после завершения каждого процесса-сборщика потомков (смотрите описание PR_SET_CHILD_SUBREAPER выше), которыми вызывающий был последовательно усыновлён. Если родительская нить и все предки сборщиков завершили работу на момент операции PR_SET_PDEATHSIG, то сигнал о завершении вызывающему не посылается.

Сигнал о завершении родителя направляется процессу (смотрите signal(7)) и, если потомок установил обработчик использовав sigaction(2) с флагом SA_SIGINFO, то поле si_pid аргумента siginfo_t обработчика содержит PID завершающегося родительского процесса.

Значение сигнала о завершении родителя очищается для потомков, созданных fork(2). Он также очищается (начиная с Linux 2.4.36 / 2.6.23) при выполнении исполняемого файла с установленным битом set-user-ID или set-group-ID, и исполняемого файла с соответствующими мандатами (смотрите capabilities(7)); иначе это значение сохраняется при execve(2).

PR_GET_PDEATHSIG (начиная с Linux 2.3.15)

Записывает текущее значение сигнала о завершении работы родительского процесса по адресу, указанному в (int *) arg2.

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

Имеет смысл, только если включён Yama LSM и в режиме 1 («ограниченный ptrace», значение доступно в /proc/sys/kernel/yama/ptrace_scope). Когда «идентификатор процесса ptracer» передаётся в arg2, вызывающий объявляет, что процесс ptracer может выполнить ptrace(2), как если бы он был прямым предком процесса. Каждая операция PR_SET_PTRACER заменяет предыдущий «идентификатор процесса ptracer». Применение PR_SET_PTRACER с значением arg2 равным 0 очищает «идентификатор процесса ptracer» вызывающего. Если arg2 равно PR_SET_PTRACER_ANY, то ограничения ptrace, предоставленные Yama отключаются для вызывающего процесса.

Дополнительную информацию смотрите в файле исходного кода ядра Documentation/admin-guide/LSM/Yama.rst (или в Documentation/security/Yama.txt до Linux 4.13).

PR_SET_SECCOMP (начиная с Linux 2.6.23)

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

Режим seccomp выбирается из arg2 (константы seccomp определены в <linux/seccomp.h>).

Если значение arg2 равно SECCOMP_MODE_STRICT, то в нити доступны только системные вызовы read(2), write(2), _exit(2) (но не exit_group(2)) и sigreturn(2). При запуске других системных вызовов генерируется сигнал SIGKILL. Режим безопасных вычислений полезен для вычислительных приложений, которым может потребоваться выполнить недоверительный байт-код, возможно полученный при чтении из канала или сокета. Эта операция доступна только, если в ядре включён параметр CONFIG_SECCOMP.

Если значение arg2 равно SECCOMP_MODE_FILTER (начиная с Linux 3.5), то список разрешённых системных вызовов определяется указателем (arg3) на пакетный фильтр Berkeley. Аргумент указывает на struct sock_fprog; в структуре можно описать фильтр и произвольных системных вызовов и их аргументов. Этот режим доступен только, если ядро собрано с параметром CONFIG_SECCOMP_FILTER.

Если в фильтрах SECCOMP_MODE_FILTER разрешён fork(2), то режим seccomp наследуется потомками, создаваемыми fork(2); если разрешён execve(2), то режим seccomp сохраняется при execve(2). Если в фильтрах разрешены prctl(), то могут быть добавлены дополнительные фильтры; они применяются до тех пор пока не будет найдено запрещение.

Дополнительную информацию смотрите в файле исходного кода ядра Documentation/userspace-api/seccomp_filter.rst (или в Documentation/prctl/seccomp_filter.txt до Linux 4.13).

PR_GET_SECCOMP (начиная с Linux 2.6.23)

Возвращает значение (как результат функции) режима безопасных вычислений вызвавшей нити. Если вызывающий не работает в режиме безопасных вычислений, то возвращается 0; если вызывающий находится в режиме ограниченных безопасных вычислений, то вызов prctl() приведёт к отправке процессу сигнала SIGKILL. Если вызывающий работает в режиме фильтрации и данный системный вызов разрешён в фильтрах seccomp, то возвращается 2; в противном случае процесс завершается по сигналу SIGKILL. Эта операция доступна только, если ядро собрано с параметром CONFIG_SECCOMP.

Начиная с Linux 3.8 в поле Seccomp файла /proc/[pid]/status предоставляется метод получения той же информации, без риска уничтожения процесса; смотрите proc(5).

PR_SET_SECUREBITS (начиная с Linux 2.6.26)

Устанавливает значение флагов «securebits» вызывающей нити равным значению arg2. Смотрите capabilities(7).

PR_GET_SECUREBITS (начиная с Linux 2.6.26)

Возвращает (как результат функции) флаги «securebits» вызывающей нити. Смотрите capabilities(7).

PR_GET_SPECULATION_CTRL (начиная с Linux 4.17)

Возвращает состояние нежелательной спекулятовности, указанной в arg2. В настоящее время значением аргумента может быть только PR_SPEC_STORE_BYPASS (в противном случае возвращается ошибка ENODEV).

В значении результата используются биты 0-3:

PR_SPEC_PRCTL

Смягчение (mitigation) можно контролировать на уровне нити через PR_SET_SPECULATION_CTRL

PR_SPEC_ENABLE

Свойство спекулятивности включено, смягчение выключено.

PR_SPEC_DISABLE

Свойство спекулятивности выключено, смягчение включено

PR_SPEC_FORCE_DISABLE

Тоже, что и PR_SPEC_DISABLE, но нельзя отменить.

Если все биты равны 0, то на ЦП нежелательная спекулятовность не работает.

Если установлен PR_SPEC_PRCTL, то доступно управление смягчением на уровне нити. Если не установлен, то вызов prctl() для нежелательной спекулятовности завершится ошибкой.

Аргументы arg3, arg4 и arg5 должны быть равны 0; в противном случае вызов завершается ошибкой EINVAL.

PR_SET_SPECULATION_CTRL (начиная с Linux 4.17)

Задаёт состояние нежелательной спекулятовности, согласно значению arg2. В настоящее время значением аргумента может быть только PR_SPEC_STORE_BYPASS (в противном случае возвращается ошибка ENODEV).Данная настройка является атрибутом нити. Аргумент arg3 используется как управляющее значение, которое может быть одним из следующих:

PR_SPEC_ENABLE

Свойство спекулятивности включено, смягчение выключено.

PR_SPEC_DISABLE

Свойство спекулятивности выключено, смягчение включено

PR_SPEC_FORCE_DISABLE

Тоже, что и PR_SPEC_DISABLE, но нельзя отменить. Последующий вызов prctl(..., PR_SPEC_ENABLE) завершится ошибкой EPERM.

Любое другое значение в arg3 приведёт к ошибке ERANGE.

Аргументы arg4 и arg5 должны быть равны 0; в противном случае вызов завершается ошибкой EINVAL.

Свойство спекулятивного выполнения также может контролироваться параметром загрузки spec_store_bypass_disable. Это параметр может установить режим только для чтения, при котором вызов prctl() будет завершаться ошибкой ENXIO. Дополнительную информацию смотрите в файле исходного кода ядра Documentation/admin-guide/kernel-parameters.txt.

PR_SET_THP_DISABLE (начиная с Linux 3.15)

Задать состояние флага «THP disable» вызывающей нити. Если arg2 не равно нулю, то флаг устанавливается, иначе очищается. Установка этого флага предоставляет метод отключения прозрачных огромных страниц для заданий, код которых нельзя изменить и использование обработчика malloc с madvise(2) невозможно (т. е., место под данные выделено статически). Значение флага «THP disable» наследуется потомком, создаваемым fork(2) и сохраняется после execve(2).

PR_TASK_PERF_EVENTS_DISABLE (начиная с Linux 2.6.31)

Отключает все счётчики производительности, прикреплённые к вызывающему процессу, не учитывая, были ли они созданы этим процессом или каким-то другим. Счётчики производительности, созданные вызывающим процессом для других процессов, не отключаются. Подробности о счётчиках производительности приведены в файле ядра Linux tools/perf/design.txt.

Сначала назывался PR_TASK_PERF_COUNTERS_DISABLE; переименован (числовое значение не изменилось) в Linux 2.6.32.

PR_TASK_PERF_EVENTS_ENABLE (начиная с Linux 2.6.31)

Противоположное действие PR_TASK_PERF_EVENTS_DISABLE; включает счётчики производительности, прикреплённые к вызывающему процессу.

Сначала назывался PR_TASK_PERF_COUNTERS_ENABLE; переименован в Linux 2.6.32.

PR_GET_THP_DISABLE (начиная с Linux 3.15)

Возвращает текущее значение (как результат функции) флага «THP disable» вызывающей нити: 1 — флаг установлен; 0 — нет.

PR_GET_TID_ADDRESS (начиная с Linux 3.5)

Возвращает адрес clear_child_tid, заданный set_tid_address(2) и clone(2) с флагом CLONE_CHILD_CLEARTID, в расположение, указанное в (int **) arg2. Эта возможность доступна только, если ядро собрано с параметром CONFIG_CHECKPOINT_RESTORE. Заметим, что так как системный вызов prctl() не содержит совместимой реализации для AMD64 x32 и MIPS n32 ABI и ядро записывает указатель размером с ядерный, то эта операция требует пользовательский буфер в 8 (не 4) байт в этих ABI.

PR_SET_TIMERSLACK (начиная с Linux 2.6.28)

Каждая нити имеет два связанных с таймером значения допуска: значение «по умолчанию» и «текущее» значение. Эта операция изменяет «текущее» значение допуска таймера вызывающей нити. Значение arg2 имеет тип длинного беззнакового целого, то есть максимальное «текущее» значение равно ULONG_MAX, а минимальное «текущее» значение равно 1. Если наносекундное значение из arg2 больше нуля, то оно присваивается «текущему» значению. Если arg2 равно 0, то «текущий» допуск таймера нити сбрасывается в значение допуска таймера «по умолчанию».

«Текущий» допуск таймера используется ядром для группировки таймерных окончаний при вызовах нити, которые происходят очень часто; как следствие, таймерные окончания нити могут быть равны до указанной наносекундной задержки (но никогда не будут истекать ранее). Группировка таймерных окончаний может помочь сократить потребление энергии системой, в следствии сокращения количества пробуждений ЦП.

Таймерные окончания, на которые влияет допуск таймера, устанавливаются select(2), pselect(2), poll(2), ppoll(2), epoll_wait(2), epoll_pwait(2), clock_nanosleep(2), nanosleep(2) и futex(2) (и, следовательно, все библиотечными функциями, реализованными через futex: pthread_cond_timedwait(3), pthread_mutex_timedlock(3), pthread_rwlock_timedrdlock(3), pthread_rwlock_timedwrlock(3) и sem_timedwait(3)).

Допуск таймера не применяется к нитям, которые планируются в соответствии с политикой реального времени (смотрите sched_setscheduler(2)).

При создании новой нити этим двум значениям присваивается значение «текущего» допуска создающей нити. После этого нить может подстроить значение своего «текущего» допуска таймера с помощью PR_SET_TIMERSLACK (значение по умолчанию не может быть изменено). Значения допуска таймера для init (PID 1), предка всех процессов, равно 50000 наносекунд (50 микросекунд). Значения допуска таймера наследуются потомком при fork(2) и сохраняются при вызове execve(2).

Начиная с Linux 4.6 значение «текущего» допуска таймера любого процесса можно получить и изменить через файл /proc/[pid]/timerslack_ns. Смотрите proc(5).

PR_GET_TIMERSLACK (начиная с Linux 2.6.28)

Возвращает значение «текущего» допуска (как результат функции) таймера вызывающей нити.

PR_SET_TIMING (начиная с Linux 2.6.0)

Включает использование обычного статистического временного режима выполнения процесса (process timing) или точного режима на основе меток времени (timestamp-based process timing), при передаче PR_TIMING_STATISTICAL или PR_TIMING_TIMESTAMP в arg2. Действия для PR_TIMING_TIMESTAMP пока не реализованы (попытка установить этот режим приведёт к ошибке EINVAL).

PR_GET_TIMING (начиная с Linux 2.6.0)

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

PR_SET_TSC (начиная с Linux 2.6.26, только для x86)

Устанавливает состояние флага, определяющего может ли процесс прочитать счётчик метки времени (timestamp counter). Значение PR_TSC_ENABLE в arg2 разрешает чтение, PR_TSC_SIGSEGV включает генерацию SIGSEGV, если процесс пытается прочитать счётчик метки времени.

PR_GET_TSC (начиная с Linux 2.6.26, только для x86)

Записывает значение флага, определяющего может ли быть прочитан счётчик метки времени (timestamp counter), по адресу, указанному в (int *) arg2.

PR_SET_UNALIGN

(только для: ia64, начиная с Linux 2.3.48; parisc, начиная с Linux 2.6.15; PowerPC, начиная с Linux 2.6.18; Alpha, начиная с Linux 2.6.22; sh, начиная с Linux 2.6.34; tile, начиная с Linux 3.12) Устанавливает значение битов контроля доступа выравнивания равным значению arg2. При значении PR_UNALIGN_NOPRINT пользовательский доступ без выравнивания без уведомления исправляется, а при PR_UNALIGN_SIGBUS генерируется сигнал SIGBUS. На Alpha также поддерживается дополнительный флаг со значением 4 (именованная константа отсутствует), который указывает ядру не исправлять невыровненный доступ (аналогично флагу UAC_NOFIX в операции SSI_NVPAIRS системного вызова setsysinfo() на Tru64).

PR_GET_UNALIGN

(информацию о версиях и архитектурах смотрите в PR_SET_UNALIGN) Записывает значение битов контроля доступа выравнивания по адресу, указанному в (unsigned int *) arg2.

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении для операций PR_GET_DUMPABLE, PR_GET_KEEPCAPS, PR_GET_NO_NEW_PRIVS, PR_GET_THP_DISABLE, PR_CAPBSET_READ, PR_GET_TIMING, PR_GET_TIMERSLACK, PR_GET_SECUREBITS, PR_MCE_KILL_GET, PR_CAP_AMBIENT+PR_CAP_AMBIENT_IS_SET, и (если возвращается) PR_GET_SECCOMP возвращаются неотрицательные значения, описанные ранее. При успешном выполнении для остальных значений option возвращается 0. При ошибке возвращается -1, а errno устанавливается в соответствующее значение.

## ОШИБКИ
EACCES

Значение option равно PR_SET_SECCOMP и arg2 равно SECCOMP_MODE_FILTER, но процесс не имеет мандата CAP_SYS_ADMIN или установленного атрибута no_new_privs (смотрите обсуждение PR_SET_NO_NEW_PRIVS выше).

EACCES

Значение option равно PR_SET_MM, а arg3 — PR_SET_MM_EXE_FILE, файл не является исполняемым.

EBADF

Значение option равно PR_SET_MM, arg3 — PR_SET_MM_EXE_FILE, и файловый дескриптор, переданный в arg4, некорректен.

EBUSY

Значение option равно PR_SET_MM, arg3 — PR_SET_MM_EXE_FILE, и это вторая попытка изменить символьную ссылку /proc/pid/exe, что запрещено.

EFAULT

В arg2 указан неправильный адрес.

EFAULT

Значение option равно PR_SET_SECCOMP, arg2 равно SECCOMP_MODE_FILTER, система была собрана с CONFIG_SECCOMP_FILTER и arg3 содержит некорректный адрес.

EINVAL

Не распознано значение option.

EINVAL

Значение option равно PR_MCE_KILL, PR_MCE_KILL_GET или PR_SET_MM, и неиспользуемые аргументы prctl() не равны нулю.

EINVAL

Неверное значение arg2 для указанной в option операции.

EINVAL

Значение option равно PR_SET_SECCOMP или PR_GET_SECCOMP, и ядро не собрано с параметром CONFIG_SECCOMP.

EINVAL

Значение option равно PR_SET_SECCOMP, arg2 равно SECCOMP_MODE_FILTER и ядро было собрано без CONFIG_SECCOMP_FILTER.

EINVAL

Значение option равно PR_SET_MM и одно из следующего является истиной:

- Значение arg4 или arg5 не равно нулю;

- Значение arg3 больше TASK_SIZE (ограничение на размер пользовательского адресного пространства для этой архитектуры);

- Значение arg2 равно PR_SET_MM_START_CODE, PR_SET_MM_END_CODE, PR_SET_MM_START_DATA, PR_SET_MM_END_DATA или PR_SET_MM_START_STACK, и права на соответствующую область памяти не удовлетворяют требованиям;

- Значение arg2 равно PR_SET_MM_START_BRK или PR_SET_MM_BRK, и значение arg3 меньше или равно концу сегмента данных, или было бы превышено ограничение ресурса RLIMIT_DATA.

EINVAL

Значение option равно PR_SET_PTRACER и значение arg2 не равно 0, PR_SET_PTRACER_ANY или PID существующего процесса.

EINVAL

Значение option равно PR_SET_PDEATHSIG и значение arg2 не является корректным номером сигнала.

EINVAL

Значение option равно PR_SET_DUMPABLE и значение arg2 не равно SUID_DUMP_DISABLE или SUID_DUMP_USER.

EINVAL

Значение option равно PR_SET_TIMING и значение arg2 не равно PR_TIMING_STATISTICAL.

EINVAL

Значение option равно PR_SET_NO_NEW_PRIVS и значение arg2 не равно 1 или arg3, arg4 или arg5 не равны нулю.

EINVAL

Значение option равно PR_GET_NO_NEW_PRIVS и значения arg2, arg3, arg4 или arg5 не равны нулю.

EINVAL

Значение option равно PR_SET_THP_DISABLE и arg3, arg4 или arg5 не равны нулю.

EINVAL

Значение option равно PR_GET_THP_DISABLE и значения arg2, arg3, arg4 или arg5 не равны нулю.

EINVAL

Значение option равно PR_CAP_AMBIENT и неиспользуемый аргумент (arg4, arg5 или, в случае PR_CAP_AMBIENT_CLEAR_ALL, arg3) не равен нулю; или arg2 содержит некорректное значение; или arg2 равно PR_CAP_AMBIENT_LOWER, PR_CAP_AMBIENT_RAISE или PR_CAP_AMBIENT_IS_SET и в arg3 указан некорректный мандат.

EINVAL

Значение option равно PR_GET_SPECULATION_CTRL или PR_SET_SPECULATION_CTRL, но неиспользуемые аргументы prctl() не равны 0.

ENODEV

Значение option равно PR_SET_SPECULATION_CTRL, но ядро или ЦП не поддерживает запрашиваемую нежелательную спекулятовность.

ENXIO

Значение option было PR_MPX_ENABLE_MANAGEMENT или PR_MPX_DISABLE_MANAGEMENT и ядро или ЦП не поддерживают управление MPX. Проверьте, что ядро и процессор поддерживают MPX.

ENXIO

Значение option, равное PR_SET_SPECULATION_CTRL, подразумевает, что управление выбранной нежелательной спекулятовности невозможно. Доступные значения смотрите в описании битовых полей PR_GET_SPECULATION_CTRL.

EOPNOTSUPP

Значение option равно PR_SET_FP_MODE и arg2 содержит неправильное или неподдерживаемое значение.

EPERM

Значение option равно PR_SET_SECUREBITS, и вызывающий не имеет мандата CAP_SETPCAP, или пытается сбросить «заблокированный» флаг, или пытается установить флаг, для которого установлен соответствующий заблокированный флаг (смотрите capabilities(7)).

EPERM

Значение option равно PR_SET_SPECULATION_CTRL, но спекулятивность была отключена с помощью PR_SPEC_FORCE_DISABLE, а вызывающий пытается включить её снова.

EPERM

Значение option равно PR_SET_KEEPCAPS, и у вызывающего установлен флаг SECBIT_KEEP_CAPS_LOCKED (смотрите capabilities(7)).

EPERM

Значение option равно PR_CAPBSET_DROP, и вызывающий не имеет мандата CAP_SETPCAP.

EPERM

Значение option равно PR_SET_MM, и вызывающий не имеет мандата CAP_SYS_RESOURCE.

EPERM

Значение option равно PR_CAP_AMBIENT и arg2 равно PR_CAP_AMBIENT_RAISE, но мандат, указанный в arg3, отсутствует в разрешительном или унаследованном наборе мандатов, или был установлен бит безопасности PR_CAP_AMBIENT_LOWER.

ERANGE

Значение option равно PR_SET_SPECULATION_CTRL, но значение arg3 не равно PR_SPEC_ENABLE, PR_SPEC_DISABLE или PR_SPEC_FORCE_DISABLE.

## ВЕРСИИ
Системный вызов prctl() впервые появился в Linux 2.1.57.

## СООТВЕТСТВИЕ СТАНДАРТАМ
Данный вызов существует только в Linux. В IRIX есть системный вызов prctl() (также представленный в Linux 2.1.44 как irix_prctl на архитектуре MIPS) объявленный как

```
ptrdiff_t prctl(int option, int arg2, int arg3);
```

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

## СМОТРИТЕ ТАКЖЕ
signal(2), core(5)


pread

title: pread(2)

text:
# pread(2)

## ИМЯ
pread, pwrite - чтение или запись информации из файлового дескриптора согласно заданному смещению

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

ssize_t pread(int fd, void *buf, size_t count, off_t offset);

ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset);

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

pread(), pwrite():

_XOPEN_SOURCE >= 500

|| /* начиная с glibc 2.12: */ _POSIX_C_SOURCE >= 200809L

## ОПИСАНИЕ
pread() читает максимум count байтов из файлового дескриптора fd, начиная со смещения offset (от начала файла), в буфер, начиная с buf. Текущая позиция файла не изменяется.

pwrite() записывает максимум count байтов из буфера buf в файловый дескриптор fd , начиная со смещения offset. Текущая позиция файла не изменяется.

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

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении pread() возвращается количество считанных байт (ноль указывает на конец файла), а pwrite() — количество записанных байт.

Заметим, что для успешного выполнения не считается ошибкой передача меньшего количества байт чем запрошено (смотрите read(2) и write(2)).

При ошибке возвращается -1, а в errno содержится код ошибки.

## ОШИБКИ
Вызов pread() может завершиться неудачно и записать в errno один из кодов ошибки, определённых для read(2) или lseek(2). Вызов pwrite() может завершиться неудачно и записать в errno один из кодов ошибки, определённых для write(2) или lseek(2).

## ВЕРСИИ
Системные вызовы pread() и pwrite() были внесены в ядро Linux, начиная с версии 2.1.60; как элементы таблицы системных вызовов i386 были добавлены в ядро версии 2.1.69. Поддержка в библиотеке С (включая эмуляцию с помощью lseek(2) в старых ядрах, не имеющих соответствующих системных вызовов) была добавлена в glibc 2.1.

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

## ЗАМЕЧАНИЯ
Системные вызовы pread() и pwrite() особенно полезны в многонитевых приложениях. Они позволяют нескольким нитям выполнять ввод-вывод в один файловый дескриптор не учитывая изменений файлового смещения, сделанного другими нитями.

### Отличия между библиотекой C и ядром
В Linux нижележащие системные вызовы переименованы в ядре версии 2.6: pread() стал называться pread64(), а pwrite() — pwrite64(). Номера системных вызовов остались прежними. Обёрточные функции pread() и pwrite() в glibc скрывают данные переименование.

На некоторых 32-битных архитектурах интерфейс этих системных вызовов отличается от описанного выше, по причинам указанным в syscall(2).

## ДЕФЕКТЫ
Согласно POSIX требуется, чтобы открытие файла с флагом O_APPEND не влияло на расположение, по которому pwrite() записывает данные. Однако в Linux, если файл открывается с флагом O_APPEND, pwrite() добавляет данные в конец файла, независимо от значения offset.

## СМОТРИТЕ ТАКЖЕ
lseek(2), read(2), readv(2), write(2)


title: process_vm_readv(2)

summary: производит обмен данными между

text:
# process_vm_readv(2)

## ИМЯ
process_vm_readv, process_vm_writev - производит обмен данными между адресными пространствами процессов

## ОБЗОР

```
#include <sys/uio.h>
```

```
ssize_t process_vm_readv(pid_t pid,
                         const struct iovec *local_iov,
                         unsigned long liovcnt,
                         const struct iovec *remote_iov,
                         unsigned long riovcnt,
                         unsigned long flags);
```

```
ssize_t process_vm_writev(pid_t pid,
                          const struct iovec *local_iov,
                          unsigned long liovcnt,
                          const struct iovec *remote_iov,
                          unsigned long riovcnt,
                          unsigned long flags);
```

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

process_vm_readv(), process_vm_writev():

_GNU_SOURCE

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

Системный вызов process_vm_readv() перемещает данные из удалённого процесса в локальный. Перемещаемые данные задаются remote_iov и riovcnt: remote_iov — указатель на массив, описывающий адресные пространства в процессе pid, и в riovcnt указывается количество элементов в remote_iov. Данные перемещаются в расположения, задаваемые local_iov и liovcnt: local_iov — указатель на массив, описывающий адресные пространства в вызывающем процессе, а в liovcnt задаётся количество элементов в local_iov.

Системный вызов process_vm_writev() выполняет операцию, обратную process_vm_readv() — перемещает данные из локального процесса в удалённый. Кроме направления передачи, аргументы liovcnt, local_iov, riovcnt и remote_iov имеют то назначение что и для process_vm_readv().

Аргументы local_iov и remote_iov указывают на массив структур iovec, определённых в <sys/uio.h>:

```
struct iovec {

    void  *iov_base;    /* начальный адрес */

    size_t iov_len;     /* количество перемещаемых байт */
};
```

Буферы обрабатываются в порядке, в каком они указаны в массиве. Это означает, что process_vm_readv() сначала полностью заполнит local_iov[0] и только потом перейдёт к local_iov[1] и так далее. Подобным образом remote_iov[0] сначала полностью читается перед переходом к remote_iov[1] и так далее.

Подобным образом process_vm_writev() записывает всё содержимое local_iov[0] перед тем, как перейти к local_iov[1], и это полностью заполняет remote_iov[0] перед тем как перейти к remote_iov[1].

Длины remote_iov[i].iov_len и local_iov[i].iov_len могут быть не одинаковы. То есть, возможно разделить одни локальный буфер на несколько удалённых буферов и наоборот.

В настоящее время аргумент flags не используется и должен равняться 0.

Значения, указанные в аргументах liovcnt и riovcnt, должны быть меньше или равны IOV_MAX (определено в <limits.h> или доступно через вызов sysconf(_SC_IOV_MAX)).

Количество аргументов и local_iov проверяется перед началом передачи. Если количество слишком велико или local_iov содержит некорректное значение, или адреса областей недоступны локальному процессу, то ни один из векторов не будет обработан и сразу возвращается ошибка.

Однако заметим, что эти системные вызовы не проверяют области памяти в удалённом процессе до начала выполнения чтения/записи. Следовательно может выполниться частичное чтение/запись (смотрите ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ), если один из элементов remote_iov указывает на некорректную область памяти в удалённом процессе. После нахождения такого элемента дальнейшее чтение/запись не производится. Помните об этом, когда читаете данные неизвестной длины (например, строки C, завершающиеся null) из удалённого процесса, избегайте объединения страниц памяти (обычно, 4 КиБ) одного удалённого элемента iovec (вместо этого разделите чтение удалённого элемента на два элемента remote_iov и объедините их обратно в одну запись local_iov entry. Первый читаемый элемент дойдёт до границы страницы, а второй начнётся на следующей границе страницы).

Право читать или писать в другой процесс определяется проверкой режима доступа ptrace PTRACE_MODE_ATTACH_REALCREDS; смотрите ptrace(2).

## ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении process_vm_readv() возвращает количество прочитанных байт, process_vm_writev() возвращает количество записанных байт. Это значение может быть меньше полного числа запрашиваемых байт, если произошло частичное чтение/запись (частичная передача выполняется с точностью по iovec элементам. Эти системные вызовы не выполняют частичной передачи, которая разделила бы один элемент iovec). Вызывающий должен проверить возвращаемое значение, чтобы определить возникало ли частичное чтение/запись.

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

## ОШИБКИ
EFAULT

Память, описываемая в local_iov, находится вне пределов доступного адресного пространства вызывающего.

EFAULT

Память, описываемая в remote_iov, находится вне пределов доступного адресного пространства процесса pid.

EINVAL

Сумма значений iov_len из local_iov или remote_iov превышает значение ssize_t.

EINVAL

Значение flags не равно 0.

EINVAL

Значение liovcnt или riovcnt слишком велико.

ENOMEM

Невозможно выделить память для внутренних копий структур iovec.

EPERM

Вызывающий не имеет прав на доступ к адресному пространству процесса pid.

ESRCH

Процесс с идентификатором pid не существует.

## ВЕРСИИ
Данные системные вызовы были добавлены в Linux 3.2. Поддержка в glibc появилась в версии 2.15.

## СООТВЕТСТВИЕ СТАНДАРТАМ
Данные системные вызовы являются нестандартными расширениями Linux.

## ЗАМЕЧАНИЯ
При пересылке данных с помощью process_vm_readv() и process_vm_writev() не гарантируется атомарность.

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

## ПРИМЕР
В следующем примере показано использование process_vm_readv(). Вызов читает 20 байт по адресу 0x10000 из процесса с PID 10 и записывает первые 10 байт в buf1, а вторые 10 байт в buf2.

```
#include <sys/uio.h>
int
main(void)
{

    struct iovec local[2];

    struct iovec remote[1];

    char buf1[10];

    char buf2[10];

    ssize_t nread;

    pid_t pid = 10;             /* PID удалённого процесса */

    local[0].iov_base = buf1;

    local[0].iov_len = 10;

    local[1].iov_base = buf2;

    local[1].iov_len = 10;

    remote[0].iov_base = (void *) 0x10000;

    remote[0].iov_len = 20;

    nread = process_vm_readv(pid, local, 2, remote, 1, 0);

    if (nread != 20)

        return 1;

    else

        return 0;
}
```

## СМОТРИТЕ ТАКЖЕ
readv(2), writev(2)