8.6 KiB
Comprendre la base guidée
Au TP1, lire les parties 1 à 5 pendant les temps de découverte déjà prévus. Les pointeurs de fonctions viennent au CM3/TP3 : voir APPELS-INDIRECTS.md. Il n'est pas nécessaire de commencer par eux.
1. À quoi sert ce programme ?
Snapguard construit une sauvegarde consultable dans un répertoire. On appelle instantané cette copie datée de l'arborescence. Le programme reçoit une source, une nouvelle destination et, éventuellement, un instantané précédent. Le nom de destination est choisi par l'appelant : le programme n'y ajoute pas automatiquement une date.
./snapguard SOURCE DESTINATION [PRECEDENT]
Les crochets signifient « argument facultatif » : on ne les tape pas. Sans précédent, le programme copie les fichiers. Sinon, il décide pour chaque fichier s'il peut réutiliser sa version précédente ou doit le copier.
La destination est d'abord construite sous un nom terminé par .en-cours.
Publier signifie ici renommer ce répertoire vers le nom définitif.
Ce n'est ni une mise en ligne ni un envoi sur Internet.
Le parcours, les opérations sur les fichiers et les tests sont fournis. Vous faites évoluer quatre décisions en C, une par TP. Le programme contient les défauts annoncés : on observe son comportement actuel avant de le comparer au comportement attendu.
2. Où se trouve chaque responsabilité ?
| Fichier | Son rôle | Votre lecture |
|---|---|---|
src/sg.h |
Types, prototypes et contrats communs | Le type et le contrat du TP du jour |
src/main.c |
Lit les arguments, lance la sauvegarde, affiche le résultat | La fonction main, sans détailler d'abord les contrôles de chemins |
src/service.c |
Organise les étapes et parcourt les répertoires | Les points d'appel indiqués dans le sujet |
src/rapport.c |
Choisit l'étiquette du bilan | Chantier TP1 |
src/regles.c |
Décide si une version précédente est réutilisable | Chantier TP2 |
src/transfert.c |
Organise les tentatives de lien et de copie | Chantier TP3 |
src/finalisation.c |
Décide de publier et met à jour l'état | Chantier TP4 |
src/fs_posix.c |
Réalise les opérations sur de vrais fichiers sous Linux ou macOS | Fourni ; détails système à consulter au besoin |
tests/test_seances.c |
Prépare les cas R, D, E et A et vérifie leurs résultats | Les tests de votre séquence |
tests/mes_tests.c |
Accueille vos tests personnels | À compléter selon le sujet |
tests/doublure.h et .c |
Simulent des réponses et comptent les appels | À lire au TP3 |
tests/integration.py |
Lance le vrai programme sur des fichiers temporaires | À exécuter ; Python n'est pas un chantier du projet |
Makefile |
Donne les commandes de compilation et de test | Utiliser les cibles annoncées |
sg_ est le préfixe des noms du projet ; _t est une convention pour les noms
de types. Ces morceaux de noms ne sont pas des instructions du langage C.
3. Quel chemin suit une sauvegarde ?
Voici les appels principaux d'une exécution qui atteint la fin du parcours. L'indentation signifie « appelle » ; certaines erreurs peuvent arrêter plus tôt.
main() [main.c]
sg_sauvegarder(...) [service.c]
initialise le rapport et l'état
vérifie la source et crée le répertoire de travail
parcourir(...) [service.c]
pour chaque fichier :
sg_reutilisable(...) [regles.c]
sg_transferer(...) [transfert.c]
pour chaque sous-répertoire : parcourir(...) à nouveau
sg_finaliser(...) [finalisation.c]
sg_bilan(&rapport) [rapport.c]
affiche les compteurs et l'état
Le service organise les tâches. Les quatre fonctions étudiées en TP répondent
chacune à une question locale. sg_bilan est appelée après le retour du service :
elle lit le rapport, elle ne déclenche pas la sauvegarde.
Exemple sans incident ni précédent : pour deux fichiers copiés, le rapport
contient vus=2, copies=2, lies=0, erreurs=0. Le renommage final réussit,
l'état devient SG_COMPLET, puis main affiche les résultats.
4. Quelles données circulent ?
| Type | Ce qu'il représente | À retenir |
|---|---|---|
sg_entree_t |
Nom, taille, date mtime, nature d'un fichier ou répertoire |
Des métadonnées, pas le contenu. off_t représente une taille ; time_t, une date. |
sg_rapport_t |
Compteurs vus, copies, lies, erreurs |
Le service et le transfert les remplissent ; le bilan les lit. vus compte les fichiers rencontrés, pas les répertoires. |
sg_etat_t |
État de la tentative : en cours, complet ou échec | Déclaré avec enum ; distinct des compteurs de traitement. |
sg_port_t |
Opérations utilisables pour accéder aux fichiers | Au TP1, retenir : une boîte à opérations déjà préparée. Les adresses de fonctions seront lues au TP3. |
Dans main.c :
sg_rapport_t rapport;
sg_etat_t etat;
int code = sg_sauvegarder(sg_posix(), argv[1], precedent,
argv[2], &rapport, &etat);
rapport et etat sont des objets locaux à main. Leurs adresses sont
transmises pour que le service puisse les initialiser et les modifier.
Il ne reçoit pas une copie du rapport. Ces objets existent pendant l'appel.
const char *sg_bilan(const sg_rapport_t *r);
r pointe vers le rapport. r->erreurs lit son champ erreurs ; c'est une
autre écriture de (*r).erreurs. Le const interdit de modifier le rapport
à travers r. Le résultat const char * désigne le texte de l'étiquette.
sg_bilan n'alloue pas un nouveau rapport.
Le retour code, les compteurs et l'état répondent à des questions différentes.
Zéro erreur de traitement ne prouve pas que le renommage final a réussi.
On approfondira cette distinction au TP4.
5. Pourquoi un .h et plusieurs .c ?
sg.h décrit ce qu'un fichier doit connaître pour utiliser une fonction définie
ailleurs : nom, paramètres et résultat. Il définit aussi les types partagés.
Les commentaires de contrat disent ce que la fonction doit garantir.
#include "sg.h" rend ces déclarations visibles au compilateur ; cela
n'exécute aucune fonction. La définition de sg_bilan, avec son corps,
est dans rapport.c. On inclut le .h, pas le .c. Les lignes #ifndef,
#define et #endif évitent de relire deux fois le même en-tête lors de la
compilation d'un fichier.
Le Makefile construit trois programmes séparés :
| Programme | Point de départ | Opérations utilisées |
|---|---|---|
snapguard |
main dans src/main.c |
Vrais fichiers : src/fs_posix.c |
run_tests |
main dans tests/test_seances.c |
Cas fournis ; opérations simulées si nécessaire |
tests_perso |
main dans tests/mes_tests.c |
Vos cas ; même simulation disponible |
Les mêmes fichiers de décision sont compilés avec chacun des programmes.
Il y a plusieurs fonctions main dans le dossier, mais une seule par
exécutable. Les tests n'ont pas leur propre copie corrigée de vos fonctions.
Depuis le dossier base-guidee/ :
make depart
make observer
make test-s1
make depart compile les trois programmes puis vérifie une copie sur des
données temporaires. make observer affiche deux rapports : dans la base
initiale, leur étiquette vaut OK malgré leurs compteurs différents.
make test-s1 signale alors l'échec de R2. C'est le défaut à étudier, pas
une installation ratée. Une erreur de compilation, en revanche, empêche de
lancer les tests : il faut d'abord lire le message du compilateur.
Avant de modifier : retrouvez le prototype de sg_bilan, sa définition,
son appel et R2. Expliquez qui écrit le rapport et qui le lit. Vous avez ainsi
suivi une donnée entre plusieurs fichiers sans lire toute l'infrastructure.
6. Ce qui s'ajoute aux séances suivantes
- TP2 : dans
parcourir, suivrep, initialementNULL, puis&infosi les métadonnées précédentes sont disponibles.NULLmarque ici leur absence. Un lien dur crée un autre nom pour le même fichier : il vise la version de l'instantané précédent, jamais la source susceptible de changer. - TP3 : lire APPELS-INDIRECTS.md, puis suivre un appel
de
transfert.cjusqu'à la doublure : fonction choisie et contexte. - TP4 : suivre l'adresse de l'état jusqu'à
sg_finaliser, puis observer l'appel de publication et les effets autorisés.
À chaque TP : contrat → appel → résultat prédit → test → modification.