使用pty时,设备的ioctl不正确,并且没有作业控制

0g0grzrc  于 2022-12-11  发布在  其他
关注(0)|答案(1)|浏览(121)

为了给未来的项目打下基础,我创建了一个通过伪终端运行bash的程序,它只转发接收到的任何东西。
然而,尽管通过termios设置,我得到这个错误:

bash: cannot set terminal process group (8751): Inappropriate ioctl for device
bash: no job control in this shell

这是我的代码,任何帮助都非常感谢。注意:我知道我还没有实现信号处理

#define _XOPEN_SOURCE 700

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/poll.h>
#include <pty.h>

#include "libtmt/tmt.h"
#include <ncurses.h>

typedef struct App {
    int pty_fd;
    pid_t pid;
} App;

App *App_new(char **argv) {
    App *self = malloc(sizeof(App));
    int slave_pty_fd, master_pty_fd;

    struct termios terminal_settings;
    tcgetattr(STDERR_FILENO, &terminal_settings);
    
    struct winsize terminal_size = {
        .ws_row = 24,
        .ws_col = 80,
    };
    int ret = openpty(&master_pty_fd, &slave_pty_fd, NULL, &terminal_settings, &terminal_size);
    if (ret < 0) {
        perror("openpty");
        exit(1);
    }
    self->pty_fd = master_pty_fd;

    self->pid = fork();
    if (self->pid < 0) {
        perror("fork");
        exit(1);
    }
    if (self->pid == 0) {
        close(master_pty_fd);
        if (dup2(slave_pty_fd, STDIN_FILENO) != STDIN_FILENO) {
            perror("dup2");
            exit(1);
        }
        if (dup2(slave_pty_fd, STDOUT_FILENO) != STDOUT_FILENO) {
            perror("dup2");
            exit(1);
        }
        if (dup2(slave_pty_fd, STDERR_FILENO) != STDERR_FILENO) {
            perror("dup2");
            exit(1);
        }

        if (execvp(argv[0], argv) < 0) {
            perror("execvp");
            exit(1);
        }
    }

    close(slave_pty_fd);

    return self;
}

int main() {
    int ret;

    char *argv[] = {
        "/bin/bash",
        NULL,
    };

    App *app = App_new(argv);

    while (TRUE) {
        struct pollfd fds[2] = {
            { .fd = app->pty_fd, .events = POLLIN },
            { .fd = STDIN_FILENO, .events = POLLIN },
        };
        ret = poll(fds, 2, -1);
        if (ret < 0) {
            perror("poll");
            exit(1);
        }

        if (fds[0].revents & POLLIN) {
            char buf[1024];
            ret = read(app->pty_fd, buf, sizeof(buf));
            if (ret < 0) {
                perror("read");
                exit(1);
            }
            if (ret == 0) {
                printf("0 read but poll said it was okay\n");
                exit(0);
            }
            write(STDOUT_FILENO, buf, ret);
        }
        if (fds[1].revents & POLLIN) {
            char buf[1024];
            ret = read(STDIN_FILENO, buf, sizeof(buf));
            if (ret < 0) {
                perror("read");
                exit(1);
            }
            if (ret == 0) {
                printf("0 read but poll said it was okay\n");
                exit(0);
            }
            write(app->pty_fd, buf, ret);
        }
    }
}
qaxu7uf2

qaxu7uf21#

您需要从连接的终端运行程序。请参阅What does the sh:cannot set terminal process group (-1) inappropriate ioctl for device error mean?
您可以验证是否有任何当前可用的TTY可供连接:

# tty
/dev/pty0

相关问题