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 :

Redirection de stdout en C


Sujet :

Linux

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Rédacteur

    Avatar de gege2061
    Femme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2004
    Messages
    5 840
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Juin 2004
    Messages : 5 840
    Par défaut Redirection de stdout en C
    Bonjour,

    j'ai voulu m'amuser un peu avec les redictions mais je crois que je suis tombé sur un os

    Je code en GTK+ et la redirection se fait dans un thread à part du reste du programme (je problème vient peut être de là), voici le code de redirection simplifié :
    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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
        int fd[2];
        gchar text[BUFSIZ] = "";
        FILE *stream;
     
        if (pipe (fd) == 0)
        {
          dup2 (fd[1], STDOUT_FILENO);
          fclose (stdout);
          stdout = fdopen (fd[1], "w");
          stream = fdopen (fd[0], "r");
          if (stream && stdout)
          {
            printf ("printf\n");
            fflush (stdout);
            fprintf (stdout, "fprintf\n");
            fflush (stdout);
            write (STDOUT_FILENO, "write\n", 6);
            while (GTK_IS_STDOUT_VIEW (p_stdout_view))
            {
              if (fgets (text, BUFSIZ, stream))
              {
    /* redirection */
              }
            }
          }
          else
          {
            printf ("Erreur\n");
          }
        }
    ce qui est drole c'est que fprintf (srdout, ...) marche mais pas printf
    Pour continuer dans le commique, la redirection ne marche pas dans le reste du progamme.

    Bien sur j'ai essayé quelques combinaisons tel que :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    /*      dup2 (fd[1], STDOUT_FILENO);*/
          fclose (stdout);
          stdout = fdopen (fd[1], "w");
          stream = fdopen (fd[0], "r");
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
          dup2 (fd[1], STDOUT_FILENO);
          fclose (stdout);
          stdout = fdopen (STDOUT_FILENO, "w");
          stream = fdopen (fd[0], "r");
    Mais ça va du segfault à la perte des données.

    J'ai fait quelque chose de travers ?

  2. #2
    Rédacteur

    Avatar de gege2061
    Femme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2004
    Messages
    5 840
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Juin 2004
    Messages : 5 840
    Par défaut
    Bon j'ai retravaillé un peu le code :
    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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
     
    int main (void)
    {
      int fd[2];
     
      if (pipe (fd) == 0)
      {
        char text[BUFSIZ];
        FILE *stream = NULL;
     
        fclose (stdout);
        stdout = fdopen (fd[1], "w");
        stream = fdopen (fd[0], "r");
        printf ("printf\n");
        fflush (stdout);
        fprintf (stdout, "fprintf\n");
        fflush (stdout);
        system ("echo system");
        while (fgets (text, BUFSIZ, stream))
        {
          fprintf (stderr, "stdout : %s\n", text);
        }
        fclose (stream); stream = NULL;
      }
      return 0;
    }
    Et le résultat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    gege2061@debian:~/Desktop/flux$ gcc -Wall -W -Werror -O2 main.c
    gege2061@debian:~/Desktop/flux$ ./a.out
    sh: line 0: echo: write error: Mauvais descripteur de fichier
    stdout : fprintf
    ^D
    gege2061@debian:~/Desktop/flux$
    Et bien sûr ce qui m'interesse c'est de rediriger la sortie de la commande echo

  3. #3
    Expert confirmé

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Par défaut
    J'ai bidouiller avec ton code et en effet, cela ne marche pas avec ta version (logique, vu que tu postes quelque chose )

    Lorsque je m'amuse à faire des redirections, j'ai une tendance à partir dans le non portable et fermer directement le descripteur de fichier 1 pour l'écriture.

    En testant ce code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
       FILE *stream;
     
        out = dup(1);
        close(1);
     
        dup(fd[1]);
     
        stream = fdopen (fd[0], "r");
    J'obtiens dans ta boucle la sortie du printf, du fprintf et du echo. Pas forcèment la meilleure solution vu qu'on utilise dup/close mais bon... C'est déjà une solution intermédiaire.

  4. #4
    Rédacteur

    Avatar de gege2061
    Femme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2004
    Messages
    5 840
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Juin 2004
    Messages : 5 840
    Par défaut
    Citation Envoyé par fearyourself
    Pas forcèment la meilleure solution vu qu'on utilise dup/close mais bon... C'est déjà une solution intermédiaire.
    C'est une solution qui marche c'est déjà ça. Merci pour ton aide

  5. #5
    Rédacteur

    Avatar de gege2061
    Femme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2004
    Messages
    5 840
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Juin 2004
    Messages : 5 840
    Par défaut
    Bon je crois que je me suis compliqué

    J'ai un peu fouiller la glib est j'ai trouvé : g_spawn_async_with_pipes et une fois le descripteur de fichier récupérer, il suffit de l'ouvrir avec g_io_channel_unix_new et en plus c'est portable

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

Discussions similaires

  1. Redirection de stdout en C vers Python
    Par makia42 dans le forum PyQt
    Réponses: 11
    Dernier message: 05/04/2011, 21h03
  2. Réponses: 4
    Dernier message: 16/04/2008, 19h54
  3. redirection de stdout
    Par tet.dum dans le forum C
    Réponses: 12
    Dernier message: 19/09/2007, 21h40
  4. Redirection stdin / stdout
    Par Neitsa dans le forum Linux
    Réponses: 3
    Dernier message: 17/02/2007, 15h57

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