Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/280.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何保证指定的文件是来自PHP的BSD/Linux设备?_Php_Linux_File Io_Filesystems_Bsd - Fatal编程技术网

如何保证指定的文件是来自PHP的BSD/Linux设备?

如何保证指定的文件是来自PHP的BSD/Linux设备?,php,linux,file-io,filesystems,bsd,Php,Linux,File Io,Filesystems,Bsd,在处理从/dev/uradom读取以生成随机字节的项目时,建议我检查以确保/dev/uradom不仅仅是一个文件,而是一个设备 最直接的方法似乎是: /** * Is the given file a device? * * @param string|resource $file * @return boolean */ function is_device($file) { if (is_resource($file)) { $stat = fstat($

在处理从
/dev/uradom
读取以生成随机字节的项目时,建议我检查以确保
/dev/uradom
不仅仅是一个文件,而是一个设备

最直接的方法似乎是:

/**
 * 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代码。Composer可以在任何其他人的PHP5项目中安装该项目。

    您可以使用filetype()

    如果您对urandom进行快速ll,您将看到:

    ll /dev/urandom 
    crw-rw-rw- 1 root root 1, 9 Jul 26 17:38 /dev/urandom
    
    开头的“c”表示它是一个“字符”文件类型。您可以在此处查看所有不同的文件类型:

    这意味着如果你跑步

    filetype("/dev/urandom");
    

    您将返回“char”,意思是字符文件类型。这应该可以解决问题。

    更新

    我最初的解决方案只是重新实现了
    filetype($filepath)==“char”
    ,因此
    filetype()
    似乎是您唯一需要的


    根据@frymaster的回答

    我查看了PHP的
    stat()
    函数的工作原理,查找“char”并找到了它

    结合and和a的stat(2)手册,我得出以下结论:

    function is_device($filepath) { if ( ! file_exists($filepath) OR (stripos(PHP_OS, 'Linux') === false && stripos(PHP_OS, 'BSD') === false)) { return false; } $mode = stat($filepath)['mode']; return (020000 === ($mode & 0170000)); } 函数是\u设备($filepath) { 如果(!file_存在($filepath)或(stripos(PHP_OS,'Linux')==false&&stripos(PHP_OS,'BSD')==false)) { 返回false; } $mode=stat($filepath)['mode']; 返回(020000==($mode&0170000)); } 在我的Linux系统上工作

    更新(回答第二个问题)


    是,
    stat($file)['rdev']!=0
    可能会失败。根据我的发现,如果操作系统不支持,它可能返回-1,而即使是正值也可能指向不同的设备类型。它的值似乎也依赖于操作系统。

    “您应该花时间研究openssl_random_pseudo_bytes()。”。所讨论的项目是PHP7的
    random_bytes()
    random_int()
    函数的polyfill。我目前的非正式立场是,“TOCTOU问题和文件描述符耗尽攻击超出范围。如果您的文件系统被破坏,您的PHP web应用程序将无法拯救您。”libsodum似乎做了一些非常类似的事情:这就是
    filetype()
    返回“char”时所做的事情:)刚刚更新了答案。。。这与@frymaster所说的非常相似。不客气。:)我也这么做了——我以前不知道这些,事实上也不知道PHP有一个
    filetype()
    函数,还以为你在谈论别的东西。然而,从你的答案中提取了另一条线索,并将其作为一个完整的循环——集体思考在工作中!:D