[C] Parcourir une arborescence et voir les dates

Statut
N'est pas ouverte pour d'autres réponses.

*Serval

Elite
Salut à tous,


J'ai exam demain sur un cours d'architecture système et on aura probablement une question en C.
Seulement j'ai pas beaucoup de notions la dessus...


Ceux qui ont eu l'exam la semaine passée ont eu ceci :
1. Concevez un programme C qui parcourt l'arborescence dont la racine est reçue en premier argument et y recherche tous les programmes plus récents que la date reçue en 2ème arguement sous la forme YYMMDD. Le programme affichera à la sortie standard les chemins de tous les programmes trouvés à partir de et y compris la racine recue en argument. Pour information, dans /usr/include/sys/types.h , on trouve :
Code:
#if !defined(_TIME_T) || __cplusplus >= 199711L
#define _TIME_T
typedef long time_t; /*time of day in seconds*/
#endif /* _TIME_T */


2. Concevez un programme C appelé boss qui crée 3 fils. Deux de ceux-ci doivent exéctuter un autre programme /opt/bin/work avec comme argument respectivement le premier, et le second argument de boss. Le troisième fils exécute un programme /opt/bin/collect qui lira les fichiers résultat des work, dont le nom est respectivement /tmp/work_pid, les traitera et affichera le résultat à l'écran.
a. proposez le code de boss
b. quels autres arguments doivent avoir work et collect
c. que faut-il dans work et collect pour que collect lise les fichiers au bon moment.

3. et 4. : 2 questions théoriques pour lesquelles j'ai pas de probs ;)
Pour la question 1, j'ai déjà du mal à parcourir l'arborescence :/
Il faut faire un truc récursif ? si quelqu'un avait un exemple ;)
Ensuite, il doit rechercher tous les programmes, donc tout ce qui a été chmodé +x ? On peut voir ca avec fstats ?
La date, idem avec fstats ?

Et le code qu'il donne pour information, ca aide à quoi ?




Pour la question 2, ben la je comprends vraiment rien, on a pas vu cette matière :/ Quelqu'un pourrait rapidement m'expliquer comme faire des fils et comment ils peuvent interagir entre eux et avec le père ?





Je sais, je suis complètement largué :/

Merci d'avance pour votre aide :)






[edit]Si quelqu'un est vraiment très motivé pour tout faire avec moi sur msn ou quoi, ca marche aussi bien sûr :D
 

Ahava

Revenant
Purée c'est balaize comme exercice :gne:


J'ai commencé ma révision du cours de systeme today, je ne suis pas encore à ce niveau là.. Dés que j'ai une idée jte pm !
 
1er
OP
*Serval

*Serval

Elite
oki merci...


Je tiens à signaler qu'on a jamais eu de cours de C :shock:

Juste 2 TPs : un avec pointeur et un ou il fallait refaire la commande "mv" de linux en C (enfin juste les bases)...
TPs jamais corrigés d'ailleurs...


Et là beng, des questions de fous :shock:


Je stress assez
 

Froggy

fake geek
essaye de pm jereck ... il est plutot calé en C/C++/C#/... ;)
 
1er
OP
*Serval

*Serval

Elite
je l'ai SMSé, mais j'ai peur d'abuser en le PMant :p


Vous croyez que je peux ? :p
 

AssiuM

Fan
*Serval a dit:
je l'ai SMSé, mais j'ai peur d'abuser en le PMant :p


Vous croyez que je peux ? :p
Un pm est quand même moins embêtant qu'un sms hein :)
 
1er
OP
*Serval

*Serval

Elite
je parlais d'un sms sur GamerZ :p

Au moins ca envoi pas de mail ;)
 

AssiuM

Fan
*Serval a dit:
je parlais d'un sms sur GamerZ :p

Au moins ca envoi pas de mail ;)
Oui mais ça apparaît directement , et tu es obligé de le lire :-D

Enfin, désolé pour ce off-topic, au moins ça a remonté ton sujet en haut de la liste :)
 

Tifox

ou pas
30 secondes, je t'explique ça.
 
1er
OP
*Serval

*Serval

Elite
prends ton temps, tant que j'ai une explication pour demain matin 7h30 :p



Limite si tu veux prendre mon MSN si c'est plus simple pour toi, hésite pas, il est dans mon profil :)



Je te remercie d'avance, parce que là je stresse un max :/
 

Tifox

ou pas
Voila, alors supposons que le chemin vers ton dossier soit dans arg1

Code:
#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>
#include <fcntl.h>

...


// Ouverture dossier
DIR *folder = opendir(arg1);
if (folder != NULL){
	struct dirent *file;
	// Listing des fichiers
	while ( (file = readdir(folder)) ){

		if( strncmp(file->d_name, ".", 1) != 0 ){	// passer les "fichiers" . et ..
		
			// Récupérer les information sur un fichier
			struct stat fileInfo;
			char filePath[strlen(arg1) + strlen(file->d_name) + 1);
			strcpy(filePath, arg);
			strcpy(filePath + strlen(arg1), "/");
			strcpy(filePath + strlen(arg1) + 1, file->d_name);
			stat(filePath, &fileInfo);

			if( S_ISDIR (fileInfo.st_mode){
				// Le fichier consulter est un dossier, relancer la fonction sur ce dossier
			}
			else{
				// ici tu fais ce que tu dois.
			}
		}
	}
}

Le contenu d'une structure stat (donc le fileInfo dans l'exemple) est dispo ici, tu y trouvera les info qu'il faut pour les dates.
http://pwet.fr/man/linux/appels_systemes/stat

Note que j'ai pas testé, donc regarde un peu et dis-moi si tu as encore besoin d'aide.
 
1er
OP
*Serval

*Serval

Elite
Hum ca m'aide déjà vraiment bien :)


On pourrait en discuter sur msn ? si oui je prendrai ton adresse.


Pour la 2), tu as une idée ? :)
 

Tifox

ou pas
Pour convertir l'argument 2 (supposé etre une chaine de caractère) en le nombre de seconde correspondant a ce qu'il y a dans la structure stat, il faut utiliser :

Code:
char tmp[2];
int nbJour;
int nbMois;
int nbAnnee;
strncpy(tmp, arg2, 2);
nbAnnee = atoi(tmp);
strncpy(tmp, arg2+2, 2);
nbmois = atoi(tmp);
strncpy(tmp, arg2+4, 2);
nbjours = atoi(tmp);
Puis tu calcules le nombre de seconde correspondant a ce qu'il y a dans la structure stat avec nbJour, nbMois nbAnnee.

La je suis sur un PC ultra-limlité ou il n'y a aps moyen d'utiliser msn.
Je regarde la question 2...
 
1er
OP
*Serval

*Serval

Elite
ah euh merci, ca m'aide encore plus :p


Je te parlais en fait de la question 2 avec le boss et les fils, mais ceci m'aide bien aussi ;)



Avec les boss et les fils, Jereck m'a parlé de fork et execl ou je sais plus quoi, je vais essayer de chercher :)
 

Tifox

ou pas
La question 2 a:

Pour créer un processus fils, il faut utiliser

Code:
#include <unistd.h>

...

// Creation d'un nouveau processus
pid_t   pid;
pid = fork ();
if (pid == 0){
	// Ici on est dans le processus fils
}
else{
	// Ici on est dans le processus père
}
Pour lancer un processus avec des arguments, faut utiliser les fonctions exec.
http://www.linux-kheops.com/doc/man/manfr/man-html-0.9/man3/execl.3.html

La partie b, je ne comprend pas bien ce qu'il veut dire.

Pour la partie c, il faut que les work envoie un signal à collect quand ils ont fini de travailler et que les fichiers ont été écrit, et que collect attendent les signaux des 2 work pour lire les fichiers (sinon les fichiers n'existeront pas).
 
1er
OP
*Serval

*Serval

Elite
Voici les lignes que je ne comprends pas :
  • Les includes, je sais pas a quoi ils servent tous, mais je trouverais seul ;)
  • Code:
    char filePath[strlen(arg1) + strlen(file->d_name) + 1);
    (je suppose qu'il manque une fermeture de crochets avant le ; )
    Si je comprend bien, ca créée un tableau de la taille du premier arg + le nom du fichier + 1... le +1, c'est pour '\0' ?
  • Code:
    strcpy(filePath, arg);
    strcpy(filePath + strlen(arg1), "/");
    strcpy(filePath + strlen(arg1) + 1, file->d_name);
    Premier, on copie arg dans filePath, jusque la ca va.
    Les 2 lignes suivantes je comprends pas... pourquoi + strlen(arg1) ?
  • Code:
    stat(filePath, &fileInfo);
    &fileInfo, c'est l'adresse de fileInfo qui est le buffer, c'est ça ?
    Quelle différence entre stat et fstat ?
  • C'est quoi la sortie standard ?? Vous conseillez quoi comme structure pour garder la liste de tout ce que je dois retourner puis la retourner seulement à la fin ?


Merci encore :D
 

Tifox

ou pas
Petit rappel sur les chaine de caractère :
Une chaine de caractère doit tout d'abord être alouée. Si sa taille est toujours fixe, il suffit de faire
Code:
char maChaine[longueur];
Si sa taille peut varier, il faut "mallocer" :
Code:
char * maChaine;
...
maChaine = malloc(longueur);
...
free(maChaine);     // Quand on ne l'utilise plus ou qu'on voudra faire un autre malloc pour modifier la taille. Attention, il faut TOUJOURS un free pour un malloc.
Une fois que la chaine a été déclarée et alouée, on peut l'utiliser. Pour copier des caractères dedans, on utilise strcpy ou strncpy. ces fonctions prennent comme premier argument un pointeur vers l'endroit ou on commencera a écrire. Si tu commence au debut de la chaine, il suffit de faire
Code:
strcpy(maChaine, "blabla");
Par contre, si tu veux commencer a écrire au 8 caractère, il faut faire
Code:
strcpy(maChaine+8, "blabla");
La différence entre strcpy et strncpy, c'est que le second copie juste un certain nombre de caractère, alors que le premier copie jsuqu'a ce qu'il rencontre un symbole de terminaison (pas toujours présent, ce qui peut poser des problèmes de mémoire et arriver a des segmentation fault).


Pour ce qui est fait dans
Code:
char filePath[strlen(arg1) + strlen(file->d_name) + 1);
strcpy(filePath, arg);
strcpy(filePath + strlen(arg1), "/");
strcpy(filePath + strlen(arg1) + 1, file->d_name);
En fait, il faut créer le chemin vers le fichier. Je crée donc un chaine de caractère, je copie dedans la chemin du dossier (arg1), puis j'ajoute le caractère "/" et enfin j'ajoute le nom du fichier (file->d_name). C'est le "/" qui jsutifie que la taille est +1. Si tu veux être sur de ne jamais faire d'erreur de mémoire, tu peux faire +2 et ajouter le caractère de terminaison "\0" après le nom du fichier.

pour stat, c'est effectivement un pointeur (donc une adresse en mémoire) qu'il faut lui donner, c'est pour ça qu'on donne &fileInfo (le & donne l'adresse de la variable). fstat fais la même chose que stat, sauf qu'il faut lui donner un descripteur de fichier comme argument et pas une chaine de caractère contenant le chemin vers le fichier. il faut utiliser fstat si tu a ouvert le fichier en lecture ou en ecrite, ce qu n'est aps le cas ici.


La sortie standard, c'est la console. Tu peux imprimer des truc dedans avec la fonction printf. Je ne pense pas qu'il faille garder tout ce qu'il faut retourner puis tout retourner a la fin, tu fais un printf a chaque fois que tu trouve un nouveau truc et se sera bon.
 
1er
OP
*Serval

*Serval

Elite
Tifox a dit:
Code:
char tmp[2];
int nbJour;
int nbMois;
int nbAnnee;
strncpy(tmp, arg2, 2);
nbAnnee = atoi(tmp);
strncpy(tmp, arg2+2, 2);
nbmois = atoi(tmp);
strncpy(tmp, arg2+4, 2);
nbjours = atoi(tmp);
Puis tu calcules le nombre de seconde correspondant a ce qu'il y a dans la structure stat avec nbJour, nbMois nbAnnee.
euh c'est quoi atoi() ? pour me dire que je dois implémenter la fonction ? :p

Euh quand le prof dit "plus récent" il s'agit probablement de la date de création... donc st_mtime ou st_ctime ?

Dans les 2 cas, ca retourne un time_t... C'est un timestamp ?
Si oui alors je dois convertir année, mois, jour en timestamp ;) une fonction pour ca comme mktime() en PHP ? :p

Et à quoi sert les infos données dans l'énoncé sur /usr/include/sys/types.h ??


Merci d'avance :)
 

Tifox

ou pas
atoi() est un fonction qui converti une chaine de caractère en un entier correspondant.

time_t, c'est bien un timestamp. fais une recherche sur google pour savoir exactement a quoi il correspond, ne me souviens plus trop, et je ne sais pas si il existe des fonctions pour calculer ça automatiquement.

Perso, j'utiserais st_mtime.

Les infos données dans l'énoncé te dise peut-être de chercher du coté des time_t pour les dates. Mais je ne sais aps si vous avez accès à de la documentation ou a internet.

La je vais dormir, je jetterai encore un coup d'oeil à ce post demain matin.

Bonne merde pour ton exam. ;)
 
1er
OP
*Serval

*Serval

Elite
J'avance j'avance :p


Bon encore 2 choses.

Le prof parle de lister les programmes... Il faut donc regarder si c'est chmoddé en +x ? Si oui, comment ? :p

[edit = "ceci est arrangé, merci ;)"]

Ensuite, à la compilation j'ai ceci :
exo1.c: Dans la fonction «myscandir» :
exo1.c:26: attention : incompatible implicit declaration of built-in function «strlen»
exo1.c:27: attention : incompatible implicit declaration of built-in function «strcpy»
exo1.c: Dans la fonction «main» :
exo1.c:61: attention : incompatible implicit declaration of built-in function «strncpy»
Ligne 26 et 27 :
Code:
				char filePath[(strlen(source) + strlen(file->d_name) + 1)];
				strcpy(filePath, source);
(je passe char *source en paramètre à la fonction)



ligne 61 :
Code:
	strncpy(tmp, argc[2], 2);

[/arrangé]


Si vous voulez mon code complet pour voir où je me suis planté (surement avec les pointeurs), demandez :p
 
Statut
N'est pas ouverte pour d'autres réponses.
Haut