Utilisation de la fonction pipe

Résolu
Utilisateur anonyme -  
mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   -
Bonsoir,
j'aimerais avoir de l'aide concernant la fonction pipe .
avez vous des site qui explique non pas la théorie (que j'ai déjà bien compris) mais plutôt comment l'exploiter dans mon code ?
ce site est vraiment bien mais je ne parviens pas a réussir quand même
=> http://www.zeitoun.net/articles/communication-par-tuyau/start

en effet .
ont envoie a pipe uniquement des descripteur de fichier qui contienne deux entier (lecture / écriture )
alors comment faire pour faire transiter un string (par exemple) d'un processus père a son fils ?

merci de votre aide !

1 réponse

  1. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 940
     
    Il est toujours bon de savoir faire des pipes. Voici à toute fin utile un exemple de code que j'ai écrit il y a quelques temps en me basant sur un exemple que j'avais trouvé bien détaillé sur le net :
    https://stackoverflow.com/questions/478898/how-do-i-execute-a-command-and-get-the-output-of-the-command-within-c-using-po

    Dans cet exemple, un processus parent écrit des bytes (ceux d'un paquet) qui transmis par le biais d'un pipe à tcpdump, un outil permettant d'afficher le contenu d'un paquet de manière compréhensible par l'homme :

    #include <cassert>      // assert
    #include <cstdlib>      // exit
    #include <string>       // std::string
    #include <iostream>     // std::cout, std::endl
    #include <unistd.h>     // dup2, fork
    #include <sys/types.h>  // waitpid
    #include <sys/wait.h>   // waitpid
    #include <cerrno>       // errno
    #include <sstream>
    
    #define ASSERT_NOT(x, y) assert((x) != (y))
    #define ASSERT_IS(x, y)  assert((x) == (y))
    #define FAIL(x) std::cerr << (x)
    
    enum PIPE_FILE_DESCRIPTERS
    {
        READ_FD  = 0,
        WRITE_FD = 1
    };
    
    enum CONSTANTS
    {
      BUFFER_SIZE = 100
    };
    
    
    
    int main()
    {
        int         parentToChild[2];
        int         childToParent[2];
        pid_t       pid;
        std::string dataReadFromChild;
        char        buffer[BUFFER_SIZE + 1];
        ssize_t     readResult;
        int         status;
    
    
        const char * packet = "\\xd4\\xc3\\xb2\\xa1\\x02\\x00\\x04\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\xff\\xff\\x00\\x00\\x09\\x00\\x00\\x00\\x0c\\x00\\x00\\x00\\x7b\\x15\\x03\\x00\\x42\\x00\\x00\\x00\\x42\\x00\\x00\\x00\\x00\\x21\\x45\\x00\\x00\\x40\\x00\\x00\\x00\\x00\\x01\\x59\\x00\\x00\\x01\\x01\\x02\\x02\\xe0\\x00\\x00\\x05\\x02\\x05\\x00\\x2c\\x01\\x01\\x04\\x01\\x00\\x00\\x00\\x00\\xc3\\x32\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01\\x02\\x01\\x01\\x01\\x03\\x01\\x01\\x01\\x03\\x01\\x80\\x00\\x00\\x0b\\xab\\x4c\\x00\\x3c";
    
        ASSERT_IS(0, pipe(parentToChild));
        ASSERT_IS(0, pipe(childToParent));
    
        switch (pid = fork())
        {
            case -1:
                FAIL("Fork failed");
                exit(-1);
    
            case 0: /* Child */
                ASSERT_NOT(-1, dup2(parentToChild[READ_FD],  STDIN_FILENO));
                ASSERT_NOT(-1, dup2(childToParent[WRITE_FD], STDOUT_FILENO));
                ASSERT_NOT(-1, dup2(childToParent[WRITE_FD], STDERR_FILENO));
                ASSERT_IS(0, close(parentToChild[WRITE_FD]));
                ASSERT_IS(0, close(childToParent[READ_FD]));
    
                /*   file,  arg0,  arg1,   arg2 */
                /*
                {
                    execlp("ls", "ls", "-al", "--color", NULL);
                }
                */
    
                {
                    std::ostringstream oss;
                    oss << "/bin/echo -ne \"" << packet << "\" | /usr/sbin/tcpdump -nnv -r -" << std::endl;
                    const char * command = oss.str().c_str();
                    exit(system(command));
                }
    
                FAIL("This line should never be reached!!!");
                exit(-1);
    
    
            default: /* Parent */
                std::cout << "Child " << pid << " process running..." << std::endl;
    
                ASSERT_IS(0, close(parentToChild[READ_FD]));
                ASSERT_IS(0, close(childToParent[WRITE_FD]));
    
                while (true) {
                    switch (readResult = read(childToParent[READ_FD], buffer, BUFFER_SIZE)) {
                        case 0: /* End-of-File, or non-blocking read. */
                            std::cout
                                << "End of file reached..."         << std::endl
                                << "Data received was ("
                                << dataReadFromChild.size() << "):" << std::endl
                                << dataReadFromChild                << std::endl;
    
                            ASSERT_IS(pid, waitpid(pid, &status, 0));
    
                            std::cout
                                << std::endl
                                << "Child exit status is:  " << WEXITSTATUS(status) << std::endl
                                << std::endl;
    
                            exit(0);
    
                        case -1:
                            if ((errno == EINTR) || (errno == EAGAIN)) {
                                errno = 0;
                                break;
                            } else {
                                FAIL("read() failed");
                                exit(-1);
                            }
    
                        default:
                            dataReadFromChild.append(buffer, readResult);
                            break;
                    }
                } /* while (true) */
    
        } /* switch (pid = fork())*/
        std::cout << dataReadFromChild << std::endl;
    
        return 0;
    }


    Sortie :


    Child 5706 process running...
    End of file reached...
    Data received was (401):
    reading from file -, link-type PPP (PPP)
    02:00:12.202107 IP (tos 0x0, ttl 1, id 0, offset 0, flags [none], proto OSPF (89), length 64, bad cksum 0 (->d65d)!)
    1.1.2.2 > 224.0.0.5: OSPFv2, LS-Ack, length 44
    Router-ID 1.1.4.1, Backbone Area, Authentication Type: none (0)
    Advertising Router 1.1.3.1, seq 0x8000000b, age 1s, length 40
    Router LSA (1), LSA-ID: 1.1.3.1
    Options: [External]

    Child exit status is: 0


    Bonne chance
    0
    1. Utilisateur anonyme
       
      merci beaucoup mamiemando ,
      je teste sa sur le champ et vous tien informer de ce que je suis parvenue a faire !
      0
    2. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 940
       
      Ça marche :-)
      0