CoPy¶
CoPy è un programma C il cui obiettivo è mostrare l’utilizzo di alcuni servizi per la gestione di file.
1#include <stdio.h>
2#include <fcntl.h>
3#include <stdlib.h>
4#include <unistd.h>
5
6#define BUFSIZE 250
7
8#define abort(msg) do{printf(msg);exit(1);}while(0)
9
10int main(int argc, char *argv[]) {
11 int ifd, ofd, size_r, size_w, end = 0;
12 char buffer[BUFSIZE];
13
14 /* check parameters */
15 if (argc != 3) abort("usage: copy <source> <target>\n");
16
17 /* open the input file and check errors */
18 ifd=open(argv[1],O_RDONLY);
19 if (ifd == -1) abort("input open error\n");
20
21 /* opend output file and check errors */
22 ofd=open(argv[2],O_WRONLY|O_CREAT|O_TRUNC,0660);
23 if (ofd == -1) abort("output creation error\n");
24
25 while(!end){
26 /* read up to BUFSIZE from input file and check errors */
27 size_r=read(ifd,buffer,BUFSIZE);
28 if (size_r == -1) abort("read error\n");
29
30 /* has EOF been reached? */
31 end = size_r == 0;
32
33 /* write BUFSIZE to destination file */
34 size_w = write(ofd,buffer,size_r);
35 if (size_w == -1) abort("write error\n");
36 printf("written: %d\n", size_w);
37 }
38
39 /* close file descriptors */
40 close(ifd);
41 close(ofd);
42}
Il programma prende da riga di comando il file da copiare ed il file destinazione. Lo schema è il seguente:
apre il file di input in lettura utilizzando il flag O_RDONLY (riga 18)
crea ed apre il file di output in sola scrittura tramite i flag O_CREAT e O_WRONLY, e, se già esistente, ne cancella il contenuto grazie al flag O_TRUNC (riga 22)
legge al più BUFSIZE byte su un buffer (riga 27)
utilizza il suddetto buffer per la scrittura su file di output (riga 34)
una volta letto e copiato tutto il file (riga 45) vengono chiusi i relativi file descriptor (riga 40 e 41)
Avvertimento
Il codice mostrato è affetto da una problematica relativa alla fase di scrittura. Nello specifico, è possibile che il programma termini correttamente senza però aver effettuato una corretta copia del file.
Domanda
In quali scenari il programma presenta la suddetta anomalia?
Come prevenirla?