1

次のコードを実行する、その fd (標準入力) での将来のすべての read() 呼び出しが、入力をブロックする代わりにすぐに 0 を返す理由を知っている人はいますか?

termios newTerminalSettings;
tcgetattr(inFd, &newTerminalSettings);
newTerminalSettings.c_lflag &= ~ICANON;
tcsetattr(inFd, TCSANOW, &newTerminalSettings);

tcsetattr 行を削除すると、read() が期待どおりに動作するようになります。

また試しました:

fcntl(inFd, F_SETFL, 0);

運がない。

現在、2つの異なる端末があることに注意してください。それらのいずれかでアプリを実行すると、読み取りが即座に返されます。他の場所で実行すると、読み取りが入力のためにブロックされます。どうなり得るか?

前もって感謝します :-)

再現ソース:

#include <iostream>
#include <termios.h>

using namespace std;

int main(void) {
    termios newTerminalSettings;
    tcgetattr(0, &newTerminalSettings);
    newTerminalSettings.c_lflag &= ~ICANON;
    tcsetattr(0, TCSANOW, &newTerminalSettings);

    char readBuf[5000];
    cout << "read returned: " << read(0, readBuf, sizeof(readBuf));

    return 0;
}
4

2 に答える 2

0

あなたの問題はICANONをマスクしていると思います。これにより、標準モードがオフになります(非標準モードが有効になります)。termios(3) のマンページによると:

「非標準モードでは、(ユーザーが行区切り文字を入力する必要なく) 入力がすぐに利用可能になり、行編集は無効になります。」

この投稿が煩雑になるのを避けるために、man ページを参照してください。この動作について詳しく説明されています。次の動作は、(非同期モードのように) read が返すものがない場合に発生します。

toptal Engineering の Gergely

于 2011-11-06T12:54:30.540 に答える
0

tty ドライバーは、シリアルラインから既に読み取られ、ユーザーに渡されていないバイトの入力キューを維持することに注意してください。そのため、すべての read() 呼び出しが実際の I/O を待つわけではありません。入力キュー。

ここを参照

于 2011-11-06T13:08:42.483 に答える