2015-11-21 36 views
0

我一直在嘗試創建一個僞終端與mpg123進行通信。從我的所有閱讀中,我都相信我已經正確編寫了代碼,但我無法弄清楚我應該如何將主方(PTY)與外部程序連接起來。試圖找出pty

我得到第一個可用的主人posix_openpt,並啓用grantptunlockpt的奴隸。然後我得到ptsname的PTS名稱,它可以與open一起使用來獲取文件描述符。接下來,我用dup2替換PTY的STDIN,STDOUT和STDERR。然後我可以使用該文件描述符與PTY進行通信。但是,主控端如何連接到我希望與之通信的外部程序?

這是到目前爲止我的代碼:

#define _XOPEN_SOURCE 600 
#include <stdio.h> 
#include <libgen.h> 
#include <stdlib.h> 
#include <fcntl.h> 
#include <errno.h> 
#include <string.h> 
#include <unistd.h> 
#include <sys/stat.h> 
#include <termios.h> 
#include <sys/wait.h> 

int main (int argc, char *argv[]) 
{ 
    int fdm; 
    int fds; 
    pid_t pid; 
    char *slave_name; 
    char *program_name; 

    program_name = basename(argv[0]); 

    if(argc != 1) 
    { 
     fprintf(stderr, "usage: %s\n", program_name); 
     exit(EXIT_FAILURE); 
    } 

    if((fdm = posix_openpt(O_RDWR)) == -1) 
    { 
     fprintf(stderr, "%s: posix_openpt failed (%s)\n", program_name, strerror(errno)); 
     exit(EXIT_FAILURE); 
    } 

    if(grantpt(fdm) == -1) 
    { 
     fprintf(stderr, "%s: grantpt failed (%s)\n", program_name, strerror(errno)); 
     close(fdm); 
     exit(EXIT_FAILURE); 
    } 

    if(unlockpt(fdm) == -1) 
    { 
     fprintf(stderr, "%s: unlockpt failed (%s)\n", program_name, strerror(errno)); 
     close(fdm); 
     exit(EXIT_FAILURE); 
    } 

    if((slave_name = ptsname(fdm)) == NULL) 
    { 
     fprintf(stderr, "%s: ptsname failed\n", program_name); 
     close(fdm); 
     exit(EXIT_FAILURE); 
    } 

    if((pid = fork()) == -1) 
    { 
     fprintf(stderr, "%s: fork failed (%s)\n", program_name, strerror(errno)); 
     close(fdm); 
     exit(EXIT_FAILURE); 
    } 

    if(pid == 0) // Child 
    { 
     if(setsid() == -1) 
     { 
      fprintf(stderr, "%s: setsid failed (%s)\n", program_name, strerror(errno)); 
      close(fdm); 
      exit(EXIT_FAILURE); 
     } 

     if((fds = open(slave_name, O_RDWR)) == -1) 
     { 
      fprintf(stderr, "%s: open failed (%s)\n", program_name, strerror(errno)); 
      close(fdm); 
      exit(EXIT_FAILURE); 
     } 

     close(fdm); 

     if(dup2(fds, STDIN_FILENO) == -1) 
     { 
      fprintf(stderr, "%s: dup2(1) failed (%s)\n", program_name, strerror(errno)); 
      close(fds); 
      exit(EXIT_FAILURE); 
     } 

     if(dup2(fds, STDOUT_FILENO) == -1) 
     { 
      fprintf(stderr, "%s: dup2(2) failed (%s)\n", program_name, strerror(errno)); 
      close(fds); 
      exit(EXIT_FAILURE); 
     } 

     if(dup2(fds, STDERR_FILENO) == -1) 
     { 
      fprintf(stderr, "%s: dup2(3) failed (%s)\n", program_name, strerror(errno)); 
      close(fds); 
      exit(EXIT_FAILURE); 
     } 

     close(fds); 
     exit(EXIT_SUCCESS); 
    } 
    else  // Parent 
    { 
     wait(&pid); 
    } 

    exit(EXIT_SUCCESS); 
} 

我不是尋找一個伸出手,只是一個交代。我如何連接到mpg123?我在哪裏連接到mpg123,在孩子或父母?

+0

我記得很久以前我和PTY打過很多次了。如果我沒記錯的話,我通過編寫標準腳本程序的源代碼編寫了幾個代碼。這是一個短代碼,很容易破解。 –

回答

1

通常你會調用execvp來執行mpg123。然後,通過作爲終端用戶的主文件描述符(fdm)進行通信(TTY用於人類用戶)。

你確定你需要使用這個pty嗎?對於stdin/stdout,大部分程序都可以正常工作。您可以通過在父進程中調用pipesockerpair來創建這些文件。更妙的是,如果你只需要閱讀或者只寫就可以使用popen這簡化了界面。

+0

我嘗試過popen。 http://stackoverflow.com/questions/33678441/why-wont-popen-communicate-with-mpg123 – Deanie

+0

好的,我仍然想知道是否沒有比模擬人類用戶更好的界面,但那不是真的我的電話。 –

+0

你的第一段是我完成我的任務所需要的。 TY。 – Deanie