1

疑似端末を使って、パスワードでSSHにログインできるアプリを書こうとしています。しかし、マスターデバイスにwrite()を実行すると、データはどういうわけかスレーブデバイスに表示されません。簡単なテストケースは次のとおりです。

#include <sys/wait.h>
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#ifdef __linux__
    #include <pty.h>
#else
    #include <util.h>
#endif

int
main() {
    int master;
    pid_t pid = forkpty(&master, NULL, NULL, NULL);
    if (pid == 0) {
        int ch;
        read(0, &ch, 1);
        _exit(1);
    } else {
        printf("Press Enter to send a byte.\n");
        getchar();
        write(master, "1", 1);
        printf("Done. Waiting for process to exit...\n");
        waitpid(pid, NULL, 0);
        return 0;
    }
}

アプリは最初に「Enterキーを押してバイトを送信します」と出力します。Enterキーを押した後、子プロセスのread()が戻ることを期待しています。しかし、マスターのwrite()が成功したとしても、そこにあるread()は無期限にブロックされるように見えるため、マスターはwaitpid()を永久に待機します。どうしたの?

4

2 に答える 2

2

問題は、PTYのラインディシプリンを変更しなかったことです。デフォルトの行の規律は行指向であるため、改行文字が読み取られるまで入力はスレーブプロセスに送信されません。(これは、「1」ではなく「\ n」をスレーブに送信することで確認できます。)子プロセスで、を呼び出してtcgetattr、次のようにPTYをRAWモードで実行できます。cfmakerawtcsetattr

    if (pid == 0) {
        int ch;
        struct termios t;
        tcgetattr(0, &t);
        cfmakeraw(&t);
        tcsetattr(0, TCSANOW, &t);
        read(0, &ch, 1);
        _exit(1);
    } else {

これは私にとってはうまくいくようです。

于 2010-02-02T19:32:01.497 に答える
1

このブログ投稿のサンプルコードはおそらく役立つはずです。spawn (char *argv[]);作者は、与えられた使用可能な関数を使用して、元の問題(あなたの問題と非常によく似ています)を更新しています。

于 2010-02-02T19:22:10.860 に答える