使用本机C代码递归复制目录

时间:2017-05-24 10:05:37

标签: c linux

我希望实现Linux命令cp -Rf <src_dir>/* <dst_dir>的行为,它复制了&#39; src_dir&#39;中的所有内容。进入&#39; dst_dir&#39;递归地

我在网上寻求帮助并得到了一些解决方案,但他们做了以下任何我不想做的事情:

  1. 使用rename(src_dir, dst_dir),它基本上会移动&#39;内容而不是副本。 我需要保留&#39; src_dir&#39;的内容。完整。

  2. 打开以阅读&#39; src_dir&#39;中的每个文件。 我想这样做,无需打开文件和阅读内容。

  3. 使用C而不使用system("cp -Rf <src_dir>/* <dst_dir>")可以实现上述目标吗?

    (从最初的评论中得知最初的lang令人困惑之后,编辑了原始问题)

1 个答案:

答案 0 :(得分:2)

  

我当时想要实现linux系统命令的行为

     

1)cp将'src_dir'中的所有内容递归复制到'dst_dir',

  

使用C(并且没有linux系统调用)可以实现上述目标吗?

当然不是;请记住,system call是应用程序与Linux内核交互的主要方式:查看syscalls(2)以获取详尽的系统调用列表(您可能需要stat(2) ...) 。不要将系统调用与对C库system(3)函数的调用混淆(使用fork(2)execve(2)waitpid(2)等等。)

但是,您可能对nftw(3)感兴趣(当然,这是在多个系统调用之上实现的)。再看opendir(3)&amp; readdir(3)

如果不通过系统调用,您无法在文件系统上进行任何更改。

附加物

(问题已变为)

  

上述是否可以在不使用系统的情况下使用C实现(“cp -Rf / *”)?

是;您可以先使用nftw(3)扫描文件树(或使用readdir(3)等进行适当的播放...),然后检测要制作的目录(使用mkdir(2) ...);您将适当地制作目录并明确复制文件内容(例如使用stdio(3)函数或open(2)read(2)write(2)close(2)系统调用....)。请注意,open(2)(由fopen(3) ...调用)需要从文件中读取或写入任何内容(即使使用mmap(2) ...)当然,要复制文件,你需要打开它,打开它的新副本,读取它并在循环中写入副本,并关闭源文件和目标文件。但是,一旦完成复制,您应该关闭(源文件和目标文件)。顺便说一下,给定的process可能有数百(或数千)个打开的文件描述符(参见setrlimit(2) ...),而opendir(3)也会消耗一个。

(您打开的文件描述符的数量(大多数是目录,opendir(3))受文件树深度的限制,因此实际上可能很小,不到一百;并且使用聪明的使用nftw(3)缓存甚至可以避免这种情况)

BTW,cp是GNU coreutils的一部分free software,因此您可以研究其源代码。您也可以使用strace(1)来了解cp正在做什么。

阅读Advanced Linux ProgrammingOperating System : Three Easy Pieces(两者都可免费下载,PDF格式的章节)

无法使用单个system call复制一个文件的内容。你需要一个循环。但另请参阅我不推荐的Linux特定copy_file_range(2),更好地循环POSIX read(2)write(2)