post
poster: psYchotic
description: simple cp clone
language: C
[download]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
/*
 * This is basically a very simple cp clone.
 * It has one small flaw: it exits if two path strings are equal, not if
 * they're not equal but still equivalent.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BUFFER_SIZE 4096

int main(int argc, char **argv) {
    // This will be the buffer, which will hold the data we will read from the source file
    char buffer[BUFFER_SIZE];
    // This will be the source file
    FILE *src;
    // This will be the destination file
    FILE *dest;
    // This will hold the amount of bytes read from the source file
    unsigned int readBytes;
    // This will hold the amount of bytes written to the destination file
    unsigned int writtenBytes;
    // This will hold the total amount of bytes written to the destination file
    unsigned int totalWrittenBytes = 0;

    // We need 2 arguments. If we have more or less than that, we print a usage description and exit
    if (argc != 3) {
        printf("Usage: %s <source> <destination>\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    // If the source and destination filenames are the same, we print an error and exit
    if (!strcmp(argv[1], argv[2])) {
        printf("ERROR: Source and destination filenames are the same.\n");
        exit(EXIT_FAILURE);
    }

    // Open the source file for reading
    src = fopen(argv[1], "r");
    if (src == NULL) {
        perror("ERROR: Could not open source file");
        exit(EXIT_FAILURE);
    }
    
    // Open the destination file for writing.
    // If it already existed, it would be truncated.
    dest = fopen(argv[2], "w");
    if (dest == NULL) {
        perror("ERROR: Could not open destination file");
        fclose(src);
        exit(EXIT_FAILURE);
    }

    // As long as we can read something out of the source file, we keep
    // on writing it to the destination file.
    while ((readBytes = fread(buffer, sizeof(char), BUFFER_SIZE, src)) != 0) {
        writtenBytes = fwrite(buffer, sizeof(char), readBytes, dest);
        totalWrittenBytes += writtenBytes;
        // If not all bytes have been written to the destination file, something must've gone wrong.
        if (writtenBytes != readBytes) {
            printf("ERROR: Could not write to the destination file anymore.\n");
            break;
        }
    }

    // If we're not at the end of the source file, an error must've occurred. Ditto if ferror returns true.
    if (!feof(src) || ferror(src)) {
        printf("ERROR: An error occurred while reading from the source file.\n");
        fclose(src);
        fclose(dest);
        exit(EXIT_FAILURE);
    }

    fclose(src);
    fclose(dest);

    return 0;
}