Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Objective The objective of this assignment is to familiarize yourself with the s

ID: 3889008 • Letter: O

Question

Objective

The objective of this assignment is to familiarize yourself with the standard system calls and how to use them in a program.

Assignment: Simple File Copy Program

Write a C/C++ program that only uses only standard system calls to copy the contents of one file to another file. You should only have to use the open(), close(), read() and write() system calls. You can use printf() or fprintf() for error or informational messaging.  Your program should not explicitly prompt the user for input/output filenames but rather those should be provided on the command line.

Simple File Copy Program Implementation

The  program () is a simple text-based program that takes two arguments from the command line, again no prompting the user from within the program.

1.To start the  program

./filecpy <input file> <output file>

where <input file> is the file that is to be copied and <output file> is the file that is copied to. After your program completes you should be able to do a “diff”command on the two files and they should be identical. Last step is to run your program with strace to determine the number of system calls made.

Error Handling

Perform the necessary error checking to ensure that the input file exists and that the output file can be written. You can use the system error “errno” and “strerror” to provide additional error messaging.

Be sure to name your program filecpy.c (no extra characters, capitals) and include the output from the strace command.

Explanation / Answer

Code:

#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

extern int errno;

int main(int argc, char const *argv[])
{
   //check if files name are not specified
   if (argc<3)
   {
       printf("Plese provide input file and output file name "
           "Usage ./filecpy <inputfile> <outputfile> ");
       return -1;
   }
  
   int in_file_fd, op_file_fd, n;
   char buf;

   //open input file in read only mode
   in_file_fd = open(argv[1], O_RDONLY);
   //if unable to open input file
   if(in_file_fd == -1)
   {  
       printf("Error opening input file [%s]. "
               "Error: [%s] ", argv[1], strerror(errno));
       return -1;
   }

   //open output file with write only flag and create if not exist and
   //O_EXCL to ensure this call creates file if not means file already
   //exist or some other error
   //0664 are permission of file to be created
   op_file_fd = open(argv[2],O_WRONLY | O_CREAT | O_EXCL, 0664);
   if(op_file_fd == -1)
   {
       printf("Error opening output file [%s]. "
               "Error: [%s] ", argv[2], strerror(errno));
       return -1;
   }

   //read data byte by from input file and write it to output file
   while((n=read(in_file_fd,&buf,1)) > 0)
    {
        write(op_file_fd, &buf, 1);
    }

    //write 2nd argument on stdout 3rd argument is size in bytes
    write(STDOUT_FILENO, "File Copied Sucessfully ", 24);
  
    close(in_file_fd);
    close(op_file_fd);

    //execute diff command on the files if there is any difference
    //this will show output
    char* command;
    strcpy(command, "diff ");
    strcat(command, argv[1]);
    strcat(command, " ");
    strcat(command, argv[2]);
    system(command);

   return 0;
}

output from strace

strace -t ./filecpy file outfile > opfile

18:28:06 execve("./filecpy", ["./filecpy", "file", "outfile"], [/* 60 vars */]) = 0
18:28:06 brk(NULL)                      = 0x2414000
18:28:06 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
18:28:06 mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fe55e1ef000
18:28:06 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
18:28:06 open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
18:28:06 fstat(3, {st_mode=S_IFREG|0644, st_size=130693, ...}) = 0
18:28:06 mmap(NULL, 130693, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fe55e1cf000
18:28:06 close(3)                       = 0
18:28:06 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
18:28:06 open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
18:28:06 read(3, "ELF>P "..., 832) = 832
18:28:06 fstat(3, {st_mode=S_IFREG|0755, st_size=1868984, ...}) = 0
18:28:06 mmap(NULL, 3971488, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fe55dc02000
18:28:06 mprotect(0x7fe55ddc2000, 2097152, PROT_NONE) = 0
18:28:06 mmap(0x7fe55dfc2000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1c0000) = 0x7fe55dfc2000
18:28:06 mmap(0x7fe55dfc8000, 14752, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fe55dfc8000
18:28:06 close(3)                       = 0
18:28:06 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fe55e1ce000
18:28:06 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fe55e1cd000
18:28:06 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fe55e1cc000
18:28:06 arch_prctl(ARCH_SET_FS, 0x7fe55e1cd700) = 0
18:28:06 mprotect(0x7fe55dfc2000, 16384, PROT_READ) = 0
18:28:06 mprotect(0x600000, 4096, PROT_READ) = 0
18:28:06 mprotect(0x7fe55e1f1000, 4096, PROT_READ) = 0
18:28:06 munmap(0x7fe55e1cf000, 130693) = 0
18:28:06 open("file", O_RDONLY)         = 3
18:28:06 open("outfile", O_WRONLY|O_CREAT|O_EXCL, 0664) = 4
18:28:06 read(3, "H", 1)                = 1
18:28:06 write(4, "H", 1)               = 1
18:28:06 read(3, "e", 1)                = 1
18:28:06 write(4, "e", 1)               = 1
18:28:06 read(3, "l", 1)                = 1
18:28:06 write(4, "l", 1)               = 1
18:28:06 read(3, "l", 1)                = 1
18:28:06 write(4, "l", 1)               = 1
18:28:06 read(3, "o", 1)                = 1
18:28:06 write(4, "o", 1)               = 1
18:28:06 read(3, " ", 1)                = 1
18:28:06 write(4, " ", 1)               = 1
18:28:06 read(3, "t", 1)                = 1
18:28:06 write(4, "t", 1)               = 1
18:28:06 read(3, "h", 1)                = 1
18:28:06 write(4, "h", 1)               = 1
18:28:06 read(3, "i", 1)                = 1
18:28:06 write(4, "i", 1)               = 1
18:28:06 read(3, "s", 1)                = 1
18:28:06 write(4, "s", 1)               = 1
18:28:06 read(3, " ", 1)                = 1
18:28:06 write(4, " ", 1)               = 1
18:28:06 read(3, "i", 1)                = 1
18:28:06 write(4, "i", 1)               = 1
18:28:06 read(3, "s", 1)                = 1
18:28:06 write(4, "s", 1)               = 1
18:28:06 read(3, " ", 1)                = 1
18:28:06 write(4, " ", 1)               = 1
18:28:06 read(3, "f", 1)                = 1
18:28:06 write(4, "f", 1)               = 1
18:28:06 read(3, "i", 1)                = 1
18:28:06 write(4, "i", 1)               = 1
18:28:06 read(3, "l", 1)                = 1
18:28:06 write(4, "l", 1)               = 1
18:28:06 read(3, "e", 1)                = 1
18:28:06 write(4, "e", 1)               = 1
18:28:06 read(3, " ", 1)                = 1
18:28:06 write(4, " ", 1)               = 1
18:28:06 read(3, "s", 1)                = 1
18:28:06 write(4, "s", 1)               = 1
18:28:06 read(3, "o", 1)                = 1
18:28:06 write(4, "o", 1)               = 1
18:28:06 read(3, "", 1)                 = 0
18:28:06 write(1, "File Copied Sucessfully ", 24) = 24
18:28:06 close(3)                       = 0
18:28:06 close(4)                       = 0
18:28:06 rt_sigaction(SIGINT, {SIG_IGN, [], SA_RESTORER, 0x7fe55dc374b0}, {SIG_DFL, [], 0}, 8) = 0
18:28:06 rt_sigaction(SIGQUIT, {SIG_IGN, [], SA_RESTORER, 0x7fe55dc374b0}, {SIG_DFL, [], 0}, 8) = 0
18:28:06 rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
18:28:06 clone(child_stack=0, flags=CLONE_PARENT_SETTID|SIGCHLD, parent_tidptr=0x7ffd7ad8ee1c) = 20284
18:28:06 wait4(20284, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 20284
18:28:06 rt_sigaction(SIGINT, {SIG_DFL, [], SA_RESTORER, 0x7fe55dc374b0}, NULL, 8) = 0
18:28:06 rt_sigaction(SIGQUIT, {SIG_DFL, [], SA_RESTORER, 0x7fe55dc374b0}, NULL, 8) = 0
18:28:06 rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
18:28:06 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=20284, si_uid=1000, si_status=0, si_utime=0, si_stime=0} ---
18:28:06 exit_group(0)                  = ?
18:28:06 +++ exited with 0 +++