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 :

questions sur les pipes ?


Sujet :

Linux

  1. #1
    Nouveau membre du Club
    Inscrit en
    Décembre 2007
    Messages
    65
    Détails du profil
    Informations forums :
    Inscription : Décembre 2007
    Messages : 65
    Points : 35
    Points
    35
    Par défaut questions sur les pipes ?
    slt tt le monde :

    j'ai quelques questions concernant les pipes :

    1- d'abord , quand j'ai 3 commandes par exemples qui s'executent en pipe :
    commande1 | commande2 | commande3
    je dois créer en premier un seul tube ( int tube[2] ) que je vais utiliser d'abord entre
    commande 1 et commande2 , puis entre commande 2 et commande 3 ,ou bien je
    dois créer pour chaque | un tube ?

    2- et quand je crée des processus aux quels je vais faire du recouvrement pour
    chacun d'eux ( si je remplace le programme de chaque processus par un
    executable d'une commande de linux) , exemple : mkdir rep1 | ls
    que dois passer la commande mkdir a la commande ls comme paramétre ?
    je pense que ça se réalise a l'aide de la fonction write mais comment ? et que dois
    porter cette derniére comme paramétres ?? si vous pouvez me le montrer a traver
    un petit code ça sera mieux .

    3- derniérement , si j'ai commande 1;commande2 | commande 3
    a ce moment , c'est la commande 2 qui vas communiquer avec la commande 3 ?
    et y a pas d'echange entre commande1 et commande 3 ?

    merci d'avance

  2. #2
    Membre averti
    Inscrit en
    Septembre 2006
    Messages
    414
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 414
    Points : 354
    Points
    354
    Par défaut
    Citation Envoyé par laracroft87 Voir le message
    slt tt le monde :

    j'ai quelques questions concernant les pipes :

    1- d'abord , quand j'ai 3 commandes par exemples qui s'executent en pipe :
    commande1 | commande2 | commande3
    je dois créer en premier un seul tube ( int tube[2] ) que je vais utiliser d'abord entre
    commande 1 et commande2 , puis entre commande 2 et commande 3 ,ou bien je
    dois créer pour chaque | un tube ?

    2- et quand je crée des processus aux quels je vais faire du recouvrement pour
    chacun d'eux ( si je remplace le programme de chaque processus par un
    executable d'une commande de linux) , exemple : mkdir rep1 | ls
    que dois passer la commande mkdir a la commande ls comme paramétre ?
    je pense que ça se réalise a l'aide de la fonction write mais comment ? et que dois
    porter cette derniére comme paramétres ?? si vous pouvez me le montrer a traver
    un petit code ça sera mieux .

    3- derniérement , si j'ai commande 1;commande2 | commande 3
    a ce moment , c'est la commande 2 qui vas communiquer avec la commande 3 ?
    et y a pas d'echange entre commande1 et commande 3 ?

    merci d'avance
    1 - il faut absolument 2 pipes car l'appel a read doit forcement être bloquant au niveau de la lecture du pipe vu que les deux processus sont executés "en meme temps"

    2 - mkdir rep1 | ls ?? as tu réélement compris ce qu'il se passait ? tu ne peux pas faire ca ! ls n'attend rien de STDIN (du clavier quoi...) et surtout mkdir n'ecris rien sur STDOUT (ecran) donc cette redirection ne sert strictement a rien...
    sinon la commande de gauche ne passe pas de paramètre à la commande de droite:
    imagine que la comande de droite va faire un appel a scanf (ou autre fonction de lecture du clavier) et bien scanf est grosso modo un write(STDIN...)
    la redirection consiste à remplacer STDIN par le coté d'un tube
    de meme pour la coammnde de gauche, printf correspond a un write(STDOUT...)
    dans ce cas la, la redirection consiste a remplacer STDOUT par l'autre bout du tube !

    3 - non pas de redirection entre commande1 et commande3

  3. #3
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 730
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 730
    Points : 31 053
    Points
    31 053
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par laracroft87 Voir le message
    slt tt le monde :

    j'ai quelques questions concernant les pipes :

    1- d'abord , quand j'ai 3 commandes par exemples qui s'executent en pipe :
    commande1 | commande2 | commande3
    je dois créer en premier un seul tube ( int tube[2] ) que je vais utiliser d'abord entre
    commande 1 et commande2 , puis entre commande 2 et commande 3 ,ou bien je
    dois créer pour chaque | un tube ?

    2- et quand je crée des processus aux quels je vais faire du recouvrement pour
    chacun d'eux ( si je remplace le programme de chaque processus par un
    executable d'une commande de linux) , exemple : mkdir rep1 | ls
    que dois passer la commande mkdir a la commande ls comme paramétre ?
    je pense que ça se réalise a l'aide de la fonction write mais comment ? et que dois
    porter cette derniére comme paramétres ?? si vous pouvez me le montrer a traver
    un petit code ça sera mieux .

    3- derniérement , si j'ai commande 1;commande2 | commande 3
    a ce moment , c'est la commande 2 qui vas communiquer avec la commande 3 ?
    et y a pas d'echange entre commande1 et commande 3 ?

    merci d'avance
    Pour être très simple:
    1) toute commande qui écrit un truc à l'écran peut envoyer ce truc dans un pipe => commande | ... => exemple: ls -l
    2) toute commande qui attend un truc du clavier peut prendre ce truc d'un pipe => ... | commande
    Ainsi, le pipe permet d'envoyer le résultat (affiché par la commande 1) dans l'entrée de la commande 2 => ls -l | wc => tout ce qui est affiché par "ls -l" sera compté par "wc"

    Ce mécanisme permet d'emboiter des suites de commandes pour exécuter des actions précises mais complexes...

    Exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cat /etc/passwd | sort | tr '[:lower:]' '[:upper:]' | sed -e "s/:/ /g" | awk '{printf("%s\n", $0); if ((NR % 5) == 0) printf("\n")}'
    1) le cat affiche le fichier
    2) le sort trie cet affichage
    3) le tr transforme toutes les minuscules en majuscules
    4) le sed convertis chaque ":" en espace
    5) le awk insère une ligne vide toute les 5 lignes
    Ce qui me produit en final un listing aéré du fichier "/etc/passwd"
    ...

    Bien entendu, envoyer mkdir dans un pipe est absurde. La commande mkdir n'affiche rien. De même envoyer un truc dans "ls" est aussi absurde, la commande "ls" n'attend rien du clavier...

  4. #4
    Nouveau membre du Club
    Inscrit en
    Décembre 2007
    Messages
    65
    Détails du profil
    Informations forums :
    Inscription : Décembre 2007
    Messages : 65
    Points : 35
    Points
    35
    Par défaut
    re !!
    merci a vous tous , j'ai tres bien compris le principe des pipe , juste il reste une
    petite ambiguité, je viens de realiser un mini-shell qui traite les commandes en pipe,
    lorsque deux commandes en pipes qui sont tapé, disant : cat /etc/passwd | sort

    - d'abord je dois créer un tube ( int tube [2] ) ,
    - j' appelle la fonction pipe( tube ) , qui est de l'entête < unistd.h >
    - puis je crée deux processus a l'aide du fork()
    - le premier ferme le destripteur close ( tube[1] ), et le deuxiéme ouvre le le
    descripteur tube [0] par open( tube[0] );
    - mais la premier processus (celui de la commande cat )est ce que je lui fait un
    recouvrement ( c'est a dire je remplace son code par l'executable de la fonction cat)
    ou pas ??
    - ensuite que doit ecrire le processus de la commande cat dans le stdout a l'aide de la
    fonction write !!

    et si vous pouvez me le montrer avec un petit code ça sera encore mieux

    merci encore une fois

  5. #5
    Membre averti
    Inscrit en
    Septembre 2006
    Messages
    414
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 414
    Points : 354
    Points
    354
    Par défaut
    je t'ai deja donné un code qui le fait (avec les explications):
    http://www.developpez.net/forums/d72...availler-pipe/

  6. #6
    Nouveau membre du Club
    Inscrit en
    Décembre 2007
    Messages
    65
    Détails du profil
    Informations forums :
    Inscription : Décembre 2007
    Messages : 65
    Points : 35
    Points
    35
    Par défaut
    re
    pouvez vous me dire a quoi sert cette duplication pour les deux processus, ou il y a des etoiles *********
    en plus la fermeture des deux descripeteurs pfd[0] , et pfd[1] pourquoi elle est refaite deux fois @@@
    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
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
     
    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    main(void)
    {
          int pfd[2];
          if (pipe(pfd) == -1)
                syserr("pipe");
          switch (fork()) {
          case -1:
                syserr("fork");
          case 0:
                if (close(1) == -1)
                       syserr("close");
                if (dup(pfd[1]) != 1)  ******************
                       syserr("dup");
                if (close(pfd[0]) == -1 || close(pfd[1]) == -1)    @@@
                       syserr("close2");
                execlp("who","who",NULL);
                syserr("execl");
          }
          switch (fork()) {
          case -1:
                syserr("fork");
          case 0:
                if (close(0) == -1)
                       syserr("close3");
                if (dup(pfd[0]) != 0)
                       syserr("dup3");
                if (close(pfd[0]) == -1 || close(pfd[1]) == -1)   @@@
                       syserr("close4");
                execlp("wc","wc",NULL);
                syserr("execl2");
          }
          if (close(pfd[0]) == -1 || close(pfd[1]) == -1)
                syserr("close5");
          while (wait(NULL) != -1);
    }
    /*-----------------------------------------------------------------*/
    /*            Traitement des erreurs                               */
    /*-----------------------------------------------------------------*/
    syserr(char *s)
    {
          printf("erreur de la primitive ");
          printf("%s\n",s);
          exit(1);
    }


    oui je l'ai vu cette exemple , mais moi je veux generaliser ma fonction ,si j'ai plusieurs commandes en pipe disant N dont je ne connais pas le nombre exacte , comment faire a ce moment la ?? je pense pas que je peux utiliser un tableau de N descripteurs car déja la fontion pipe() ne le permet pas , mais est ce que je peux utiliser le tube ( int tube[2] )
    une fois entre commande1 | commande2 et puis commande 2 | commande 3 et ainsi de suite ??
    merci d'avance

  7. #7
    Membre averti
    Inscrit en
    Septembre 2006
    Messages
    414
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 414
    Points : 354
    Points
    354
    Par défaut
    dup duplique un desctipteur de fichier a la premiere position disponible dans la table des descripteurs de fichier

    dans notre cas la table contient:
    0,1,2,3,4
    ou 0 == stdin
    1 == stdout
    2 == stderr
    3 == pfd[0]
    4 == pfd[1]

    or on ferme 1
    on a donc:
    0,vide,2,3,4

    en appelant dup(pfd[1]) on copie le descrpteur pfd[1] a la premiere place dispo:
    on obtien alors:
    0,5,2,3,4

    pour plus de details:
    man 2 dup

    sinon pour ton autre question, apres un fork, il me semble que le compteur d'utilisation des descripteurs de fichier partagés sont incrémentés, il faut absolument que les deux fils ferment chaque descripteur pour que le compteur d'utilisation redevienne egal a 0 et ainsi libérer l'inode.
    je ne suis pas sur a 100% de ce dernier point, mais c'est grosso modo ca...

  8. #8
    Nouveau membre du Club
    Inscrit en
    Décembre 2007
    Messages
    65
    Détails du profil
    Informations forums :
    Inscription : Décembre 2007
    Messages : 65
    Points : 35
    Points
    35
    Par défaut
    re
    encore une question ?
    la sortie standard du systéme est représenté par ( pfd[1] dans notre cas ) qui est totalement differentes de la sortie standard du processus ? la meme chose pour l'entrée !!
    merci pour votre aide

  9. #9
    Membre averti
    Inscrit en
    Septembre 2006
    Messages
    414
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 414
    Points : 354
    Points
    354
    Par défaut
    non
    la sortie standard c'est 1
    y'a une petite betise dans le code que je t'ai donné, il aurait etait plus correcte (est plus portable) de remplacer 1 par pfd[0] et non pfd[1]
    et 0 par pfd[1] dans l'autre processus..
    mais ca marche quand meme depuis la version v 4 d'unix. pfd[1] et pfd[0] peuvent etre utilisé en ecriture et en lecture depuis.

    pour en revenir a ta question, oui pfd[1] est totalement different de la sortie standard.
    Mais dans notre exemple on remplace la sortie standard par pfd[1] ! pour faire la redirection:
    au lieu d'ecrire les caracteres sur le flux standard de sortie,, on l'ecrit dans le tube, pour que l'autre processus puisse lire ces caracteres de l'autre coté du tube et faire ses traitements !
    de meme, pour l'autre processus, l'entrée standard (cad le clavier) est remplacée par pfd[0]
    ce qui fais que le processus aura l'impression que l'utilisateur tapera quelque chose au clavier quand l'autre ecrira dans le tube !

  10. #10
    Nouveau membre du Club
    Inscrit en
    Décembre 2007
    Messages
    65
    Détails du profil
    Informations forums :
    Inscription : Décembre 2007
    Messages : 65
    Points : 35
    Points
    35
    Par défaut
    slt kamou
    normalement c'est compris , je vais essaié mon pgmme en espérant que j'aurrais pas de pblme
    merci bcp

  11. #11
    Nouveau membre du Club
    Inscrit en
    Décembre 2007
    Messages
    65
    Détails du profil
    Informations forums :
    Inscription : Décembre 2007
    Messages : 65
    Points : 35
    Points
    35
    Par défaut
    re
    SVP pouvez vous regarder mon code, c'est un petit programme qui traitent des commandes en pipe , il m'affiche comme erreur lors de l'execution :
    entrée standard: Mauvais descripteur de fichier

    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
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    #include<stdio.h>
    #include<string.h>
    #include<unistd.h>
    #include<stdlib.h>
    int main()
    {
      char commande[80];
      char *file;
      char *argv[10];
      char *buffer,*res,*com,*comup,*B,*resn;
      int tube[2];
      int n=0,i=0,k=0;
      printf(" entrer des commandes qui contiennet des pipes | SVP \n");
      scanf("%[^\n]",commande); // commande contient au moins un |
      pipe(tube);
      com = strdup(commande);
      res = strtok_r(com,"|",&buffer);
      if (res != NULL)
      {
        switch (fork())
        {
          case 1:
           if (n==0)
           { //*
             n++;
             if (close(1) == -1)  printf("erreur de close \n");
             if (dup(tube[0]) == -1)  printf(" erreur de duplication \n");
             comup =strdup(res);
             resn= strtok_r(res," ",&B);
             if (resn != NULL) file =resn; else resn=com;
             i=0;
             while(resn != NULL)
             {
               argv[i]=resn;
               i++;
               resn = strtok_r(NULL," ",&B);
             }
              execvp(file,argv);
           } //*
           wait(0);
          case 0:
           if (k==0)
             res = strtok_r(NULL,"|",&buffer);
           if (close(0) == -1) printf("erreur de close() \n");
           if (dup(tube[1])) printf("erreur de dup \n");
           comup = strdup(res);
           resn = strtok_r(comup," ",&B);
           if (resn != NULL) file =resn; else resn=com;
           i=0;
           while(resn != NULL)
           {
             argv[i]=resn;
             i++;
             resn = strtok_r(NULL," ",&B);
           }
           argv[i]=NULL;
           if (( strtok_r(NULL,"|",&buffer) != NULL ) && (close(1) != -1) && (dup(tube[0])!= -1)) break;
           execvp(file,argv);
         }
       }  
     
    return 0;
    }
    merci d'avance

  12. #12
    Membre averti
    Inscrit en
    Septembre 2006
    Messages
    414
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 414
    Points : 354
    Points
    354
    Par défaut
    j'ai pas vu tout ton code, mais
    ne veut absolument rien dire !
    fork retourne:
    0 dans le cas du fils
    un entier correspondant au pid du fils dans le cas du pere
    ou -1

    a remplacer par
    et ne pas oublier de verifier le cas -1

  13. #13
    Nouveau membre du Club
    Inscrit en
    Décembre 2007
    Messages
    65
    Détails du profil
    Informations forums :
    Inscription : Décembre 2007
    Messages : 65
    Points : 35
    Points
    35
    Par défaut
    slt encore une fois :
    j'ai changé mon code mais cette fois ci il m'affiche " aucun fichier ou dossier de ce type "
    et je pense que le programme plante auniveau de la fontion close(1) , mais je ne sais pas pourquoi ? voici le nouveau 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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    #include<stdio.h>
    #include<string.h>
    #include<unistd.h>
    #include<stdlib.h>
    int main()
    {
      char commande[80];
      char *comdup,*result,*buffer,*resultat,*com,*buf,*file;
      char *argv[10];
      int tube[2];
      int i=0,n=0;
     
      if (pipe(tube) == -1) printf("erreur de la primitive pipe"); 
      scanf("%[^\n]",commande);
      comdup = strdup(commande);
      result = strtok_r(comdup,"|",&buffer);
      while (result != NULL )
       {   
           resultat = strdup(result);
           com = strtok_r(resultat," ",&buf);
           file = com;
           argv[i]= com; 
     
     
        if (com != NULL) file = com; else com = result ;
        while(com != NULL)
        {
          argv[i]=com;
          i++;
          com = strtok_r(NULL," ",&buf);
        }
         argv[i]=NULL;
     
           switch (fork())
              {
                 case -1:
                    exit(1);
                 case 0:
                    if ( n != 0) { if ((close(0)== -1) && (dup(tube[0]) != 0)) printf("erreur \n"); }
                    result = strtok_r(NULL,"|",&buffer);
                    if ( result != NULL )
                      {         
                          if (close(1) == -1) printf("erreur de close \n"); // *********************
                          if ( dup(tube[1])!= 1)  printf("erreur de duplic !! \n");
                      }        
                    execvp(file,argv);  
                    exit(0);
     
     
                 default :
                    n=1;
                    wait(0);
                    result = strtok_r(NULL,"|",&buffer);
              }    
       }
     
    return 0;
    }
    merci bcp d'avoir m'aider

  14. #14
    Membre averti
    Inscrit en
    Septembre 2006
    Messages
    414
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 414
    Points : 354
    Points
    354
    Par défaut
    ce code ne nous donne pas trop envie de t'aider !
    choisi des noms de variables plus explicite...comment veux tu qu'on comprenne quelque chose comme: result, resultat, file...

    je te conceil de recommencer et de reflechir un peut avant de coder.
    essaye deja une premiere version sans prendre en compte les arguments, si c'est bien codé, tu n'aura pas de probleme pour rajouter la gestion des arguments plus tard.

    ton code gére plusieurs pipes ? si c'est le cas, tu a besoin d'autant de tubes que de "|"... mais je ne pense pas que ce soit l'unique probleme...

  15. #15
    Nouveau membre du Club
    Inscrit en
    Décembre 2007
    Messages
    65
    Détails du profil
    Informations forums :
    Inscription : Décembre 2007
    Messages : 65
    Points : 35
    Points
    35
    Par défaut
    re
    oui c'est exactement ça , j'essaie de gerer plusieurs pipe avec 1 seul tube mais apparament
    ce n'est pas réalisable , mais le pblme je ne connais pas le nombre de " | " que j'ai a l'avance pour déclarer autant que de tube que de "|"? ça me soucie vraiment
    merci

  16. #16
    Membre averti
    Inscrit en
    Septembre 2006
    Messages
    414
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 414
    Points : 354
    Points
    354
    Par défaut
    non, ce n'est pas réalisable, et je t'ai expliqué pourquoi plus haut.
    tu as deux solutions pour le faire: soit compter le nombre de pipe dont tu aura besoin, puis les allouer dinamiquement avec un malloc.
    soit definir un nombre maximum de pipe et t'assurer qu'on ne le depassera pas.
    MAIS ce n'est pas le seul probleme de ton code (avec un seul pipe ton code ne fonctionne quand meme pas)

  17. #17
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 730
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 730
    Points : 31 053
    Points
    31 053
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par laracroft87 Voir le message
    oui c'est exactement ça , j'essaie de gerer plusieurs pipe avec 1 seul tube
    Arf. Remplace dans ta phrase le mot "pipe" par "tube" (ou "tube par "pipe" car les deux mots signifient la même chose) et tu verras tout de suite le paradoxe

    Citation Envoyé par laracroft87 Voir le message
    mais le pblme je ne connais pas le nombre de " | " que j'ai a l'avance pour déclarer autant que de tube que de "|"? ça me soucie vraiment
    merci
    Arf c'est un problème qu'on retrouve souvent en C => devoir stocker des éléments sans savoir à l'avance combien on en aura => c'est pour ça qu'il existe malloc et realloc...

Discussions similaires

  1. Petite question sur les performances de Postgres ...
    Par cb44 dans le forum PostgreSQL
    Réponses: 5
    Dernier message: 13/01/2004, 13h49
  2. question sur les vertex buffer et index buffer
    Par airseb dans le forum DirectX
    Réponses: 9
    Dernier message: 25/08/2003, 02h38
  3. question sur les variables globales et les thread posix
    Par souris_sonic dans le forum POSIX
    Réponses: 5
    Dernier message: 13/06/2003, 13h59
  4. Question sur les handles et les couleurs...
    Par MrDuChnok dans le forum C++Builder
    Réponses: 7
    Dernier message: 29/10/2002, 08h45
  5. question sur les message box !
    Par krown dans le forum Langage
    Réponses: 7
    Dernier message: 02/08/2002, 16h11

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