Как гарантировать, что указанный файл является устройством на BSD / Linux из PHP?

Работая над проектом, который читает /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;
}

У меня вопрос двоякий:

  1. Это лучший способ проверить, является ли этот файл устройством?
  2. Есть ли обстоятельства, когда это $stat['rdev'] !== 0 проверка может провалиться?

Важный: Решение, которое мне нужно, должно быть на PHP без зависимости от каких-либо расширений PECL или пользовательского кода C. Проект чистый PHP 5 polyfill из PHP 7 random_bytes() а также random_int() функции и предназначен для установки в других проектах PHP 5 Composer.

14

Решение

ну, вы можете использовать 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» назад, что означает тип файла символа. тот должен сделать трюк.

4

Другие решения

Обновить

Мое оригинальное решение оказалось просто повторной реализацией 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, если не поддерживается ОС, в то время как даже положительное значение может указывать на другой тип устройства. Его значения также зависят от ОС.

2

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector