Xterm pager - 两个终端输出 - 使用管道和 dup2
Xterm pager - two terminal output - using pipe and dup2
我正在尝试用 C 实现寻呼机,我希望代码打开另一个终端 (xterm
) 并在其中打印一些输出。
所以我先创建一个管道然后fork主程序,child会用tail命令执行xterm,主程序在执行xterm之前先把管道和child里的东西输出将重复将管道输出与 child.
的标准输入文件描述符相关联
我可能误解了 pipe
和 dup2
的用法,因为我的代码不起作用。
int p[2];
pipe(p);
char buff[512];
switch (fork()) {
case -1:
fprintf(stderr, "Fork error.\n");
break;
case 0:
dup2(p[0], 0);
close(p[0]);
close(p[1]);
execlp("xterm", "xterm", "tail", NULL);
break;
default:
scanf("%s", buff);
write(p[1], buff, strlen(buff));
getchar();
break;
}
目前,我在 parent 中输入了一些内容,但在这两个过程中都没有打印任何内容。
那么如何在 xterm 和 parent 进程之间创建通信?
编辑:我的程序示例:
#define VERBM_NOVERB 0
#define VERBM_STDOUT 1
#define VERBM_XTERMO 2
static int fd_xterm = -1;
void init_outputxterm() {
mkfifo("/tmp/mypipe", 0600);
switch (fork()) {
case -1:
fprintf(stderr, "Fork error.\n");
break;
case 0:
execlp("xterm", "xterm", "-e", "/usr/bin/tail -f /tmp/mypipe", NULL);
printf("FAILURE\n");
exit(EXIT_FAILURE);
break;
default:
if ((fd_xterm = open("/tmp/mypipe", O_WRONLY)) == -1) {
fprintf(stderr, "Can't open pipe");
exit(1);
}
write(fd_xterm, "yayay\n", 6);
dprintf(fd_xterm, "Hello world\n");
getchar();
break;
}
}
void verbose_xterm(char *format, ...) {
dprintf(fd_xterm, BOLD UNDERLINED "verbose - " RESET);
va_list aptr;
va_start(aptr, format);
dprintf(fd_xterm, format, aptr);
va_end(aptr);
}
void verbose_stdout(char *format, ...) {
printf(BOLD UNDERLINED "verbose - " RESET);
va_list aptr;
va_start(aptr, format);
vprintf(format, aptr);
va_end(aptr);
}
void verbose_noverb(char *format, ...) {
}
void (*verbose)(char *format, ...) = verbose_stdout;
void (*verbose_mode[])(char *, ...) = {
verbose_noverb,
verbose_stdout,
verbose_xterm
};
void verbosity(int mode) {
if (mode == VERBM_XTERMO)
init_outputxterm();
verbose = verbose_mode[mode];
}
主要是:
verbosity(VERBM_XTERMO);
随后多次调用 verbose
。您可以在 init_outputxterm
中看到在创建 xterm 后立即在 xterm 中写入的帐篷,就像在解决方案中一样。但是只有在我通过粗暴地关闭主终端退出程序后才会显示所有内容,使 child 进程成为孤儿(如果我使用 Ctrl-C
退出, child 也会被杀死)。
Xterm 本身不从 stdin 读取,因此向其提供数据不会产生任何影响。但是您可以打开一个命名管道并从中读取 tail -f /tmp/mypipe ,例如:
mkfifo("/tmp/mypipe", 0600);
switch (fork()) {
case -1:
fprintf(stderr, "Fork error.\n");
break;
case 0:
execlp("xterm", "xterm", "-e", "/usr/bin/tail -f /tmp/mypipe", NULL);
exit(EXIT_FAILURE);
break;
default:
;
char buff[512];
int fd = open("/tmp/mypipe", O_WRONLY);
scanf("%s", buff);
write(fd, buff, strlen(buff));
getchar();
break;
}
这将打开命名管道 /tmp/mypipe
。父进程向其写入数据,xterm 中的 tail -f
-进程随后将其输出。
我正在尝试用 C 实现寻呼机,我希望代码打开另一个终端 (xterm
) 并在其中打印一些输出。
所以我先创建一个管道然后fork主程序,child会用tail命令执行xterm,主程序在执行xterm之前先把管道和child里的东西输出将重复将管道输出与 child.
的标准输入文件描述符相关联我可能误解了 pipe
和 dup2
的用法,因为我的代码不起作用。
int p[2];
pipe(p);
char buff[512];
switch (fork()) {
case -1:
fprintf(stderr, "Fork error.\n");
break;
case 0:
dup2(p[0], 0);
close(p[0]);
close(p[1]);
execlp("xterm", "xterm", "tail", NULL);
break;
default:
scanf("%s", buff);
write(p[1], buff, strlen(buff));
getchar();
break;
}
目前,我在 parent 中输入了一些内容,但在这两个过程中都没有打印任何内容。 那么如何在 xterm 和 parent 进程之间创建通信?
编辑:我的程序示例:
#define VERBM_NOVERB 0
#define VERBM_STDOUT 1
#define VERBM_XTERMO 2
static int fd_xterm = -1;
void init_outputxterm() {
mkfifo("/tmp/mypipe", 0600);
switch (fork()) {
case -1:
fprintf(stderr, "Fork error.\n");
break;
case 0:
execlp("xterm", "xterm", "-e", "/usr/bin/tail -f /tmp/mypipe", NULL);
printf("FAILURE\n");
exit(EXIT_FAILURE);
break;
default:
if ((fd_xterm = open("/tmp/mypipe", O_WRONLY)) == -1) {
fprintf(stderr, "Can't open pipe");
exit(1);
}
write(fd_xterm, "yayay\n", 6);
dprintf(fd_xterm, "Hello world\n");
getchar();
break;
}
}
void verbose_xterm(char *format, ...) {
dprintf(fd_xterm, BOLD UNDERLINED "verbose - " RESET);
va_list aptr;
va_start(aptr, format);
dprintf(fd_xterm, format, aptr);
va_end(aptr);
}
void verbose_stdout(char *format, ...) {
printf(BOLD UNDERLINED "verbose - " RESET);
va_list aptr;
va_start(aptr, format);
vprintf(format, aptr);
va_end(aptr);
}
void verbose_noverb(char *format, ...) {
}
void (*verbose)(char *format, ...) = verbose_stdout;
void (*verbose_mode[])(char *, ...) = {
verbose_noverb,
verbose_stdout,
verbose_xterm
};
void verbosity(int mode) {
if (mode == VERBM_XTERMO)
init_outputxterm();
verbose = verbose_mode[mode];
}
主要是:
verbosity(VERBM_XTERMO);
随后多次调用 verbose
。您可以在 init_outputxterm
中看到在创建 xterm 后立即在 xterm 中写入的帐篷,就像在解决方案中一样。但是只有在我通过粗暴地关闭主终端退出程序后才会显示所有内容,使 child 进程成为孤儿(如果我使用 Ctrl-C
退出, child 也会被杀死)。
Xterm 本身不从 stdin 读取,因此向其提供数据不会产生任何影响。但是您可以打开一个命名管道并从中读取 tail -f /tmp/mypipe ,例如:
mkfifo("/tmp/mypipe", 0600);
switch (fork()) {
case -1:
fprintf(stderr, "Fork error.\n");
break;
case 0:
execlp("xterm", "xterm", "-e", "/usr/bin/tail -f /tmp/mypipe", NULL);
exit(EXIT_FAILURE);
break;
default:
;
char buff[512];
int fd = open("/tmp/mypipe", O_WRONLY);
scanf("%s", buff);
write(fd, buff, strlen(buff));
getchar();
break;
}
这将打开命名管道 /tmp/mypipe
。父进程向其写入数据,xterm 中的 tail -f
-进程随后将其输出。