__file__

Bonjour,

En utilisant FILE dans un programme pour l’espace noyau, le nom du fichier s’affiche avec son chemin.
A part basename() et strrchr(… ‘/’ ) pour supprimer le chemin quelqu’un aurait il une autre solution? :bulb:

Merci d’avance.
(en C bien sur).

Je comprends pas très bien ce que tu veux faire ?
Tu as quoi comme exemple de chaine et tu veut que ça donne quoi ?

Avec les chaines en C le plus rigolo c’est de manipuler les pointeurs :slightly_smiling:

[quote=“MisterFreez”]Je comprends pas très bien ce que tu veux faire ?
Tu as quoi comme exemple de chaine et tu veut que ça donne quoi ?

Avec les chaines en C le plus rigolo c’est de manipuler les pointeurs :slightly_smiling:[/quote]

C’est bien la partie qui m’bloque… les pointeurs… et que je ne pige toujours pas -_-

Ca ne nous dis pas ce que tu veut faire précisément.
Grosso modo quel est la forme que te renvoie FILE et qu’est ce que tu veut que ça devienne ?

Bonjour,

Je m’explique plus précisément:

J’ai l’habitude d’utiliser FILE dans mes programmes, exemple simpliste:
main.c:
fprintf (stderr, “une erreur dans %s”, FILE);
Ce qui me donne sur l’erreur le message: une erreur dans main.c

Mais en utilisant FILE dans un programme pour l’espace noyau: le noyau, les drivers…
le même message s’affichera avec pour le nom du fichier le chemin: une erreur dans /CHEMIN…/main.c

C’est un peu encombrant dans les logs et plus la chaîne est longue plus le traitement prend de la charge CPU
par exemple dans de l’embarqué.

Il est possible de supprimer le CHEMIN en écrivant:
printk (KERN_ERR “une erreur dans %s”, strrchr(FILE, ‘/’) + 1);
il semble que basename() fonctionne aussi mais je ne l’ai pas essayé.

Je voudrais savoir si quelqu’un utilise une autre solution, un autre label type FILE, une option gcc…

Au sujet des pointeurs:

exemple simple: soit une variable devant contenir un entier (type int):
déclaration: int variable
On peut affecter une valeur à cette variable: variable = 4, variable = -85565
L’adresse de cette variable est &variable.
Un pointeur pointeur_variable contiendra l’adresse de cette variable:
déclaration: int *pointeur_variable
utilisation: pointeur_variable = &variable
tu peux affecter une valeur à cette variable en passant par le pointeur :
*pointeur_variable=4, *pointeur_variable = -85565

Si tu veux passer la valeur de la variable à une fonction la déclaration de la fonction sera par exemple:
void function (int valeur) et l’appel: function(variable) ou function(*pointeur_variable)
Si tu veux passer l’adresse de la variable à une fonction la déclaration sera par exemple:
void function (int *valeur) et l’appel: function(&variable) ou function(pointeur_variable)

Ensuite cela se complique légèrement:
Un pointeur de pointeur: int **pointeur_pointeur_variable contiendra l’adresse de l’adresse …
Et pour les structures l’accès aux membres de la structure qui se fait d’habitude par un point ‘.’ ex:
Structure.membre1 se fait avec ‘->’ ex: addStructure->membre1.

Tu peux pointer n’importe quoi, par exemple l’adresse d’un composant électronique pointeur = 0x3f… et avoir accès à son contenu par *pointeur pratique le langage C :smt001

merci.

T’inquiète pas je sais encore me servir de pointeur.

Voila la solution si tu as vraiment envi de bidouiller du pointeur, mais je ne sais pas si ça a un quelconque interet.

[code]#include <stdio.h> /printf/
#include <string.h> /strlen et strrchr/
#include <libgen.h> /basename/

int main(){
char *str = FILE;
char ptr = str + (strlen(str) - 1);
while(
(ptr-1) != ‘/’ && ptr > str){
–ptr;
}
printf(“Je suis dans %s.\n”, ptr);
printf(“Je suis dans %s.\n”, strrchr(FILE, ‘/’) + 1);
printf(“Je suis dans %s.\n”, basename(FILE));
return 0;
}[/code]

Bonjour Mr MisterFreez,

je ne doute pas que tu saches manipuler les pointeurs, le petit rappel était pour Mr Zodar.

Cela dit ta réponse ne répond pas à ma question et en plus ton programme provoquera sûrement un belle erreur de segmentation, parce que dans l’espace utilisateur FILE ne retourne pas le chemin.
Comme je l’ai expliqué plus haut le problème se pose seulement dans l’espace noyau par exemple avec printk.

Mais bon tu dois être débordé de travail, merci quand même pour ta réponse.

J’ai testé avec et sans le chemin. Il y a peut être un memory leak mais je ne suis pas sûr. Je sais pas exactement comment marche la macro FILE s’il faut libérer manuellement la mémoire ou non.

Je n’ai pas compris ce qui est différents en espace noyau. Avoir le chemin complet tu peut l’avoir en espace utilisateur :

[code]% mkdir test
% cat > test/test.c
#include <stdio.h> /printf/
#include <string.h> /strlen et strrchr/
#include <libgen.h> /basename/

int main(){
char *str = FILE;
char ptr = str + (strlen(str) - 1);
while(
(ptr-1) != ‘/’ && ptr > str){
–ptr;
}
printf(“Je suis dans %s.\n”, ptr);
printf(“Je suis dans %s.\n”, strrchr(FILE, ‘/’) + 1);
printf(“Je suis dans %s.\n”, basename(FILE));
return 0;
}
% make test/test
% test/test[/code]
Printk je ne l’ai pas trouvé dans mes pages man.

Mais en principe le fait d’avoir un chemin dans une chaine en anglais et de vouloir en récupérer uniquement le dernier mot c’est lié au langage et pas du tout au noyau. De même pour la macro son comportement est normalisé il ne dépend pas du contexte d’exécution.

[quote=“Dixippe”]Bonjour Mr MisterFreez,

je ne doute pas que tu saches manipuler les pointeurs, le petit rappel était pour Mr Zodar.

Cela dit ta réponse ne répond pas à ma question et en plus ton programme provoquera sûrement un belle erreur de segmentation, parce que dans l’espace utilisateur FILE ne retourne pas le chemin.
Comme je l’ai expliqué plus haut le problème se pose seulement dans l’espace noyau par exemple avec printk.

Mais bon tu dois être débordé de travail, merci quand même pour ta réponse.[/quote]

Merci pour ton petit rappel.Déjà que je me souviens avoir mis un bon bou de temps à comprendre juste à quoi les pointeurs servaient… C’est dommage que je n’ai pas le temps en ce moment pour m’y remettre… mais je m’y remettrai

[quote=“MisterFreez”]Je sais pas exactement comment marche la macro FILE s’il faut libérer manuellement la mémoire ou non.[/quote]La macro FILE est gérée par le préprocesseur (comme le nom de “macro” l’indique).
Le PP effectue un simple remplacement du symbole FILE par une chaîne statique contenant le nom du fichier :

char* str = __FILE__; // est vu par le compilateur (après l'étape préprocesseur) comme char* str = "nom_du_fichier";
Au fait, une chaîne statique (typiquement, allouée dans un segment de données en lecture seule) doit toujours être typée const char* et non pas simplement char*. Mon exemple ci-dessus est donc incorrect car il manque le const.

Mise en évidence de ce problème :

[code]#include <stdio.h>
#include <string.h>
#include <assert.h>

int main() {
char* str = FILE; // pas de const
assert(strlen(str)>0);
str[0] = ‘X’; // SIGSEGV (Segmentation fault)
return 0;
}[/code]
Solution : toujours compiler avec -Wwrite-strings, qui émettra un avertissement pour ce genre de cas. Il y a aussi d’autres options pour rendre les chaînes statiques modifiables (et donc contourner ce problème), mais là on s’éloignerait du standard C.

[quote=“MisterFreez”]De même pour la macro son comportement est normalisé il ne dépend pas du contexte d’exécution.[/quote]La différence de ne vient pas du contexte d’exécution, mais des options de compilation (selon que la cible est l’espace utilisateur ou le noyau) qui influent sur le comportement non seulement du compilateur mais aussi du préprocesseur.

[code]% cd
% cat > /tmp/prog.c
#include <stdio.h>

int main(){
printf("%s\n", FILE);
return 0;
}
% make /tmp/prog
% /tmp/prog
/tmp/prog.c
% touch /tmp/prog.c
% make …/…/tmp/prog
% /tmp/prog
…/…/tmp/prog[/code]
Tu pense toujours que c’est lié au fait d’être en espace noyau ?

Bonjour Mr MisterFreez,

Ok ta démonstration est claire, cela n’a rien à voir avec l’espace noyau ou utilisateur, mais plutôt du
chemin enregistré au moment de la compilation. Et comme la façon de compiler les drivers sous la version
2.6 à changée par rapport aux noyaux 2.4, le chemin se trouve systématiquement dans FILE.
Peut être dans le future une nouvelle macro apparaîtra ne contenant pas le chemin de compilation.

Merci pour ton aide.

Mais c’est un plaisir :slightly_smiling: