ИМЯ getrandom - возвращает серию произвольных байт
ОБЗОР #include <sys/random.h>
ssize_t getrandom(void *buf, 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() заблокировался
ENOSYS Обёрточная функция в glibc для getrandom() определила, что используемое ядро не поддерживает данный системный вызов.
ВЕРСИИ Вызов getrandom() появился в версии ядра Linux 3.17. Поддержка в glibc добавлена в версии 2.5.
СООТВЕТСТВИЕ СТАНДАРТАМ Данный вызов есть только в Linux.
ЗАМЕЧАНИЯ Обзор и сравнение возможных интерфейсов, через которые можно получать случайные данные, смотрите в random(7).
В отличие от /dev/random и /dev/urandom, в вызове getrandom() не используются пути или файловые дескрипторы. Таким образом, getrandom() полезен в случаях, когда chroot(2) делает пути /dev невидимыми и приложение (например, служба во время загрузки) закрывает файловый дескриптор одного из этих файлов, которые были открыты библиотекой.
Возвращается максимальное количество байтов На момент Linux 3.19 существуют следующие ограничения:
* При чтении из источника urandom в системах, где размер int равен 32 битам, один вызов getrandom() возвращает максимум 33554431 байт.
* При чтении из источника random возвращается максимум 512 байт.
Прерывание обработчиком сигнала При чтении из источника urandom (GRND_RANDOM не указан), getrandom() блокируется до тех пор, пока не специализируется пул энтропии (если не указан флаг GRND_NONBLOCK). Если запрос требует большого количества байт (больше 256), getrandom() будет заблокирован до тех пор, пока байты не будут сгенерированы и переданы из памяти ядра в buf. При чтении из random (указан GRND_RANDOM), getrandom() будет заблокирован до тех пор, пока какое-то количество произвольных байт не станет доступно (если не указан флаг GRND_NONBLOCK).
Что происходит когда вызов блокированный чтением источника urandom вызов getrandom() прерывается обработчиком сигнала зависит от состояния инициализации буфера энтропии и от запрашиваемого объёма buflen. Если энтропия ещё не инициализирована, то вызов завершится с ошибкой EINTR. Если пул энтропии инициализирован и запрашиваемый объём большой (buflen > 256), то вызов или завершится успешно, вернув частично заполненный буфер, или завершится с ошибкой EINTR. Если пул энтропии инициализирован и запрашиваемый объём мал (buflen <= 256), то getrandom() завершится без ошибки EINTR. Вместо этого, он вернёт все запрашиваемый байты.
При чтении из источника random блокирующие запросы на любой объём могут быть прерваны обработчиком сигналом (вызов завершается с ошибкой EINTR).
Использование getrandom() для чтения маленьких буферов (<= 256 байт) из источника urandom — предпочтительный способ использования.
Специальный режим для маленького объёма buflen был разработан для совместимости с системным вызовом getentropy(3) из OpenBSD, который теперь поддерживается glibc.
* В зависимости от загруженности ЦП, getrandom() не реагирует на прерывания, пока не прочитает все запрашиваемые байты.
СМОТРИТЕ ТАКЖЕ getentropy(3), random(4), urandom(4), random(7), signal(7)
|