Работая над проектом, который читает /dev/urandom
для генерации случайных байтов было предложено проверить, чтобы убедиться, что /dev/urandom
это устройство, а не просто файл.
Наиболее простой способ выглядит примерно так:
/**
* Is the given file a device?
*
* @param string|resource $file
* @return boolean
*/
function is_device($file)
{
if (is_resource($file)) {
$stat = fstat($file);
} elseif (is_readable($file) && !is_link($file)) {
$stat = stat($file);
} else {
return false;
}
return $stat['rdev'] !== 0;
}
У меня вопрос двоякий:
$stat['rdev'] !== 0
проверка может провалиться?Важный: Решение, которое мне нужно, должно быть на PHP без зависимости от каких-либо расширений PECL или пользовательского кода C. Проект чистый PHP 5 polyfill из PHP 7 random_bytes()
а также random_int()
функции и предназначен для установки в других проектах PHP 5 Composer.
ну, вы можете использовать filetype ().
если вы сделаете быстрый лл на urandom, вы увидите:
ll /dev/urandom
crw-rw-rw- 1 root root 1, 9 Jul 26 17:38 /dev/urandom
«c» в начале означает, что это «символьный» тип файла. Вы можете проверить все различные типы файлов здесь:
https://en.wikipedia.org/wiki/Unix_file_types
это означает, что если вы запустите
filetype("/dev/urandom");
вы получите «char» назад, что означает тип файла символа. тот должен сделать трюк.
Обновить
Мое оригинальное решение оказалось просто повторной реализацией filetype($filepath) === 'char'
, так filetype()
кажется, единственное, что вам нужно.
Основываясь на ответе @ frymaster …
Я посмотрел на то, как PHP stat()
функция работает, искал «char» и нашел этот.
В сочетании с руководством stat (2) для обоих Linux а также FreeBSD, также как и прокомментируйте руководство по PHP для stat (), Я придумал следующее:
функция is_device ($ filepath) { if (! file_exists ($ filepath) ИЛИ (stripos (PHP_OS, 'Linux') === false stripos (PHP_OS, 'BSD') === false)) { вернуть ложь; } $ mode = stat ($ filepath) ['mode']; возврат (020000 === ($ mode) 0170000)); }
Работает в моей системе Linux.
Обновление (чтобы ответить на второй вопрос)
Да, stat($file)['rdev'] !== 0
может потерпеть неудачу. Из того, что я обнаружил, он может вернуть -1, если не поддерживается ОС, в то время как даже положительное значение может указывать на другой тип устройства. Его значения также зависят от ОС.