Implement the Linux cp Command, Then Explain Its OS and C++ Internals
Company: Microsoft
Role: Software Engineer
Category: Software Engineering Fundamentals
Difficulty: medium
Interview Round: Onsite
How would you implement the Linux `cp` command? Write it, then be ready for the discussion to go deep into the operating-system and C++ concepts underneath your implementation.
### Clarifying Questions
- Which interfaces may I use: POSIX system calls, the C standard library, or C++17 `std::filesystem`?
- Should the first version handle only regular files, or also directories (`-r`), symbolic links and special files?
- If DEST already exists, should it be overwritten silently, or should the program ask or fail?
- Must permissions, ownership and timestamps be preserved, as `cp -p` does?
### Part 1 — Implement the basic copy
Write a C++ program, invoked as `cp SOURCE DEST`, that copies a regular file. DEST may be a new path, an existing file, or an existing directory. Handle the errors a real command-line tool has to handle, and exit with a non-zero status on failure.
```hint Think in system calls
Decide which calls you need to open, read, write and close the files, and what each one can return besides full success.
```
```hint Look closely at DEST before writing to it
DEST may already exist, may be a directory, or may even be SOURCE itself under another name.
```
#### What This Part Should Cover
- A correct copy loop, including partial writes, interrupted calls and end of file
- Handling of an existing file, a directory target, and SOURCE and DEST being the same file
- Clear error messages and release of every resource on every path
### Part 2 — What happens underneath
Walk through what the operating system does while your program runs: from each system call into the kernel, through the file system and its caches, down to the disk. Then explain how you would make the copy faster for very large files.
```hint Count the copies and the crossings
Follow one block of data and count how many times it crosses between user space and the kernel, and how many times it is copied in memory.
```
```hint Ask whether your program needs the bytes at all
Consider what the kernel or the file system could do if the data never had to pass through your buffer.
```
#### What This Part Should Cover
- User space and kernel space, the cost of a system call, and the effect of the buffer size
- The page cache, read-ahead and write-back, and what a successful `write` actually guarantees
- Kernel-assisted copying and when each option applies or falls back
### Part 3 — Make it robust C++
Now treat the code as production C++. How do you guarantee that file descriptors are always released and that errors are reported correctly? What would it take to support directories, symbolic links and preserving metadata, and to avoid leaving a half-written DEST behind when the copy fails?
```hint Let object lifetime do the cleanup
Think about tying the release of a descriptor to the end of an object's lifetime, and what copying such an object should mean.
```
```hint Decide what a failure leaves behind
If the copy fails halfway, think about what the user finds at DEST afterwards.
```
#### What This Part Should Cover
- Descriptor ownership through RAII, including copy and move semantics
- An error model (exceptions or error codes) and when `errno` must be read
- Recursive copy, symbolic links, metadata, and never leaving a half-written file behind
### What a Strong Answer Covers
- Working code that is correct on the error paths, not only the happy path
- Accurate operating-system mechanics tied to the performance choices in the code
- Sound C++ resource management
- Explicit trade-offs, such as portability against speed and in-place overwrite against atomic replacement
### Follow-up Questions
- How would you make the new DEST appear atomically to other processes reading it?
- How do you copy a sparse file without filling its holes with zeros?
- What does your program produce if another process is writing to SOURCE during the copy?
- How does moving a file differ from copying it when the source and destination are on the same file system, and when they are not?
Overview: A low-level engineering exercise to implement the Linux cp command in C++ and then explain what happens beneath it. It tests system calls, short writes and error handling, the page cache and kernel-assisted copying, and RAII-based management of file descriptors.