Exercise: Copy A File ===================== .. topic:: See also * :doc:`/trainings/material/soup/linux/sysprog/file-io/index` * :doc:`/trainings/material/soup/linux/sysprog/file-io/file-descriptors/index` * :doc:`/trainings/material/soup/linux/sysprog/file-io/open/index` * :doc:`/trainings/material/soup/linux/sysprog/file-io/file-input/index` * :doc:`/trainings/material/soup/linux/sysprog/file-io/file-output/index` * :doc:`/trainings/material/soup/linux/sysprog/file-io/create/index` * :doc:`/trainings/material/soup/linux/sysprog/process/exit/index` * :doc:`/trainings/material/soup/linux/sysprog/process/argv/index` * :doc:`/trainings/material/soup/linux/sysprog/syscalls/errorhandling/index` * :doc:`/trainings/material/soup/linux/basics/permissions/basics` .. topic:: Documentation * 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 `__ Requirement ----------- Write a program ``cp-for-the-poor`` which exhibits the following behavior: * It interprets its two arguments as filenames, and copies the first to the second * The first filename must be an existing file * The second filename is the target of the copy * No existing file must be overwritten * *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/syscalls/errorhandling/index` for how to. * Make sure the program interprets its commandline correctly; see :doc:`/trainings/material/soup/linux/sysprog/process/argv/index` for how to. * Make sure the program returns exit statuses as specified below; see :doc:`/trainings/material/soup/linux/sysprog/process/exit/index` 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 (:download:`Test script (download) `) Error: Wrong Number Of Arguments Specified .......................................... .. code-block:: console $ ./cp-for-the-poor ./cp-for-the-poor: SRCFILE DSTFILE $ echo $? 1 (:download:`Test script (download) `) 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 (:download:`Test script (download) `) 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 (:download:`Test script (download) `) 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 (:download:`Test script (download) `) .. 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)