UP | HOME

File System (fs) Project
COP-3402

Table of Contents

1. Overview

In this project, you will implement a variation of the cp command called mycp.

2. Input

USAGE: ./mycp source_file target_file

The program should be called mycp. It takes two arguments: source_file is an existing, regular file; and target_file is either an existing file or a non-existent file but in an existing directory. The source and destination should not be the same file.

3. Input validation

Report errors via exit codes passed to the exit library call, e.g., exit(5) terminates the program with exit code 1.

Error messages are optional, but should only be written to stderr, not to stdout, which will be used for program output, i.e., use fprintf(stderr, ...) instead of printf.

3.1. Number of arguments

Exit with exit code 3 if there are not two arguments (remember that argc will be 3, since it includes the name of the program itself). A useful error message is to print the usage instructions, e.g.,

fprintf(stderr, "USAGE: ./mvplus source_file target_file\n");

3.2. Source file

Exit with exit code 4 if source_file does not exist or cannot be opened for any other reason, i.e., if stat fails.

Exit with exit code 5 if source_file is not a regular file, i.e., check that (statbuf.st_mode & S_IFMT) is S_IFREG, where statbuf is the result of the call to stat.

3.3. Syscall Errors

For any other system calls that fail, use exit code EXIT_FAILURE, which is defined in stdlib.h.

3.4. Exit code precedence

If an input violates multiple exit codes, only the lowest-numbered exit code should be produced. Consider EXIT_FAILURE to be the lowest-numbered exit code.

3.5. Checking for the same file

It is not required to check that the source and destination are the same file, thought it may be one part of a bonus project extension. What can we look at to see whether two paths are referring to the same file (same as determined by the file system)?

4. Output

When running successfully, the program should exit with the success exit code (0 or EXIT_SUCCESS), which is the default exit code returned by main. The destination file should be a different file that has the exact same byte contents as the source file. If the destination file exists, it should be overwritten. If it doesn't exist, then it should be created. No directories should be created; it is an error if the destination file is in a non-existent directory.

5. System call and library references

Do not use helper libraries or other simplified calls to achieve similar results as functions below. Just use the syscalls below for these aspects of the project.

Symbol Reference Reading
stat() man 2 stat LPI 15.1
struct stat man 2 stat  
st_mode man 7 inode  
open() man 2 open LPI 4.1
read() man 2 read  
write() man 2 write  
close() man 2 close  
perror() man 3 perror LPI 3.4
exit(EXIT_FAILURE) man 3 exit  
  • man is the command-line manual.
  • LPI is The Linux Program Interface book.
  • Knowledge of memory management and string processing is assumed.

6. Building and running the tool

Create a Makefile that will build your project and give the resulting program the name mycp. See the hello project for an example Makefile.

Your project must be buildable with make and runnable with ./mycp, both from the root of your repo, i.e.,

make
./mycp

Automated grading will build and run your tool this way and only this way.

7. Submitting your project

7.1. git setup

Be sure to complete the git exercise before attempting this project.

Create a new local repository, following the directions in the git exercise (including the git --set-upstream last step) and set the local and remote repository URLs to be the following locations:

Local repository ~/cop3402spring25/fs
Remote repository gitolite3@eustis3.eecs.ucf.edu:cop3402/$USER/fs

7.2. Self-check

See the hello project for instructions on cloning a project from the grading server.

8. Grading

The test cases used to grade the project are listed below. Scripts to run the the odd-numbered test cases are provided publicly, while the even-numbered test cases are private.

To use the automated tests, first download them, e.g.,

cd ~/cop3402spring25/fs
wget https://www.cs.ucf.edu/~gazzillo/teaching/cop3402spring25/files/fs_public_tests.tar
tar -xvf fs_public_tests.tar

To run a test case, e.g., tests/03-threeargs.sh, use the following bash command from the root of your local repository directory:

bash tests/03-threeargs.sh $(readlink -f mycp)

This runs the bash script, passing in the absolute path to your program, which is what $(readlink -f mycp) does.

8.1. Test cases

# Short Name Description Expected Output
1 noargs Call mycp with no arguments. It should fail with the appropriate exit code.
2 onearg Call mycp with one argument. It should fail with the appropriate exit code.
3 threeargs Call mycp with three arguments. It should fail with the appropriate exit code.
4 missingsource Call mycp with a source file that does not exist. It should fail with the appropriate exit code.
5 dirsource Pass a directory as the source file. It should fail with the appropriate exit code.
6 destdirnotexist The source file exists but the destination file is in a directory that does not exist. It should fail with the appropriate exit code for a failed syscall.
7 destisdir Use a directory as the target file. It should fail with the appropriate exit code.
8 emptysourcedest The source and destination files both exist and are empty. After running, the destination file should exist.
9 sourceemptydestnotexist Use an empty source file and provide a destination file that does not exist but will be in an existing directory. After running, the destination file should exist and be empty.
10 sourcedestnotexist The source exists and is non-empty, but the destination does not exist (but is targeting an existing directory). After running, the destination file should exist and contain the contents of the source file.
11 sourcedestexistshorter The source file exists and is non-empty and the destination exists and contains fewer bytes than the source. After running, the destination should exist and contain the exact contents of the source file.
12 sourcedestexistlonger The source file exists and is non-empty and the destination exists, is non-empty, and is longer than the source file. After running, the destination should exist and contain only the contents of the source file (none of the contents of the destination file).
13 sourcedestdirexistlonger The source is an existing file and the destination file is in a different directory and is larger than the destination file. After running, the destination should exist and contain the exact contents of the source file.

9. Bonus project ideas

  • Create a version of the copy that avoids a race condition where a component of the target path is changed during the open. See the manpages for open(2) and openat2(2)
  • If the directory (or directories) in the target file do not exist, create them first.
  • Add a command-line flag that provides an option to avoid overwriting an existing file or other features similar to cp's -i, -u, or -n. See the manpage for cp(1).
  • Come up with your own extension or change and propose it.

10. Grading schema

Criterion Points
The git repo exists 1
The program is written, builds, and runs as described here 1
Tests pass, prorated by the number of test cases passing 6
TOTAL 8

Author: Paul Gazzillo

Created: 2025-02-10 Mon 11:29

Validate