Version without JavaScript, read-only: workshops, quizzes and running code are not available here. Full version · Catalogue · Sign in
Exercise sheet 5
Input and output Predict what a program writes depending on whether its output goes to the terminal or to a file, write wc, tee and tail with read, write and lseek, follow shared file offsets, send integers through a pipe. Chapter 5.
All programs are compiled with gcc -std=c11 -Wall -Wextra -Werror -D_POSIX_C_SOURCE=200809L. We do not use <stdio.h> to read or write the data, only for error messages and for displaying results.
Exercise · Terminal or file?
#include <stdio.h>
#include <sys/wait.h>
#include <unistd.h>
int main(void )
{
printf("A\n" );
printf("B" );
write(STDOUT_FILENO, "C\n" , 2 );
if (fork() == 0 )
{
printf("D\n" );
return 0 ;
}
wait(NULL );
printf("E\n" );
return 0 ;
}
What does this program print when run in a terminal? What is in f.txt after ./q1 > f.txt? Where should you add a single call so that both outputs are identical and no letter is repeated?
Exercise · Counting
Write compte, which reads its standard input to the end, and prints the number of bytes and the number of lines read (the number of \n), like wc -c -l. Read in blocks of 4096 bytes.
Check it on its own source: ./compte < compte.c, then wc -c -l compte.c.
Exercise · A tee
tee file copies its standard input both to its standard output and into file. Write montee. Each block read must be written in full to both places.
$ printf 'un\ndeux\n' | ./montee copie.txt | wc -l
2
$ cat copie.txt
un
deux
Exercise · Who writes where?
Without running it, give the contents of the three files after this program. od -c p1.txt shows a file byte by byte, so you can check.
#include <fcntl.h>
#include <unistd.h>
int main(void )
{
int a = open("p1.txt" , O_WRONLY | O_CREAT | O_TRUNC, 0666 );
int b = dup(a);
write(a, "bonjour" , 7 );
write(b, "!!" , 2 );
close(a);
close(b);
int c = open("p2.txt" , O_WRONLY | O_CREAT | O_TRUNC, 0666 );
int d = open("p2.txt" , O_WRONLY);
write(c, "bonjour" , 7 );
write(d, "!!" , 2 );
close(c);
close(d);
int e = open("p3.txt" , O_WRONLY | O_CREAT | O_TRUNC, 0666 );
write(e, "bonjour" , 7 );
lseek(e, 0 , SEEK_SET);
write(e, "B" , 1 );
lseek(e, 2 , SEEK_END);
write(e, "!" , 1 );
close(e);
return 0 ;
}
Exercise · The last bytes
Write queue n file, which prints the last n bytes of the file (the whole file if it has fewer), like tail -c n, without reading the beginning of the file.
What happens if you call echo x | ./queue 3 /dev/stdin? Why?