【问题标题】:why this linux pseudo terminal program doesn't work?为什么这个 linux 伪终端程序不起作用?
【发布时间】:2016-04-14 14:20:13
【问题描述】:

Master 从 stdin 读取输入并写入 pty-master,slave 从 pty-slave 读取输入并写入 stdout。

但是这个代码/程序似乎不起作用。 Master 向 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;
}

【问题讨论】:

    标签: c linux unix terminal posix


    【解决方案1】:

    除了打开伪终端之外,您还必须对其进行初始化(称为行规)。在您的示例中,我没有看到任何内容。您可以与luit 进行比较,后者确实可以做到这一点(例如,查看sys.c 中的openTty 函数)。

    进一步阅读:

    【讨论】:

      猜你喜欢
      • 2013-01-26
      • 2016-04-20
      • 2021-09-09
      • 2018-02-09
      • 2015-05-21
      • 1970-01-01
      • 2022-01-17
      • 1970-01-01
      • 2019-12-31
      相关资源
      最近更新 更多