Besoin d'une expertise en C

Fermé
AirSeb - 11 mars 2009 à 12:28
Char Snipeur Messages postés 9813 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 - 13 mars 2009 à 08:15
Bonjour,
Je travaille sur une TVbox basé sur un kernel linux minimaliste. Pour gérer l'interface la TVbox lance un binaire dont je maitrise rien excepté son log dans lequel il y a des informations que je voudrai parser pour les eploiter dans un de mes programmes.
Le problème auquel je suis confronté est le suivant :
-Quand je lance ce binaire, son log s'affiche en temps réel à l'écran (console).
-Quand je fais une redirection de ce binaire vers un fichier de log, la sortie semble être bufferisée par Linux.Et donc finalement mon log n'est pas synchronisé en temps réel. ce qui ne me va pas.
D'où ma question, comment forcer ce binaire à sortir ses données en temsp réél dans le fichier log sans utiliser le buffer ?????
Je peux coder en php ou en C sur la TVbox.

merci de votre aide.

cdlt.

AirSeb
A voir également:

6 réponses

fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 840
11 mars 2009 à 13:01
Salut,
Si tu fais la redirection dans un fichier, il grossira en temps réel si cela s'affiche en temps réel sur l'écran.
Par contre lorsque t'ouvriras le fichier, tu verras que le contenu à l'instant de l'ouverture dudit fichier.
En C, tout simplement, tu lis le fichier. Il se mettra à jour tout seul. Tu te places à la fin du fichier. Et tu fais une boucle de lecture. Dès que le fichier grossira, ton programme C lira le changement.

Cdlt
0
Bonjour fiddy,

Non le problème est bien le décalage entre le remplissage de mon log et l'affichage en temps réél lors de l'affichage ds la console.
Pour être plus claire :
1)Je lance juste le binaire dans une console et je regarde l'évolution des sorties à l'écran sur les actions que je fais à l'aide de la télécommande la TVbox et là c'est nickel les infos dont j'ai besoin apparaissent bien en temps réél à l'écran.
2) maintenant, je lance le même binaire en faisant une redirection vers un fichier (# binaire > /mon_log.txt par ex). et là, la sortie dans mon log n'est plus temps réel , il me flush les lignes dans le log par bloc de 15 lignes.
Après avoir pas mal chercher depuis 2 jours, j'ai vu que le kernel linux éatit line buffered pour stdout,not buffered pour stderr et block buffered pour les écriture fichier (à priori un un buffer de 4096 o). D'où le décalage que je constate dans mon fichier log.
Ce que je voudrais, c'est qu'il écrive dans le fichier log comme il affiche à l'écran (line buffered me va très bien).
J'ia essayé pas mal de truc avec popen, spawn mais je n'arrive pas à bypasser ce buffer d'écriture ...

ça fait 2 jours que je galère la dessus ....

merci de ton aide.

AirSeb
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 840
11 mars 2009 à 15:56
Ah, je vois ce que tu veux dire.
As-tu essayé de réaliser un pipe : binaire | prog
Et prog est l'exécutable de prog.c qui copierait l'entrée dans un fichier en le flushant à chaque itération.
Sinon (plus propre), à la place de flusher tu peux utiliser : int setvbuf (FILE *stream, char *buf, int mode , size_t size); pour agir sur le type de buffer et le mettre en line buffered.
0
Salut fiddy,
partant de tes conseils j'ai essayé le code suivant :
# include <stdio.h>

int main () {
char c;
FILE *file;

file=popen("run_all","r");
setvbuf(file,NULL,_IONBF,0);
if (file==NULL){
printf("Error: can t open file.\n");
return 1;
}
else {
printf("[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[file opened sucessfully. Contents: \n\n");

while (1) { /* ---------------*/
fflush(file);
c=fgetc(file);
if (c!=EOF){
printf("%c",c);
if (c=='\n') {
printf("[[[[[");
}
}
else {
break;
}
}/* -------------------------*/

printf("\n\n Now closing file ...\n");
fclose(file);
return 0;
}
}

le binaire est bien entndu 'run_all', je le lance à travers mon code C avec un popen.
mais le résultat est le même , mon code affiche la sortie de 'run_all' avec le même décalage du au buffer block.
j'ai essayé de rajouter les deux lignes suivnates qui ne changent rien au comportement :
setvbuf(file,NULL,_IONBF,0);
fflush(file);

aurais-tu une idée pour forcer le binaire que je lance à travers popen de ne plus utiliser son buffer ???

merci d'avance.

je continue à chercher.

AirSeb
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 840
12 mars 2009 à 13:57
En fait, c'est pas comme ça que je pensais.
Par exemple, le programme donnerait :
//prog.c
int main(void) {
   char buffer[255];
   FILE *fp=fopen("log","w");
   if(fp==NULL) {
       fputs("erreur ouverture fichier\n",stderr);
       return 1;
   }
   
   while(1) {
       fgets(buffer,sizeof buffer,stdin);
       fputs(buffer,fp);
       fflush(fp);
   }
   fclose(fp),fp=NULL;

   return 0;
}

Et dans le shell, tu lances : $ binaire | prog
0
fiddy,

j'ai essayé avec ton code, mais même comportement.
idem en fait à faire une simple redirection sous le shell binaire >log.txt.
Le fichier s'incrémente bien à chaque vidage du buffer du binaire, mais pas en temps réel.

je pense qu'il faudrait arriver a forcer le binaire à ne pas utiliser de binaire pour sa sortie stdout... mais je ne sais pas comment arriver à faire ça.

c'est pour cela que j'étais parti avec un popen pour essayer de lui forcer son buffer .

si tu as une autre piste ...

merci

AirSeb
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 840 > AirSeb
12 mars 2009 à 15:11
Juste pour m'ôter d'un doute :vlorsque tu fais $ binaire > log et que dans une autre console tu fais, tail -f log
Qu'est-ce qui se passe ? (Ca s'affiche par bloc ?).
0
AirSeb > fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022
12 mars 2009 à 15:53
je viens de faire le test :

comportement normal dans la console 'binaire > log.txt', il affiche des infos, jusqu'à s'arréter avec des infos qui sont cachés dans le buffer

concernant la fenetre avec le tail, il pause avant d'afficher d'un bloc une liste d'information.
0
Char Snipeur Messages postés 9813 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 297
12 mars 2009 à 16:41
le problème semble venir du shell...
Je pense que dès qu'il détecte une écriture dans un fichier, c'est à dire indirection ou pipe (le pipe si j'ai bien comrpis la doc c'est en fait des indirections avec fichier temporaire), le shell buffeurise les écriture.
En regardant le man bash, j'ai trouver ça :
ulimit

              ulimit [-acdefilmnpqrstuvxSH] [limit]

    ulimit provides control over the resources available to processes started by the shell, on systems that allow such control. If an option is given, it is interpreted as follows:
[...]
    -p
        The pipe buffer size. 

http://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html
0
merci pour cette piste , malheureusement ca ne m'aide dans mon cas.
En effet le linux embarqué sur ma TVboc est minimaliste, et notamment cette commande 'ulimit' n'est pas dans le shell de base. je ne peux donc pas l'utiliser.
C'est don cmort, il n'ya pas un autre moyen d'arriver à bypasser le buffer en écriture du shell ????
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 840
12 mars 2009 à 17:46
Je promets rien mais tu peux voir du côté du kernel. /proc/sys/vm, tu dois pouvoir modifier ce comportement.
0
Char Snipeur Messages postés 9813 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 297
13 mars 2009 à 08:15
oui, et puis là, j'ai regarder le man bash. Si tu décortique le manuel de ton shell, tu y trouvera peut être quelque chose.
0