简体   繁体   English

如何使用 c++ 制作终端仿真器并在 ncurses window 中显示 output?

[英]How to make terminal emulator using c++ and display the output in ncurses window?

#include "Terminal.h"


void Terminal::send_buffer_to_terminal(std::string buffer)
{
    input << buffer << std::endl;
    input << "echo " << delimiter << std::endl;
}

std::string Terminal::terminal_process(std::string command)
{
    bp::child p("/bin/bash", std::vector<std::string>(), bp::std_out > output, bp::std_in < input);  
    while(1)
    {
        command.clear();
        //get_input(command);
        //printw("Enter command")
        send_buffer_to_terminal(command);
        std::cout << command ;
        process_command(command, output, input, delimiter);
        //_terminal_display._input_buffer.erase();
        //_terminal_display._enter = true;
    }
    // p.terminate();
    p.wait();
}

void Terminal::process_command(std::string& command, bp::ipstream& output, bp::opstream& input, char delimiter) {
    if(command == "exit")
    {
        return;
    }
    //input << command <<std::endl;
    //input << "echo "<< delimiter<<std::endl;

    std::string line;
    std::getline(output, line, delimiter);
    _terminal_display.add_message(line);
    // refresh();
    char c = output.get();
    assert(c == '\n');
}

This is the code i have.这是我的代码。 now i have another function from which i have to call the active window which is the terminal window and here is the code for it:现在我有另一个 function,我必须从中调用活动的 window,这是终端 window,这是它的代码:

void DisplayManager::run()
{
    while(true)
    {
        
        move(LINES-2, 2);
        getstr(_input);
        if(strcmp(_input, "EXIT")==0)
        {
            break;
        }
        
        if(strcmp(_input, "SWITCH")==0)
        {
            _active_window = _active_window == CHAT_WINDOW ? TERM_WINDOW : CHAT_WINDOW;
            move(LINES-2, 0);
            clrtoeol();
            continue;
        }
        if(_active_window == CHAT_WINDOW)
        {
            add_chat_message(_input);    
        }
        else if(_active_window == TERM_WINDOW)
        {
            while(1)
            {
            getstr(_input);
            mvwprintw(_term_display._window, 1, 2, "i");
            _terminal.terminal_process(_input);
            }
        }
        move(LINES-2, 0);
        clrtoeol();
        display();
    }   
}

so i need to make the boost child run throughout the time i am using term_window.所以我需要让 boost child 在我使用 term_window 的整个过程中运行。 any idea how i could make this work?知道我怎么能让这个工作吗?

I tried the terminal code and it works individually, but somehow i cannot display it in the terminal ncurses window and it is throwing boost::process::error, what() execve failed:Bad address error whenever i enter a shell command.我尝试了终端代码并且它单独工作,但不知何故我无法在终端 ncurses window 中显示它并且它抛出 boost::process::error, what() execve failed: Bad address error 每当我输入 shell 命令时。

what i actually want to happen is that when i enter bash commands, i need it to execute the commands and display the result in ncurses window. btw, this is linux based.我真正想要发生的是,当我输入 bash 命令时,我需要它来执行命令并在 ncurses window 中显示结果。顺便说一句,这是基于 linux 的。

You need to start a terminal emulator, for example with libvterm .您需要启动终端仿真器,例如使用libvterm

Then, the easiest way is to use forkpty instead of fork which correctly does openpty , fork and login_tty steps required to connect the child process to your terminal emulation.然后,最简单的方法是使用forkpty而不是fork正确执行将子进程连接到终端仿真所需的openptyforklogin_tty步骤。

In the child process make sure the TERM environment variable is set to the appropriate value.在子进程中,确保 TERM 环境变量设置为适当的值。

In the parent process, until the child process exits, you need to在父进程中,直到子进程退出,需要

  • Have async loops to process input/output between vt and pty master.使用异步循环来处理 vt 和 pty master 之间的输入/输出。 This amounts to just reading whatever your receive, and pushing it to the terminal emulator ( libvterm has vterm_push_bytes for that purpose).这相当于只读取您收到的任何内容,并将其推送到终端仿真器( libvtermvterm_push_bytes用于此目的)。
  • Idem to process vt input ( vterm_output_get_buffer_current in libvterm ). Idem 处理 vt 输入( vterm_output_get_buffer_current中的libvterm )。

As an example (not using Asio) I got https://github.com/cantora/ncte to build and run on my box.作为一个例子(不使用 Asio)我得到了https://github.com/cantora/ncte在我的盒子上构建和运行。 That could be a starting point.这可能是一个起点。

Out-Of-The-Box盒子外面

If you're ready to start processes anyways, you should consider whether just launching an existing terminal emulator like xterm or gnome-terminal to run your child process in would not be a lot more straightforward如果您无论如何都准备好启动进程,您应该考虑是否只启动一个现有的终端仿真器(如 xterm 或 gnome-terminal)来运行您的子进程是否会更直接

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM