getrandom -
возвращает
серию
произвольных
байт
Standard C library (
libc,
-lc)
#include <sys/random.h>
ssize_t getrandom(void buf[.buflen], size_t buflen, unsigned int flags);
Системный
вызов
getrandom()
заполняет
буфер,
указанный
в
buf,
произвольными
байтами в
количестве
до
buflen. Эти
байты
можно
использовать
как
начальные
значения в
генераторах
произвольных
чисел
пространства
пользователя
или с
целями
шифрования.
По
умолчанию,
getrandom()
забирает
энтропию
из
источника
urandom (т. е., того
же
источника
что и
устройство
/dev/urandom). Это
поведение
можно
изменить
через
параметр
flags.
Если
источник
urandom
инициализирован,
то из него
можно
прочитать
не более 256
байт, но
всегда
возвращается
столько
байт,
сколько
запрошено
и это не
будет
прерываться
сигналами.
Для
буферов
большего
размера
это не
гарантируется.
Например,
если вызов
прерывается
обработчиком
сигнала, то
он может
вернуть
частично
заполненный
буфер или
завершиться
с ошибкой
EINTR.
Если
источник
urandom ещё не
инициализирован,
то вызов
getrandom()
блокируется,
если в
flags не
указано
значение
GRND_NONBLOCK.
Аргумент
flags
является
битовой
маской,
которая
может
содержать
ноль или
более
следующих
флагов:
- GRND_RANDOM
- Если
этот бит
установлен,
то
произвольные
байты
берутся из
источника
random (т. е., того
же
источника
что и
устройство
/dev/urandom), а не из
источника
urandom.
Ограничение
источника
random следует
из
энтропии,
которую
можно
получить
из
окружающего
шума. Если
количество
доступных
байт в random
меньше
запрашиваемых
в buflen, то
вызов
завершается
сразу
после
выдачи
всех
доступных
произвольных
байт. Если
произвольных
байт нет,
то
поведение
зависит от
наличия
флага GRND_NONBLOCK в
параметре
flags.
- GRND_NONBLOCK
- По
умолчанию,
при чтении
из
источника
random вызов getrandom()
блокируется,
если
произвольные
байты
недоступны,
и а при
чтении из
источника
urandom
блокируется,
если ещё не
инициализирован
пул
энтропии.
Если
указан
флаг GRND_NONBLOCK, то
в этих
случаях
getrandom() не
блокируется,
а сразу
возвращает
-1 и
присваивает
errno
значение
EAGAIN.
При
успешном
выполнении
getrandom()
возвращает
количество
скопированных
в буфер
buf
байт. Это
значение
может быть
меньше, чем
количество
запрашиваемых
в
buflen байт,
если в
flags
был указан
GRND_RANDOM и нет
достаточного
количества
энтропии в
источнике
random, или если
системный
вызов был
прерван
сигналом.
В случае
ошибки
возвращается
-1, а
errno
устанавливается
в значение
ошибки.
- EAGAIN
- Запрошенное
количество
энтропии
недоступно,
и getrandom()
заблокировался
бы, если бы
отсутствовал
флаг GRND_NONBLOCK.
- EFAULT
- Адрес,
указанный
в buf, лежит
вне
доступного
адресного
пространства.
- EINTR
- Вызов
был
прерван
обработчиком
сигнала;
смотрите
описание о
прерывании
вызовов read(2)
при работе
с
«медленными»
устройствами
и при
отсутствии
флага SA_RESTART в
справочной
странице
signal(7).
- EINVAL
- В flags
указан
неверный
флаг.
- ENOSYS
- Обёрточная
функция в glibc
для getrandom()
определила,
что
используемое
ядро не
поддерживает
данный
системный
вызов.
getrandom() was introduced in Linux 3.17. Support was added in glibc
2.25.
Данный
вызов есть
только в Linux.
Обзор и
сравнение
возможных
интерфейсов,
через
которые
можно
получать
случайные
данные,
смотрите в
random(7).
В отличие
от
/dev/random и
/dev/urandom, в
вызове
getrandom()
не
используются
пути или
файловые
дескрипторы.
Таким
образом,
getrandom()
полезен в
случаях,
когда
chroot(2)
делает
пути
/dev
невидимыми
и
приложение
(например,
служба во
время
загрузки)
закрывает
файловый
дескриптор
одного из
этих
файлов,
которые
были
открыты
библиотекой.
На момент Linux 3.19
существуют
следующие
ограничения:
- •
- When reading from the urandom source, a maximum of
32Mi-1 bytes is returned by a single call to getrandom() on systems
where int has a size of 32 bits.
- •
- При
чтении из
источника
random
возвращается
максимум 512
байт.
При чтении
из
источника
urandom (
GRND_RANDOM не
указан),
getrandom()
блокируется
до тех пор,
пока не
специализируется
пул
энтропии
(если не
указан
флаг
GRND_NONBLOCK).
Если
запрос
требует
большого
количества
байт
(больше 256),
getrandom()
будет
заблокирован
до тех пор,
пока байты
не будут
сгенерированы
и переданы
из памяти
ядра в
buf. При
чтении из
random (указан
GRND_RANDOM),
getrandom()
будет
заблокирован
до тех пор,
пока
какое-то
количество
произвольных
байт не
станет
доступно
(если не
указан
флаг
GRND_NONBLOCK).
Поведение
при
прерывании
обработчиком
сигнала
вызова
getrandom(),
заблокированного
чтением
источника
urandom, зависит
от
состояния
инициализации
буфера
энтропии и
от
запрашиваемого
объёма
buflen.
Если
энтропия
ещё не
инициализирована,
то вызов
завершается
ошибкой
EINTR.
Если пул
энтропии
инициализирован
и
запрашиваемый
объём
большой (
buflen > 256), то
вызов или
завершится
успешно,
вернув
частично
заполненный
буфер, или
завершится
с ошибкой
EINTR. Если пул
энтропии
инициализирован
и
запрашиваемый
объём мал (
buflen <= 256), то
getrandom()
завершится
без ошибки
EINTR. Вместо
этого, он
вернёт все
запрашиваемый
байты.
При чтении
из
источника
random
блокирующие
запросы на
любой
объём
могут быть
прерваны
обработчиком
сигналом
(вызов
завершается
с ошибкой
EINTR).
Использование
getrandom() для
чтения
маленьких
буферов (<= 256
байт) из
источника
urandom —
предпочтительный
способ
использования.
Специальный
режим для
маленького
объёма
buflen
был
разработан
для
совместимости
с
системным
вызовом
getentropy(3)
из OpenBSD,
который
теперь
поддерживается
glibc.
Пользователь
getrandom() всегда
должен
проверять
возвращаемое
значение,
чтобы
определить
что
возникла
ошибка или
возвращено
меньшее
количество
запрошенных
байт. В
случае
когда флаг
GRND_RANDOM не
указан и
значение
buflen
меньше или
равно 256,
возврат
меньшего
количества
байт чем
запрошено
никогда не
происходит,
но
осторожный
программист
всегда
проверяет
значение!
В Linux 3.19
существуют
следующие
дефекты:
- •
- В
зависимости
от
загруженности
ЦП, getrandom() не
реагирует
на
прерывания,
пока не
прочитает
все
запрашиваемые
байты.
getentropy(3),
random(4),
urandom(4),
random(7),
signal(7)
Русский
перевод
этой
страницы
руководства
был сделан
Azamat Hackimov <
[email protected]>, Dmitry Bolkhovskikh
<
[email protected]>, Vladislav <
[email protected]>,
Yuri Kozlov <
[email protected]> и
Иван
Павлов <
[email protected]>
Этот
перевод
является
бесплатной
документацией;
прочитайте
Стандартную
общественную
лицензию GNU
версии 3
или более
позднюю,
чтобы
узнать об
условиях
авторского
права. Мы не
несем
НИКАКОЙ
ОТВЕТСТВЕННОСТИ.
Если вы
обнаружите
ошибки в
переводе
этой
страницы
руководства,
пожалуйста,
отправьте
электронное
письмо на
[email protected]