.. ot-exercise:: linux.sysprog.fileio.basics_exercise_copy :dependencies: linux.sysprog.fileio.basics, linux.sysprog.basics.errorhandling, linux.basics.permissions.basics Exercise: Copy A File ===================== .. contents:: :local: Requirement ----------- .. sidebar:: **Topics** * The Whole Truth About ``open()`` * :doc:`/trainings/material/soup/linux/sysprog/file-io/basics` * :doc:`/trainings/material/soup/linux/sysprog/file-io/example-O_RDONLY` * :doc:`/trainings/material/soup/linux/sysprog/file-io/example-O_WRONLY` * :doc:`/trainings/material/soup/linux/sysprog/file-io/example-O_CREAT` * :doc:`/trainings/material/soup/linux/sysprog/file-io/example-O_EXCL` * :doc:`/trainings/material/soup/linux/sysprog/process/commandline` * :doc:`/trainings/material/soup/linux/sysprog/basics/errorhandling` * :doc:`/trainings/material/soup/linux/basics/permissions/basics` **Manual Pages** * File I/O * `man -s 2 open `__ * `man -s 2 read `__ * `man -s 2 write `__ * `man -s 2 close `__ * Miscellaneous * `man -s 3 errno `__ * `man -s 3 strerror `__ Write a program ``cp-for-the-poor`` which exhibits the following behavior: .. list-table:: :align: left :widths: 1, 2 * * *Requirement 1* * It interprets its two arguments as filenames, and copies the first to the second * * *Requirement 2* * The first filename must be an existing file * * *Requirement 3* * The second filename is the target of the copy * * *Requirement 4* * No existing file must be overwritten * * *Requirement 5* * *The program operates at the system call layer*. Use ``open()``/``read()``/``write()``/``close()``, and *not* anything from ````. .. note:: * Check for system call errors; see :doc:`/trainings/material/soup/linux/sysprog/basics/errorhandling` for how to. * Make sure the program interprets its commandline correctly; see :doc:`/trainings/material/soup/linux/sysprog/process/commandline` for how to. * Make sure the program returns exit statuses as specified below; see :doc:`/trainings/material/soup/linux/sysprog/process/commandline` for how to. Sunny Case: Source File Exists, Destination Does Not Exist .......................................................... .. code-block:: console $ ./cp-for-the-poor /etc/passwd /tmp/passwd-copy $ echo $? 0 Error: Wrong Number Of Arguments Specified .......................................... .. code-block:: console $ ./cp-for-the-poor ./cp-for-the-poor: SRCFILE DSTFILE $ echo $? 1 Error: Source File Does Not Exist ................................. .. code-block:: console $ ./cp-for-the-poor /etc/passwd-not-there /tmp/some-file-that-does-not-exist /etc/passwd-not-there: No such file or directory $ echo $? 2 Error: Destination File Exists .............................. Provided that ``/tmp/passwd-copy`` already exists [#create-file]_: .. code-block:: console $ ./cp-for-the-poor /etc/passwd /tmp/passwd-copy /tmp/passwd-copy: File exists $ echo $? 3 Error: Destination Directory Not Writable ......................................... Provided that ``/etc`` is not writable (because you are not ``root``, for example), .. code-block:: console $ ./cp-for-the-poor /etc/passwd /etc/passwd-copy /etc/passwd-copy: Permission denied $ echo $? 4 Submission ---------- * Create a directory ``exercise-1`` which contains all the source (C code, and CMake build instructions) * From the parent directory of ``exercise-1``, package that directory .. code-block:: $ tar -J -c -f submission.tar.xz exercise-1/ * Submit ``submission.tar.xz`` Dependencies ------------ .. ot-graph:: :entries: linux.sysprog.fileio.basics_exercise_copy .. rubric:: Footnotes .. [#create-file] If not, and you need one for testing purposes, you create it like so: .. code-block:: console $ touch /tmp/passwd-copy (Or by running the sunny case, of course)