2016-09-29 3 views
0

Я могу открыть новый псевдотерминал и запустить оболочку на подчиненном устройстве, но запись в мастер ничего не делает и пытается прочитать после оболочки начал заканчиваться неудачей (-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 
[email protected]:~/Desktop/terminal$ exit 

wrote 3 to master 
read -1 from master 
buffer = 
forked child starting terminal 
[email protected]:~/Desktop/terminal$ exit 

Я не знаю, почему он имеет слово выход там. Заранее спасибо за любые указатели, которые у вас могут быть!

+1

Ahem ... 'int slave_fd = open (slave_name, ** O_WRONLY **);' – ninjalj

ответ

0

ninjalj был прав. У меня был раб, открытый только для написания.

спасибо!

Смежные вопросы