使用IPC在while循环中重定向stdin

时间:2016-02-26 12:06:40

标签: c ipc stdin

我正在尝试使用C在linux上将字符串写入剪贴板。我计划使用xsel -ib(从标准输入中获取字符串并将其设置为当前剪贴板内容)。例如,在bash中,执行echo Hello world | xsel -ib会将“Hello World”设置为clipbord。

我的代码由一个简单的IPC组成,当我的程序(父)完成执行时,它运行良好,但如果我将IPC包装在while循环中则不起作用。

#include<unistd.h>
void main()
{
    while (1) { // 1
        int pipes[2] = { 0 };
        pipe(pipes);
        if (fork()) {
            close(pipes[0]);
            write(pipes[1], "hello world", sizeof("hello world"));
        } else {
            close(0);
            dup2(pipes[0], STDIN_FILENO);
            close(pipes[1]);
            execl("/usr/bin/xsel", "xsel", "-ib", NULL);
        }
        printf("\nTesting..");
        sleep(3); // 2
    } // 3
}

如果我删除由“1”,“2”和“3”注释的行,它可以正常工作。但是有一个while循环对于我能够不时地向剪贴板输出不同的字符串至关重要。如何在不终止我的程序的情况下执行此操作。

1 个答案:

答案 0 :(得分:1)

以下是一些小的更改,应该使程序更具可调试性,并至少修复一些问题。

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/wait.h>
int main() /*correct declaration is int main()...*/
{
    while (1) { // 1
        int pipes[2] = { 0 };
        if (pipe(pipes)){
            perror("pipe() failed");
            exit(EXIT_FAILURE);
        }
        pid_t pid = fork();
        if (pid == -1){
            perror("fork() failed");
            exit(EXIT_FAILURE);
        }
        if (pid) {
            close(pipes[0]);
            write(pipes[1], "hello world", sizeof("hello world"));
            close(pipes[1]);
/*prevents file descriptor leak, also causes a read() to signal EOF rather than block indefinitely*/
            int status;
            wait(&status); /*prevents child zombification*/

        } else {
            close(0);
            dup2(pipes[0], STDIN_FILENO);
            close(pipes[1]);
            execl("/usr/bin/xsel", "xsel", "-ib", NULL);
        }
        printf("\nTesting..");
        sleep(3); // 2
    } // 3
}