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
- Repeat:
- Read from stdin
- Write to stdout
- 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
-
Create 1MB file:
dd if=/dev/zero of=foobar count=1 bs=1M
-
Measure time of the copying for the
cpm1
program:
time ./cpm <foobar >my_output
-
Measure time of the copying for the
cp
program:
time cp foobar my_output
-
Using the
strace
utility observe system calls made by the
programs
strace cp foobar my_output strace ./cpm <foobar >my_output
- Modify the cpm to copy file as fast as cp . (Hint: Create a new version - cpm2 )
Creating the output file inside the cpm program
-
Set file mode creation mask using umask command
umask 000
More about umask umask() -
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
- Modify the cpm to read the input file from the first command line argument. (Hint: Create a new version - cpm3 )
- Test existing / non-existing input file
- Modify the cpm to also write to the input file from the first command line argument. (Hint: Create a new version - cpm4 ).
-
Compare output files for
cpm3
and
cpm4
when output
files exist and
- infile is larger than the outfile
- infile is smaller than the outfile
- If necessary, modify the cpm program to create the output file if it does not exist. Remember to include file mode bits parameter.
- 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);
}
}