Soft links are not preserved while copying the files using C++ and directories recursively from one directory to another

68 Views Asked by At

I am using below code to copy files, directories, soft links, hard links from one directory to another.

#include <fstream>
#include <filesystem>
#include <iostream>

namespace fs = std::filesystem;

//function copy files
void cpFile(const fs::path & srcPath,
  const fs::path & dstPath) {

  std::ifstream srcFile(srcPath, std::ios::binary);
  std::ofstream dstFile(dstPath, std::ios::binary);

  if (!srcFile || !dstFile) {
    std::cout << "Failed to get the file." << std::endl;
    return;
  }

  dstFile << srcFile.rdbuf();

  srcFile.close();
  dstFile.close();
}

//function create new directory
void cpDirectory(const fs::path & srcPath,
  const fs::path & dstPath) {

  fs::create_directories(dstPath);

  for (const auto & entry: fs::directory_iterator(srcPath)) {
    const fs::path & srcFilePath = entry.path();
    const fs::path & dstFilePath = dstPath / srcFilePath.filename();
    //if directory then create new folder
    if (fs::is_directory(srcFilePath)) {
      cpDirectory(srcFilePath, dstFilePath);
    } else {
      cpFile(srcFilePath, dstFilePath);
    }
  }
}

int main(int argc, char *argv[]) {

  const auto root = fs::current_path();
  const fs::path srcPath = argv[1];
  const fs::path dstPath = argv[2];

  // Copy only those files which contain "Sub" in their stem.
  cpDirectory(srcPath, dstPath);

  return 0;

}

Below is content of src directory:

$ ls -ltr a/
    total 4
    -rw-rw-r-- 1 ubuntu ubuntu    0 Sep 30 19:58 test.txt
    -rw-rw-r-- 1 ubuntu ubuntu    0 Oct  1 18:12 d.txt
    lrwxrwxrwx 1 root   root      5 Oct  1 18:12 linkd -> d.txt
    drwxrwxr-x 2 ubuntu ubuntu 4096 Oct  1 18:21 testd

When i run the code:

$ ./copyRec a/ e/

Below is the content of dst directory:

$ls -ltr e/
total 4
drwxrwxr-x 2 ubuntu ubuntu 4096 Oct  1 18:21 testd
-rw-rw-r-- 1 ubuntu ubuntu    0 Oct  1 18:38 test.txt
-rw-rw-r-- 1 ubuntu ubuntu    0 Oct  1 18:38 linkd
-rw-rw-r-- 1 ubuntu ubuntu    0 Oct  1 18:38 d.txt

Where linkd is a soft link to d.txt but it is not preserved and is shown as a regular file. Please help.

1

There are 1 best solutions below

0
Sam Varshavchik On

You must take specific action in order to preserve symbolic links. The filesystem library will not do it for you.

   if (fs::is_directory(srcFilePath)) {

You already know how to use is_directory. If you go back and look at your C++ reference or textbook where you learned about is_directory, you will also find a description of is_symlink which checks whether the given entry is a symbolic link.

Then, you will need to use read_symlink to read the symlink, and create_symlink to recreate it.