我一直在尝试创建一个与mpg123
进行通信的伪终端。从我的所有阅读材料中我都认为我已经正确编写了代码,但我无法弄清楚我应该如何将主机端(PTY)与外部程序连接起来。
我使用posix_openpt
获得第一个可用的主人,并使用grantpt
和unlockpt
启用从属。然后我得到ptsname
的PTS名称,可以与open
一起使用来获取文件描述符。接下来,我将PTY的STDIN,STDOUT和STDERR替换为dup2
。然后我可以使用该文件描述符与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 :(得分:1)
通常你会在子进程中调用execvp来执行mpg123。然后,您通过作为终端用户的主文件描述符(fdm
)进行通信(TTY适用于人类用户)。
你确定你需要使用pty吗?对于stdin / stdout,大多数程序只能使用普通管道。您可以通过在父进程中调用pipe
或sockerpair
来创建这些内容。更好的是,如果您只需要阅读或只需要编写,您可以使用popen
来简化界面。