Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a POSIX function to copy a file? [closed]

Tags:

c

posix

Looking now through some OS functions I find that on POSIX systems you have C function calls like unlink() to remove files, link() to create hard links to files, symlink() to create symbolic files, rename() to move a file, but ... where is a function to copy() a file?

I know that the usual way is to just open the source file, read its contents, open a destination file and dump them there. But why can't I find any such utility function given all the previous ones?

like image 315
Grzegorz Adam Hankiewicz Avatar asked Jul 16 '13 00:07

Grzegorz Adam Hankiewicz


People also ask

How copy AC file in Linux?

To copy files and directories use the cp command under a Linux, UNIX-like, and BSD like operating systems. cp is the command entered in a Unix and Linux shell to copy a file from one place to another, possibly on a different filesystem.

Which commands can be used to copy a file?

Use the cp command to create a copy of the contents of the file or directory specified by the SourceFile or SourceDirectory parameters into the file or directory specified by the TargetFile or TargetDirectory parameters.

How do you copy a file in Linux?

To copy a file, specify “cp” followed by the name of a file to copy. Then, state the location at which the new file should appear. The new file does not need to have the same name as the one you are copying. The “source” refers to the file or folder you want to move.


1 Answers

When talking about "copying a file", two semantics exist:

  1. Deep Copy - the creation of a new file containing a copy of all data / metadata associated with the file, however the filesystem structures this
  2. Shallow Copy - the creation of a new directory entry/file referring to the same data (and possible some or all of the metadata) as the source file

Windows / DOS filesystems traditionally didn't have any "shallow copy" mechanism - but UN*X always had, in the form of hard links.

So POSIX/UN*X has the link(2) system call - to establish a new reference to existing "file data" under a new name - i.e., do a shallow copy.

A "deep copy" system call only makes sense if there is a "fast deep copy" mechanism - for example, in cases where the underlaying filesystem implements something like deduplucation to do file-level cloning.

Otherwise, such a function would have to "degrade" (fall back to) a library implementation.

The UN*X mechanism to allow for something as filesystem-specific as this is ioctl(), the "kitchen sink of I/O extensibility". For an example as how to use this facility, if available, to copy files, see this GNU coreutils post with an enhancement request to use file cloning on BTRFS.

Given that Windows' CopyFile is actually CopyFileEx without a callback, I strongly doubt it's really a system call; it's a utility function. For the Wine Windows Emulator, you can check the kernel32.dll source implementation, find CopyFileEx in the Wine sources, dlls/kernel32/path.c for an example how this can be done.
Disassembling / Decompiling Windows' actual kernel.dll is not allowed under Microsoft's licensing, so I cannot legally assert that Windows itself does the same, i.e. CopyFile is a userland implementation, not a system call.

To compare Windows and UN*X again here... not everything in UN*X libc is a system call, that's why the UN*X manpages distinguish between section 2 (sys calls) and section 3 (runtime library interfaces). The same is true for functions in kernel.dll on Windows - some of them are "direct passthrough" while others are more complex "utility functions" not implemented via a single system call.

like image 78
FrankH. Avatar answered Sep 26 '22 09:09

FrankH.