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?
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.
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.
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.
When talking about "copying a file", two semantics exist:
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With