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

把友情*_*在无盐 1 cp

使用时/bin/cp source_file destination_file,其中一个参数是块特殊的。

把友情*_*在无盐 6

  • 当源文件是常规文件和目标块设备时(并且当没有 -i 命令行开关时,或者从 -i 得到了亲和),POSIX 说 [1] 目标应该用 O_WRONLY|O_TRUNC 打开(),并且写的源内容。并且 POSIX 说 [2] 使用 O_TRUNC open() 的块设备(以及其他特殊设备)的行为是实现定义的,根据我的经验,通常从头开始覆盖,如果源是较小。GNU cp 还具有 --remove-destination 命令行开关,当源文件是常规文件和目标块设备时,它将首先 unlink() 目标,然后在其位置创建一个常规文件。

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

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


[1] cp.1posix, POSIX.1-2017 Shell & Utilities https://pubs.opengroup.org/onlinepubs/9699919799/utilities/cp.html

[2] open.3posix

[3] cp,GNU Coreutils https://www.gnu.org/software/coreutils/manual/html_node/cp-invocation.html

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

此文本在“info”格式的文档中,但不在“man”中。

[4] freebsd release/12.1.0 https://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;
            }
Run Code Online (Sandbox Code Playgroud)

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


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