Utilisation de la fonction pipe

Résolu/Fermé
Utilisateur anonyme - 7 mai 2015 à 14:50
mamiemando Messages postés 33446 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 20 décembre 2024 - 8 mai 2015 à 15:57
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

mamiemando Messages postés 33446 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 20 décembre 2024 7 812
8 mai 2015 à 00:28
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
Utilisateur anonyme
8 mai 2015 à 09:58
merci beaucoup mamiemando ,
je teste sa sur le champ et vous tien informer de ce que je suis parvenue a faire !
0
mamiemando Messages postés 33446 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 20 décembre 2024 7 812
8 mai 2015 à 15:57
Ça marche :-)
0