#include <stdio.h>    // pour perror() et printf() : fonctions d’affichage
#include <stdlib.h>   // pour exit() : permet de quitter le programme en cas d’erreur
#include <fcntl.h>    // pour open() : ouverture de fichiers
#include <unistd.h>   // pour read(), write(), close() : appels systèmes bas niveau

int main() {
    int source, dest;    // "descripteurs de fichiers" : nombres entiers utilisés par le système
    char c;              // variable qui va contenir un caractère (1 octet) lu depuis le fichier

    // Ouvrir le fichier source en lecture seule (O_RDONLY)
    source = open("source.txt", O_RDONLY);
    if (source < 0) { // si la valeur < 0, c’est que l’ouverture a échoué
        perror("Erreur ouverture source"); // affiche l’erreur système
        exit(1); // quitte le programme avec un code d’erreur
    }

    //  Créer (si n’existe pas) ou ouvrir le fichier destination en écriture
    // O_WRONLY = écriture seule
    // O_CREAT = créer le fichier si n’existe pas
    // O_TRUNC = vider le fichier s’il existe déjà
    // 0644 = permissions du fichier (rw-r--r--)
    dest = open("dest.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644);
    if (dest < 0) { // si l’ouverture échoue
        perror("Erreur ouverture destination");
        close(source); // on ferme quand même le fichier source ouvert
        exit(1);
    }

    //  Lire et écrire le fichier octet par octet
    // read(source, &c, 1) lit 1 octet du fichier source et le stocke dans c
    // la boucle continue tant que read() lit bien 1 octet
    while (read(source, &c, 1) == 1) {
        // écrire cet octet dans le fichier destination
        if (write(dest, &c, 1) != 1) { // si write() échoue
            perror("Erreur écriture");
            close(source);
            close(dest);
            exit(1);
        }
    }

    //  Fermer les deux fichiers
    close(source);
    close(dest);

    //  Indiquer à l’utilisateur que tout s’est bien passé
    printf("Copie terminée (méthode appels système).\n");
    return 0; // programme terminé correctement
}
