簡體   English   中英

子進程無法從創建的偽終端讀取

[英]Child process unable to read from created pseudo terminal

我正在嘗試編寫一個可以使用偽終端使用密碼登錄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()上等待。 這是怎么回事?

問題是您沒有修改PTY的線路規則。 默認的行規則是面向行的,因此在讀取換行符之前,不會將任何輸入發送到從屬進程。 (您可以通過向從屬服務器發送“ \\ n”,而不是僅發送“ 1”來看到此信息。)您可以通過在子進程中調用tcgetattrcfmakerawtcsetattr ,以RAW模式運行PTY,如下所示:

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

這似乎為我工作。

此博客文章中的示例代碼可能應該會有所幫助。 作者使用可用的spawn (char *argv[]);更新了他的原始問題(非常類似於您的問題spawn (char *argv[]); 給定的功能。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM