Working with files

Return to homepage

Copying a file

Output / input redirection

                                    
mkdir ex1 ; cd ex1 # just to put everything into one directory
echo "hello" > h
ls -l
ls -l > l
ls -l
                                    
                                
What about input? Standard error output vs Standard output ?

Program cpm

Goal: make program that copies statdard input to standard output.

Usage:

  • version 1: ./cpm1 < infile > outfile
  • version 2: ./cpm2 < infile > outfile
  • version 3: ./cpm3 infile > outfile
  • version 4: ./cpm4 infile outfile

Program copies until it reaches end of the input file.

Tasks

  1. Repeat:
    1. Read from stdin
    2. Write to stdout
  2. Until the input file is empty

A simple starter program

Modify this program to copy the whole input file.

                                    
#include <unistd.h>
#include <stdio.h>

int main(int argc, char const *argv[])
{
char b = -1;

ssize_t num_r = -1;
ssize_t num_w = -1;

num_r = read(0, &b, 1);
num_w = write(1, &b, 1);

fprintf(stderr, "num_r = %lld ; num_w = %lld\n", (unsigned long long) num_r, (unsigned long long) num_w);

return 0;
}
                                    
                                

Compile the program using the following command:

                                    gcc -std=gnu11 -Wall -pedantic cpm.c -o cpm1
                                

Manpages

Measuring time of the file copy operation

  1. Create 1MB file: dd if=/dev/zero of=foobar count=1 bs=1M
  2. Measure time of the copying for the cpm1 program: time ./cpm <foobar >my_output
  3. Measure time of the copying for the cp program: time cp foobar my_output
  4. Using the strace utility observe system calls made by the programs
                                                
    strace cp foobar my_output
    strace ./cpm <foobar >my_output
                                                
                                            
  5. Modify the cpm to copy file as fast as cp . (Hint: Create a new version - cpm2 )

Creating the output file inside the cpm program

  1. Set file mode creation mask using umask command umask 000
    More about umask umask()
  2. Experiment with the following scenarios:
    • infile does not exist , outfile does not exist
    • infile exists , outfile does not exist
    • infile exists , outfile exists
    • infile does not exist , outfile exists
  3. Modify the cpm to read the input file from the first command line argument. (Hint: Create a new version - cpm3 )
  4. Test existing / non-existing input file
  5. Modify the cpm to also write to the input file from the first command line argument. (Hint: Create a new version - cpm4 ).
  6. Compare output files for cpm3 and cpm4 when output files exist and
    • infile is larger than the outfile
    • infile is smaller than the outfile
  7. If necessary, modify the cpm program to create the output file if it does not exist. Remember to include file mode bits parameter.
  8. Change file mode creation mask using umask command to a different value, for instance 0022 . Observe how this changes access mode of newly created files.

Homework 1

Change the following source code so it doesn't truncate the output file but appends the content of input file at the end of it.
								
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(int argc, char** argv)
{
	char c[10000];
	int bytesRead = 0;

	int fd1, fd2;

	if( (fd1 = open(argv[1], O_RDONLY)) == -1)
	{
		perror("Open infile failed");
		return 0;
	}
	if( (fd2 = open(argv[2], O_CREAT | O_RDWR | O_TRUNC, S_IRWXU)) == -1)
	{
		perror("Open infile failed");
		return 0;
	}

	while( (bytesRead = read(fd1, c, 10000)) > 0 )
	{
		write(fd2, c, bytesRead);
	}
}