Partage
  • Partager sur Facebook
  • Partager sur Twitter

Lancer plusieurs instances de bash -i

[serveur telnet] lancer plusieurs instances de "bash -i" avec fork()

    21 octobre 2018 à 18:44:42

    Bonjour,

    je cherche à programmer un serveur telnet en C++. Voici mon code:

    #include <iostream>
    #include <sys/types.h>
    #include <sys/wait.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #include <netdb.h>
    #include <pthread.h>
    #include <cstdlib>
    
    using namespace std;
    
    void *waitEndProcess(void *arg);
    
    int main()
    {
        int lsock, csock;
        pid_t cpid;
        pthread_t threadWaitEndProcess;
        char *cmd = "/bin/bash";
        char *cmd_args[] = {"/bin/bash", "-i", NULL};
        struct sockaddr_in server , client;
        lsock = socket(AF_INET , SOCK_STREAM , 0);
        if (lsock == -1)
        {
            cerr << "Could not create socket" << endl;
        }
        server.sin_family = AF_INET;
        server.sin_addr.s_addr = INADDR_ANY;
        server.sin_port = htons(2323);
        if( bind(lsock,(struct sockaddr *)&server , sizeof(server)) < 0)
        {
            cerr << "bind failed" << endl;
            exit(-1);
        }
        listen(lsock, 0);
        while(1)
        {
            if ((csock = accept(lsock, NULL, NULL)) == -1)
            {
                cerr << "accept failed" << endl;
                exit(-1);
            }
            cout << "accepted" << endl;
            cpid = fork();
            if (cpid < 0)
            {
                cerr << "fork failed" << endl;
                exit(-1);
            }
            if (cpid)
            {
                close(csock);
                pthread_create(&threadWaitEndProcess, NULL, waitEndProcess, (void*)&cpid);
                pthread_detach(threadWaitEndProcess);
            }
            else
            {
                cout << "fork" << endl;
                dup2(csock, STDIN_FILENO);
                dup2(csock, STDOUT_FILENO);
                dup2(csock, STDERR_FILENO);
                close(csock);
                execvp(cmd, cmd_args);
                exit(0);
            }
        }
        return 0;
    }
    
    void *waitEndProcess(void *arg)
    {
        cout << "wait" << endl;
        pid_t pidProcess=*(pid_t*)arg;
        waitpid(pidProcess, NULL, 0);
        cout << "Process terminated" << endl;
        pthread_exit(NULL);
    }

    Ça marche bien à la première connexion mais dès qu'un deuxième client se connecte, on obtient:

    accepted

    fork

    wait

    accepted

    wait

    fork


    [1]+  Arrêté                ./telnetsvr

    Le problème vient de la commande "bash -i" puisqu'on aura le même résultat si on fait 2 fois "bash -i &" dans la console.

    Côté client, le premier reçoit bien l'invite de commande interactive mais le deuxième ne peut rien taper dans son terminal distant.

    Comment lancer 2 processus de bash -i

    Merci d'avance

    • Partager sur Facebook
    • Partager sur Twitter
      22 octobre 2018 à 11:25:06

      Salut,

      par curiosité, j'ai compilé ton programme sur mon codeblocks, et ça me dit que

      |fatal error: sys/wait.h: No such file or directory|

      Sur quel environnement travailles-tu ? et qu'as-tu d'installé pour avoir ces include ?

      • Partager sur Facebook
      • Partager sur Twitter
        22 octobre 2018 à 12:00:18

        Ce sont des includes spécifiques aux systèmes de type UNIX, comme unistd.h, le PO doit certainement être sous Linux

        Sinon, il s'agit d'un code C, tu recevras plus d'aide et elle sera plus pertinente sur le forum ad hoc. Si tu souhaite utiliser les fonctionnalités du C++, tu as de quoi gérer les threads dans le standard, et pour gérer une communication on utilisera plus volontier une lib tel que asio.

        Dans ton programme tu mélanges gestion de processus et multithreading, peux tu expliquer le rôle que tu veux donner à chacun ?

        Je crois que tu cherches dans la mauvaise direction car tu fais ton fork manuellement, ce n'est pas pareil que "/bin/bash -i &"

        Il n'y a pas de soucis avec csock là ? j'ai un peu du mal à suivre son évolution pour chaque process là comme ça.

        • Partager sur Facebook
        • Partager sur Twitter
        Dream on, Dream on, Dream until your dream comes true
          22 octobre 2018 à 23:08:41

          Bonjour et merci pour vos réponses.

          Je suis sous Linux mais ça marche normalement avec n'importe quel environnement Unix.

          Désolé pour les forums C/C++. Pour les bibliothèques (asio) l'objectif était plutôt de rester sous la bibliothèque standard.

          Les threads servent à attendre la fin d'un processus fils (waitpid()) tout en permettant au thread principal de continuer à accepter les connexions entrantes.

          En fait je me suis aperçu que l'erreur venait de la commande "/bin/bash -i". J'avais l'impression que cette commande ne pouvait pas être lancée 2 fois en même temps. Je viens de tester sous un autre environnement et j'ai un résultat différent: la première connexion est acceptée avec un shell, les autres sont acceptées avec un écran noir. La déconnexion du client avec shell fait apparaître le shell pour le suivant... (Du coup j'aimerai que tout le monde ait le shell tout de suite)

          • Partager sur Facebook
          • Partager sur Twitter
            23 octobre 2018 à 9:21:14

            Rimfambir a écrit:

            Désolé pour les forums C/C++

            Oh je dis ça pour toi, car mis à part cerr/cout, ton code est purement du C donc tu ne trouveras juste pas l'aide que tu souhaites ici

            Rimfambir a écrit:

            Pour les bibliothèques (asio) l'objectif était plutôt de rester sous la bibliothèque standard.

            Ben du coup c'est raté, tu n'utilises pas du standard mais l'API POSIX, asio en revanche est proche de devenir standard (c'était en discussion pour C++20, je sais pas où ç'en est).

            Pour l'instant il n'y a pas de standard concernant le networking

            Il y a une véritable raison valide qui t'empêche d'utiliser des libs ?

            Rimfambir a écrit:

            Les threads servent à attendre la fin d'un processus fils (waitpid()) tout en permettant au thread principal de continuer à accepter les connexions entrantes.

            Donc c'est vraiment ce que tu souhaitais faire ... ça me parait absurde !
            C'est tout l'intérêt de waitpid d'être bloquant, et tu crées un thread juste pour que ça ne le soit pas o_O
            Pourquoi souhaites-tu y faire appel alors ?

            Rimfambir a écrit:

            En fait je me suis aperçu que l'erreur venait de la commande "/bin/bash -i". J'avais l'impression que cette commande ne pouvait pas être lancée 2 fois en même temps. Je viens de tester sous un autre environnement et j'ai un résultat différent: la première connexion est acceptée avec un shell, les autres sont acceptées avec un écran noir. La déconnexion du client avec shell fait apparaître le shell pour le suivant... (Du coup j'aimerai que tout le monde ait le shell tout de suite)

            arf, d'accord ouais, y'a une subtilité qui se cache là, peut-être que les linuxiens des forums Linux connaissent mieux ?

            J'ai l'impression que bash essaie d'accéder à une ressource déjà occupée, c'est pour ça que je remets en cause csock mais je trouve pas ce qui cloche :/

            • Partager sur Facebook
            • Partager sur Twitter
            Dream on, Dream on, Dream until your dream comes true
              26 octobre 2018 à 11:04:29

              Bonjour,

              Avez_vous flushé le buffer dans un premier temps ?
              C'est la première chose à faire lorsqu'on commence une telle tâche.


              Bonne journée :)
              • Partager sur Facebook
              • Partager sur Twitter
                26 octobre 2018 à 16:05:08

                Avec fflush(std{in;out;err}) ?

                J'ai essayé et malheureusement ça ne change rien

                -
                Edité par Rimfambir 26 octobre 2018 à 16:05:35

                • Partager sur Facebook
                • Partager sur Twitter

                Lancer plusieurs instances de bash -i

                × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                • Editeur
                • Markdown