【问题标题】:How to return control back to terminal in C using termios如何使用termios将控制权返回到C中的终端
【发布时间】:2020-01-29 22:14:24
【问题描述】:

我正在创建一个模仿 Linux 中 shell 行为的 shell,比如执行 ls、mkdir、find 等命令,现在我使用了 termios听箭头键按下和 Enter 键按下,如果用户按下向上箭头键,则向用户显示先前执行的命令。但是在执行我的 shell 程序后,在输入第一个命令后,例如:ls 将显示命令的输出,但之后我无法执行另一个命令,因为在终端中输入并按 Enter 只需将文本打印回新的行并且不执行它。

我的代码:

#include <stdio.h>
#include <stdlib.h>
#include <termios.h>
#include <term.h>
#include <curses.h>
#include <unistd.h>

static struct termios initial_settings, new_settings;
static int peek_character = -1;
void init_keyboard();
void close_keyboard();
int kbhit();
int readch();


int main() {

    int ch;
    char str[1000][200];
    init_keyboard();
    int i = 0;
    int j = 0;

    while(ch != 'q') {

    if(kbhit()) {

        ch = readch();

        if (ch == 10) {
            system(str[i]);
            i++;
        } else {
            str[i][j] = ch;

            j++;
        }

    }

}
    close_keyboard();
    exit(0);
}

void init_keyboard() {
    tcgetattr(0, &initial_settings);
    new_settings = initial_settings;
    // new_settings.c_iflag &= ~BRKINT;
    // new_settings.c_iflag &= ICRNL;
    new_settings.c_lflag &= ~ICANON;
    new_settings.c_lflag &= ECHO;
    new_settings.c_lflag &= ~ISIG;
    new_settings.c_cc[VMIN] = 1;
    new_settings.c_cc[VMIN] = 0;
    tcsetattr(0, TCSANOW, &new_settings);

}

void close_keyboard() {

    tcsetattr(0, TCSANOW, &initial_settings);

}

int kbhit() {
    char ch;
    int nread;

    if (peek_character != -1) {
        return 1;
    }

    new_settings.c_cc[VMIN] = 0;
    tcsetattr(0, TCSANOW, &new_settings);
    nread = read(0, &ch,1);
    new_settings.c_cc[VMIN]=1;
    tcsetattr(0, TCSANOW, &new_settings);

    if (nread == 1) {
        peek_character = ch;
        return 1;
    }
    return 0;
}


int readch() {
    char ch;

    if (peek_character != -1) {
        ch = peek_character;
        peek_character = -1;
        return ch;
    }

    read(0, &ch,1);
    return ch;
}

【问题讨论】:

  • 为什么你在 readch() 中有一个 read(0, &amp;ch,5);,而 ch 的大小只能容纳一个字符?
  • 我的错应该是1 而不是5
  • 我没有看到用于查找箭头键的代码(实际上在各种终端协议之间可能会有很大差异)。你认为你已经这样做了吗?
  • 您可以考虑查看ncurses 库,该库旨在协助箭头键和滚动类型的程序
  • 我还没有实现箭头键功能,但我只需要知道如何才能重新控制终端。我不允许使用 ncurses

标签: c linux termios


【解决方案1】:

您需要 fork() 来创建新进程,因为 system() 执行您的命令并退出... 试试这个代码:

int main() {

int ch;
char str[1000][200];
init_keyboard();
int i = 0;
int j = 0;
pid_t father;
father = 0;

while(ch != 'q') {

if(kbhit()) {

    ch = readch();

    father = fork();
    if (father == 0)
    {
        if (ch == 10) {
          system(str[i]);
          i++;
        } else {
        str[i][j] = ch;
        j++;
        }
    }

}

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-07-03
    • 2012-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-25
    • 2012-08-30
    • 2021-03-29
    相关资源
    最近更新 更多