プログラムが読み取り行で終了した後、標準入力のテキストは表示されません。

プログラムが読み取り行で終了した後、標準入力のテキストは表示されません。

私の端末で標準入力のテキストが表示されない問題に直面しました。私のプログラムは次のことを行います

一定時間経過してもユーザー入力がない場合にプログラムを終了するSIGALRMハンドラを設定します。

void sigalrm_handler(int arg)
{   
    exit(0);
} 

主な機能では:

{
...
alarm(100);
line = readline(line = readline(prompt);)
...
}

ただし、プログラムの終了後に端末に入力した内容は表示されません。しかし、コマンドはうまく動作します。

一時的に実行すると system("reset")問題が解決しました。しかし、よりクリーンなソリューションが必要です。int rl_reset_line_state ()私はそれらを試しましたが、うまく int rl_reset_terminal (char *terminal_name)いかないようです。

ベストアンサー1

最新のシェルはプログラムが終了した後にターミナルの状態を復元する傾向がありますが、古いシェルやパフォーマンスが低下しているシェルはそうではありません。 APUEやその他のテキストの一般的なアプローチは、端末の状態のコピーを保存してから、プログラムが終了したtcgetattrときにその状態を復元することです。

#include <sys/time.h>

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

#include <readline/readline.h>
#include <readline/history.h>

struct itimerval Alarm_Timer;
struct termios Original_Termios;
int Need_Reset;

void sigalrm_handler(int arg)
{
    if (Need_Reset)
        tcsetattr(STDIN_FILENO, TCSANOW, &Original_Termios);
    exit(0);
}

int main(void)
{
    char *line;

    tcgetattr(STDIN_FILENO, &Original_Termios);
    Need_Reset = 1;

    signal(SIGALRM, sigalrm_handler);
    Alarm_Timer.it_value.tv_sec = 3;
    setitimer(ITIMER_REAL, &Alarm_Timer, NULL);

    line = readline("* ");

    if (Need_Reset)
        tcsetattr(STDIN_FILENO, TCSANOW, &Original_Termios);

    exit(0);
}

おすすめ記事