Xterm 寻呼机 - 两个终端输出 - 使用管道和 dup2

问题描述 投票:0回答:1

我正在尝试用 C 实现寻呼机,我希望代码打开另一个终端(

xterm
)并在其中打印一些输出。

所以我首先创建一个管道并分叉主程序,子程序将使用tail命令执行xterm,主程序将在管道中输出内容,子程序在执行xterm之前将重复将管道与stdin文件描述符相关联孩子。

我可能误解了

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;
}

现在,我在父进程中输入了一些内容,但在两个进程中都没有打印任何内容。 那么如何在 xterm 和父进程之间创建通信呢?

编辑:我的程序示例:

#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 中写入的 tentavie,就像解决方案中一样。但是只有在我通过残酷地关闭主终端退出程序后,所有内容才会显示,使子进程成为孤儿(如果我用
Ctrl-C
退出,子进程也会被杀死)。

c fork xterm dup
1个回答
2
投票

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
进程随后将输出它。

© www.soinside.com 2019 - 2024. All rights reserved.