簡體   English   中英

為什么這個linux偽終端程序不起作用?

[英]why this linux pseudo terminal program doesn't work?

主機從stdin讀取輸入並寫入pty-master,從機從pty-slave讀取輸入並寫入stdout。

但是此代碼/程序似乎不起作用。 主機寫入pty-master可以,但是從pty-slave讀取時,slave掛起。

有人可以幫助我嗎? 提前。

#include <assert.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>

/*
 * copy from apue
 */
int ptym_open(char *pts_name, int pts_namesz)
{
    char *ptr;
    int fdm, err;
    if ((fdm = posix_openpt(O_RDWR)) < 0) {
        assert(0);
        return -1;
    }
    if (grantpt(fdm) < 0) {
        assert(0);
        return -1;
    }
    if (unlockpt(fdm) < 0) {
        assert(0);
        return -1;
    }
    if ((ptr = ptsname(fdm)) == NULL) {
        assert(0);
        return -1;
    }
    strncpy(pts_name, ptr, pts_namesz);
    pts_name[pts_namesz - 1] = 0;
    printf("pts_name:%s\n", pts_name);
    return fdm;
}

int ptys_open(char *pts_name)
{
    int fds;
    if ((fds = open(pts_name, O_RDWR)) < 0) {
        return -1;
    }
    return fds;
}

int pty_fork(int *ptrfdm, char *slave_name, int slave_namesz)
{
    int fdm, fds;
    pid_t pid;
    char pts_name[1024];
    if ((fdm = ptym_open(pts_name, sizeof(pts_name))) < 0) {
        assert(0);
        return -1;
    }
    if (slave_name != NULL) {
        strncpy(slave_name, pts_name, slave_namesz);
        slave_name[slave_namesz - 1] = 0;
    }
    if ((pid = fork()) < 0) {
        assert(0);
        return -1;
    } else if (pid == 0) {
        if (setsid() < 0) {
            assert(0);
        }
        if ((fds = ptys_open(pts_name)) < 0) {
            assert(0);
        }
        close(fdm);
        if (dup2(fds, STDIN_FILENO) != STDIN_FILENO) {
            assert(0);
        }
        //if (dup2(fds, STDOUT_FILENO) != STDOUT_FILENO) {
        //  assert(0);
        //}
        //if (dup2(fds, STDERR_FILENO) != STDERR_FILENO) {
        //  assert(0);
        //}
        if ((fds != STDIN_FILENO) && (fds != STDOUT_FILENO) && (fds != STDERR_FILENO)) {
            close(fds);
        }
        return 0;
    } else {
        *ptrfdm = fdm;
        return pid;
    }
}

int loop(int ptym)
{
    pid_t pid;
    int nread;
#define BUFFSIZE 512
    char buf[BUFFSIZE];

    if ((pid = fork()) < 0) {
        assert(0);
    } else if (pid == 0) {
        while (1) {
            if ((nread = read(STDIN_FILENO, buf, BUFFSIZE)) < 0) {
                int errr = errno;
                printf("%s\n", strerror(errr));
                assert(0);
            } else if (nread = 0) {
                break;
            }
            if (write(ptym, buf, nread) != nread) {
                int errr = errno;
                printf("%s\n", strerror(errr));
                assert(0);
            }
            fsync(ptym);
        }
        exit(0); // child
    }

    while (1) {
        if ((nread = read(ptym, buf, BUFFSIZE)) <= 0) {
            printf("%d break read\n", getpid());
            break;
        }
        if (write(STDOUT_FILENO, buf, nread) != nread) {
            assert(0);
        }
    }
}

int main(void)
{
    int fdm;
    char slave_name[1024];
    pid_t pid = pty_fork(&fdm, slave_name, sizeof(slave_name));
    if (pid < 0) {
        assert(0);
    } else if (pid == 0) {
        int nread;
        char buf[1024];
        while(1){
            if ((nread = read(STDIN_FILENO, buf, 3)) < 0) {
                break;
            }
            printf("buf:%s\n", buf);
        }
    } else {
        printf("child:%d@%s\n", pid, slave_name);
        loop(fdm);
    }
    return 0;
}

除了打開偽終端,您還必須對其進行初始化(稱為線路規程 )。 我在您的示例中看不到任何內容。 您可以將luit比較(這樣做)(例如, openTty sys.c中的openTty函數)。

進一步閱讀:

暫無
暫無

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

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