Как читать стандартный ввод из родительского процесса? - PullRequest
0 голосов
/ 07 августа 2020

Мне нужно написать программу, которая запускает bash и проверяет ввод пользователя. Например, если я напишу «io», программа должна вывести на стандартный вывод «LOL». К сожалению, мой код не работает.

#include <iostream>
#include <thread>
#include <cstdlib>
#include <cstdio>
#include <cerrno>
#include <cstring>
#include <unistd.h>
#include <fcntl.h>
#include <fstream>

int         main(int ac, char **av)
{
    ssize_t count;

    switch(fork())
    {
        case -1 :
        {
            std::cout << strerror(errno) << std::endl;
            break;
        }
        case 0 : // child
        {
            char    curr = 0, prev = 0;

            while ((count = read(0, (void*)&curr, 1)))
            {
                if (count == -1)
                {
                    std::cout << strerror(errno) << std::endl;
                    return 1;
                }
                if (prev == 'i' && curr == 'o')
                {
                    std::cout << "LOL" << std::endl;
                }
                prev = curr;
            }
            break;
        }
        default: // parent
        {
            char *const *bashArgs = {NULL};

            execvp("bash", bashArgs);
            break;
        }
    }
    return 0;
}

Приведенный выше код просто бесконечно считывает то, что я пишу на консоле, а затем дает сбой: «bash: дерьмо, которое я написал: команда не найдена» . Затем бесконечное чтение прекращается, и я нахожусь в сеансе bash. Затем я просто выхожу из этого сеанса с помощью Ctrl + D в свой сеанс по умолчанию bash.

Также я пытался сделать это через pipe () и dup2 (). Приведенный ниже код просто запускает сеанс и ничего не делает.

#include <iostream>
#include <thread>
#include <cstdlib>
#include <cstdio>
#include <cerrno>
#include <cstring>
#include <unistd.h>
#include <fcntl.h>
#include <fstream>

int         main(int ac, char **av)
{
    ssize_t count;
    int     fd[2];

    if (pipe(fd) == -1)
        std::cout << strerror(errno) << std::endl;

    switch(fork())
    {
        case -1 :
        {
            std::cout << strerror(errno) << std::endl;
            break;
        }
        case 0 : // child
        {
            char    curr = 0, prev = 0;

            while ((count = read(fd[0], (void*)&curr, 1)))
            {
                if (count == -1)
                {
                    std::cout << strerror(errno) << std::endl;
                    return 1;
                }
                if (prev == 'i' && curr == 'o')
                {
                    std::cout << "LOL" << std::endl;
                }
                prev = curr;
            }
            break;
        }
        default: // parent
        {
            char *const *bashArgs = {NULL};

            dup2(STDIN_FILENO, fd[1]);

            execvp("bash", bashArgs);
            break;
        }
    }
    return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...