2016-01-10 4 views
1

Мастер читает ввод от stdin и записывает на pty-master, ведомое устройство считывает входные данные из pty-slave и записывает в stdout.Почему эта программа linux pseudo не работает?

Но этот код/​​программа кажется не работает. Мастер пишет в pty-master в порядке, но ведомый висит при чтении из pty-slave.

Кто-нибудь может мне помочь? thx заранее.

#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:%[email protected]%s\n", pid, slave_name); 
     loop(fdm); 
    } 
    return 0; 
} 

ответ

1

Помимо открытия псевдо-терминал, вы должны инициализировать его (что-то Именуется линии дисциплины). Я не вижу ничего подобного в вашем примере. Вы можете сравнить с luit, что делает это (посмотрите, например, на функцию openTty в sys.c).

Дальнейшее чтение: