IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Linux Discussion :

Detournement du stdin ca ne marche pas !!!


Sujet :

Linux

  1. #1
    Membre régulier
    Inscrit en
    Septembre 2003
    Messages
    222
    Détails du profil
    Informations forums :
    Inscription : Septembre 2003
    Messages : 222
    Points : 91
    Points
    91
    Par défaut Detournement du stdin ca ne marche pas !!!
    Bonjour,
    voila j'aimerai disposer d'un programme qui me permette de détourner le flux stdin via un fichier (je developpe en c)

    Je fais donc ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    FILE * strmin = freopen("stdin.txt", "rt", stdin);
    if (strmin == NULL)
    #error
    else
    #c'est ok !
    Et plus loin dans le code lorsque je désire attendre des données sur l'entrée standard (stdin) qui est détournée je fais:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    while ( (c = (char) getc(stdin) ) < 0)
    {
    //On attend car nous lisons le caracteres de FIN de fichier (EOF)
    }
    //On sort de la boucle et on peut traiter le char. (genre putchar)
    Le probleme que j'ai, c'est que lorsque je vais ouvrir mon fichier "stdin.txt" avec un editeur de texte (emacs par exemple) et que j'y ajoute des données (du texte) JAMAIS je ne sors de cette maudite boucle !!

    (J'ai aussi essayé en passant par un select c'est la même chose)

    Pourtant cette solution fonctionne très bien sous Windows !
    Alors pourquoi ne fonctionne t'elle pas sous Linux ? (Red hat 9)

    Je suis impacient de connaitre vos remarques sur mon problème !!

    Merci d'avance

  2. #2
    Membre expérimenté
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Points : 1 664
    Points
    1 664
    Par défaut
    Ton utilisation de getc() est incorrecte. Si getc() renvoie un int, ce n'est pas pour faire joli, c'est parce qu'un char (considere comme unsigned par getc() et consorts) peut ne pas pouvoir contenir EOF (par exemple sous Linux, ou il vaut -1).

    Il faut donc faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
      int c;
      while ( (c = fgetc(stdin) ) != EOF)
      {
           /* la fin de fichier n'est pas atteinte */
      }

  3. #3
    Membre régulier
    Inscrit en
    Septembre 2003
    Messages
    222
    Détails du profil
    Informations forums :
    Inscription : Septembre 2003
    Messages : 222
    Points : 91
    Points
    91
    Par défaut
    Désolé j'ai mal du m'exprimé..

    Ce que je veux c'est que le programme sorte de la boucle while dès le moment où de nouvelles données sont inscrites dans le fichier.

    Admettons que l'on modifie ton code en:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    int c;
    while ( (c == fgetc(stdin) ) == EOF )
    {
    //On boucle tant que l'on est à la fin du fichier
    }
    Maintenant que le programme est lancé, je vais ecrire dans le fichier et la ... je ne sors toujours pas de la boucle !

    Je ne sais vraiment pourquoi !

    PS: Merci quand même et désolé de m'être mal exprimé!

  4. #4
    Membre régulier
    Inscrit en
    Septembre 2003
    Messages
    222
    Détails du profil
    Informations forums :
    Inscription : Septembre 2003
    Messages : 222
    Points : 91
    Points
    91
    Par défaut
    En gros, je veux bloquer mon programme pour qu'il soit en écoute à la fin de mon fichier... rendre le fgetc blaquant !

  5. #5
    Membre du Club
    Inscrit en
    Décembre 2003
    Messages
    56
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 56
    Points : 47
    Points
    47
    Par défaut
    essaye d'utiliser la commande dup()

  6. #6
    Membre régulier
    Inscrit en
    Septembre 2003
    Messages
    222
    Détails du profil
    Informations forums :
    Inscription : Septembre 2003
    Messages : 222
    Points : 91
    Points
    91
    Par défaut
    Pour l'instant voila ce que je fais:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    strmin = freopen(pathin, "rt", stdin );  
    if( strmin == NULL )
     {
        printf("detournement IMPOSSIBLE du stdin\n");
     }
      else
      {
       printf("detournement du stdin\n");
        while(1)
        {
        while ((ic = (int)fgetc(stdin)) == EOF)            
        {         
        }
        c[0] = (char)ic;
        fprintf(stdout,"-%c[%i]-", c[0], ic);
    }
    Bon, après plusieurs cas de tests j'ai reussi à conclure cela de mon programme:
    Le fichier doit être ouvert avant de lancer le programme

    En effet, si j'ouvre le fichier "stdin.txt" et que je lance mon programme et que j'ecris dans le fichier des données (caractères + retour à la ligne) et que je sauvegarde alors dans ce cas le programme detecte qu'il y a eu une modification et affiche ce que j'ai tapé

    Maintenant si je ferme mon fichier et je le ré-ouvre, ca ne marche plus.
    De même si j'ouvre mon fichier apres avoir lancé mon executable.

    Je pense donc que mon programme perd le descripteur de mon fichier des qu'une autre application ouvre mon fichier !

    D'ou l'utilité peut etre d'un DUP (duplication de descripteur)
    Mais dans mon cas je ne vois pas comment l'utiliser.

    j'ai donc un peu chercher sur le net et j'ai testé cela:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    FD_ZERO(&rfds);
    FD_SET(0, &rfds);
    ds = dup(0);
    n = select(1, &rfds, NULL, NULL, NULL);
    while(read(ds, &chaine, 1))
    {
    printf("%c-", chaine);      
    ds = dup(0);
    n = select(1, &rfds, NULL, NULL, NULL);
    Le probleme c'est que je sors toujours du select (lecture d'un caractère ou d'une fin de fichier..

    Je ne sais plus quoi faire...
    Pourtant je semble être proche du résultat que j'attends...

    Je vais donc esperer que quelqu'un pourra m'aider dans cette lutte pour détourner le stdin...

    Merci d'avance

  7. #7
    Membre expérimenté
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Points : 1 664
    Points
    1 664
    Par défaut
    Avec cet exemple simple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    #include <stdio.h>
     
    int main(void)
    {
      FILE *f;
      int c;
     
      f = freopen("toto.txt", "w+", stdin);
      if(f)
      {
        while(1)
        {
          while( (c = fgetc(stdin) ) == EOF) ;
          printf("%c\n", c); 
        } 
      }
      return 0;
    }
    j'obtiens le meme resultat que toi (j'ouvre en w+ pour forcer la creation du fichier au cas ou il n'existerait pas au debut du programme - remarque que le "rt" que tu utilises n'est pas standard - j'ai egalement supprime des transtypages inutiles).

    En editant le fichier les modifications sont reconnues (des que le fichier est sauvegarde, evidemment, car mon editeur utilise un fichier temporaire)...

    Si je ferme puis ouvre le fichier dans mon editeur, les modifications sont encore prises en compte, contrairement a ce que tu observes. Cela depend peut-etre de l'editeur utilise (il est possible que certains effacent/renomment un fichier a la fermeture).

    Par contre, si le fichier est efface puis re-cree alors que le programme tourne, les modifications ne sont plus reconnues -> c'est comprehensible, puisque le descripteur pointe vers un emplacement desormais invalide. Il faudrait inclure un test d'existence du fichier pour faire une reouverture le cas echeant.

    A priori, je ne vois pas de comportement anormal...

  8. #8
    Membre régulier
    Inscrit en
    Septembre 2003
    Messages
    222
    Détails du profil
    Informations forums :
    Inscription : Septembre 2003
    Messages : 222
    Points : 91
    Points
    91
    Par défaut
    Je pars de suite ré-essayer avec ton exemple...

  9. #9
    Membre régulier
    Inscrit en
    Septembre 2003
    Messages
    222
    Détails du profil
    Informations forums :
    Inscription : Septembre 2003
    Messages : 222
    Points : 91
    Points
    91
    Par défaut
    Le problème ne vient donc pas de mon application !!!
    Il me suffit juste de ne pas utiliser emacs pour éditer mon fichier stdin.txt
    Lorsque j'ai utilisé kwrite par exemple, et bien je n'ai pas eu le problème !!!
    Et bien j'en ai testé des trucs pour pas grand chose !!!!

    Merci en tout cas pour vos aides !!!

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. 'SHOW TABLES' marche pas sous postgresql !?
    Par fet dans le forum PostgreSQL
    Réponses: 4
    Dernier message: 13/05/2004, 09h28
  2. Maximiser fenêtre ne marche pas
    Par sandrinec dans le forum Composants VCL
    Réponses: 2
    Dernier message: 12/06/2003, 12h02
  3. Réponses: 9
    Dernier message: 07/05/2003, 12h57
  4. [GifDecoder] marche pas dans applet avec IE
    Par formentor dans le forum Applets
    Réponses: 2
    Dernier message: 06/05/2003, 10h43
  5. Sysdate qui marche pas ??
    Par StouffR dans le forum Langage SQL
    Réponses: 4
    Dernier message: 28/08/2002, 13h23

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo