无法写入伪终端主机

时间:2016-09-29 16:18:45

标签: linux terminal

我能够打开一个新的伪终端,并在slave上启动一个shell,但写入master并没有做任何事情,并且在shell启动后尝试读取失败(-1) )。我做错了什么:

#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include <sys/ioctl.h>

int posix_openpt(int flags);
int grantpt(int fd);
int unlockpt(int fd);
char *ptsname(int fd);


static void execsh(void);



int main(int argc, char *argv[]) {
    printf("Hiya\n");

    // Open the Master Clone Device /dev/ptmx, return the fd
    int master_fd = posix_openpt(O_RDWR);
    printf("PTMaster = %d\n", master_fd);

    // Change the permissions and ownership of the slave device
    int grant_success = grantpt(master_fd);
    printf("Grant success = %d\n", grant_success);

    // Unlock the slave pseudoterminal device corresponding to master_fd
    int unlock_success = unlockpt(master_fd);
    printf("Unlock success = %d\n", unlock_success);

    // Grab the name of the slave device
    char *slave_name = ptsname(master_fd);
    printf("Slave name = %s\n", slave_name);


    // Open the slave pseudoterminal device
    int slave_fd = open(slave_name, O_WRONLY);
    printf("Slave fd = %d\n", slave_fd);

    // Exec shell
    pid_t pid;
    switch (pid = fork()) {
        case -1:
            printf("Failed to fork\n");
            break;
        case 0:
            // Child
            setsid(); /* create a new process group */
            dup2(slave_fd, STDIN_FILENO); 
            dup2(slave_fd, STDOUT_FILENO);
            dup2(slave_fd, STDERR_FILENO);
            ioctl(slave_fd, TIOCSCTTY, NULL); /* make this the controlling terminal for this process */
            close(slave_fd);
            close(master_fd);


            // Start Shell
            execsh();
            break;
        default:
            // Parent
            close(slave_fd);
    }


    // Read from master
    sleep(1);
    char buffer[200];
    ssize_t read_bytes = read(master_fd, buffer, 200);
    printf("read %ld from master\n", read_bytes);
    printf("buffer = %s\n", buffer);

    // ls  
    ssize_t written = write(master_fd, "ls\n", 3);
    printf("wrote %ld to master\n", written);


    // Read from master
    read_bytes = read(master_fd, buffer, 200);
    printf("read %ld from master\n", read_bytes);
    printf("buffer = %s\n", buffer);


    close(master_fd);
    kill(pid, SIGKILL); // Kill the child, biblical

    return 0;
}


void
execsh(void) {
    char **args;
    char *envshell = getenv("SHELL");

    unsetenv("COLUMNS");
    unsetenv("LINES");
    unsetenv("TERMCAP");


    signal(SIGCHLD, SIG_DFL);
    signal(SIGHUP, SIG_DFL);
    signal(SIGINT, SIG_DFL);
    signal(SIGQUIT, SIG_DFL);
    signal(SIGTERM, SIG_DFL);
    signal(SIGALRM, SIG_DFL);

    args = (char *[]){envshell, "-i", NULL};
    printf("\nforked child starting terminal\n");
    execvp(args[0], args);
    printf("\nExited the shell\n");
    exit(EXIT_FAILURE);
}

输出如下:

Hiya
PTMaster = 3
Grant success = 0
Unlock success = 0
Slave name = /dev/pts/19
Slave fd = 4
read 130 from master
buffer = 
forked child starting terminal
eric@vbox:~/Desktop/terminal$ exit

wrote 3 to master
read -1 from master
buffer = 
forked child starting terminal
eric@vbox:~/Desktop/terminal$ exit

我不确定为什么它还有单词exit。提前感谢您的任何指示!

1 个答案:

答案 0 :(得分:0)

ninjalj是对的。我让奴隶开了只写。

非常感谢!