/bin/cp 如何处理块设备?

/bin/cp 如何处理块设备?

当使用/bin/cp source_file destination_file, 并且参数之一是块特殊的。

答案1

  • 当源文件是常规文件且目标块设备时(并且当没有 -i 命令行开关或从 -i 获得肯定性时),POSIX 表示 [1] 目标应使用 O_WRONLY|O_TRUNC 进行 open()ed,并且所写源码的内容。 POSIX 说 [2],使用 O_TRUNC open()ed 的块设备的行为(以及其他特殊情况)是实现定义的,根据我的经验,通常从头开始覆盖,如果源是,则其余部分保持不变。较小。 GNU cp 另外还有 --remove-destination 命令行开关,当源文件是常规文件且目标块设备时,它会首先 unlink() 目标,然后在其位置创建一个常规文件。

  • 当源文件是块设备并且使用 -R 命令行开关时,POSIX 表示应使用与源相同的文件类型创建目标。这通常是 mknod() 具有相应的主要:次要目的地。

  • 现在棘手的部分是,当源文件是块设备并且没有 -R 时,POSIX 似乎忽略了这一点。 FreeBSD 实现 [4] 将 open() 目的地并写入内容。相比之下,GNU [3] 将默认使用 mknod() 目标,或者,如果使用 --copy-contents,则 open() 并写入内容。


[1] cp.1posix,POSIX.1-2017 壳牌与公用事业https://pubs.opengroup.org/onlinepubs/9699919799/utilities/cp.html

[2] open.3posix

[3] cp,GNU Coreutilshttps://www.gnu.org/software/coreutils/manual/html_node/cp-inspiration.html

'-R' '-r' '--recursive' (...) 通过创建与源文件类型相同的目标文件来复制特殊文件;请参阅 --copy-contents 选项。

该文本位于“info”格式文档中,但不在“man”中。

[4] freebsd 发行版/12.1.0https://github.com/freebsd/freebsd/blob/release/12.1.0/bin/cp/cp.c#L461

        case S_IFBLK:
        case S_IFCHR:
            if (Rflag && !sflag) {
                if (copy_special(curr->fts_statp, !dne))
                    badcp = rval = 1;
            } else {
                if (copy_file(curr, dne))
                    badcp = rval = 1;
            }

int copy_special()int copy_file()在 bin/cp/utils.c 中定义。一个 mknod(),另一个 open() 并写入内容。


toybox(bsd 许可的 busybox 多呼叫替代品,随 android 一起提供)似乎总是在编写内容。也许我稍后会对此进行更多调查。

相关内容