2

私は学校のプロジェクトに取り組んでいます(非常に基本的なシェルを構築しています)。

アイデアは、bash のようにライン エディションを実行できるようにすることです。このために、端末モードを非標準に変更し、エコーを停止します。

私は自分の問題を公開するために非常に単純なコードを作成しました (注意してください、私は関数の戻り値などをチェックします...この記事ではできるだけ短くしました)

#include <termios.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main()
{
    int     ret;
    char    buff;
    char    *term_name;
    char    *termcap;
    struct termios  termios_new;
    struct termios  termios_backup;

    /*
    ** Init termcap library
    */
    term_name = getenv("TERM");
    tgetent(NULL, term_name);

    /*
    ** Get the terminal mode to non canonical and shut down echo
    */
    bzero(&termios_new, sizeof(struct termios));
    tcgetattr(STDIN_FILENO, &termios_backup);
    termios_new = termios_backup;

    termios_new.c_lflag &= ~(ICANON);
    termios_new.c_lflag &= ~(ECHO);
    termios_new.c_cc[VMIN] = 1;
    termios_new.c_cc[VTIME] = 0;

    /*
    **  Set the change
    */
    tcsetattr(STDIN_FILENO, TCSAFLUSH, &termios_new);

    /*
    ** Get the termcap for clearing screen on the particular terminal
    */
    termcap = tgetstr("cl", NULL);

    /*
    ** Loop read to get user entries and clear screen for 'c', output char for 'b', break for 'q'
    */
    while((ret = read(STDIN_FILENO, &buff, 1)) > 0)
    {
        if (buff == 'c')
            tputs(termcap, 1, putchar);
        else if (buff == 'b')
            putchar(buff);
        else if (buff == 'q')
            break ;
        buff = 0;
    }

    /*
    ** Put back the terminal mode as found before
    */
    tcsetattr(STDIN_FILENO, TCSAFLUSH, &termios_backup);
    return (0);
}

したがって、基本的には、ユーザーエントリをキャッチするための読み取りのループです。'c' で画面をクリアし、'b' で char を出力し、'q' で元の端末モードを中断して復元します。

問題は次のとおりです。

「q」でループを中断するまで何も起こらないため、何かを入力するたびにバッファリングされているように見えます。この時点で、出力が画面に表示されます。b を 5 回入力すると、5 回の b が表示され、「c」を入力すると画面がクリアされます。ただし、「q」を入力した後のみ。動作は、元の端末モードを復元する場合も復元しない場合も同じです。( の前の最後の行return)

私が疑うもの:

コードを非常に短くしてすべてのリターンをチェックした後、端末モードを変更する方法に問題があるだけだと思う​​傾向がありますか? フラグTCSAFLUSHと関数を試してみると、同じ結果が得られましたTCSADRAINtcsetattr

ありがとう !:)

4

1 に答える 1