2016-02-26 18 views
0

我試圖用C寫一個字符串到Linux上的剪貼板。我打算使用xsel -ib(從標準輸入中取一個字符串並將其設置爲當前剪貼板內容)。例如,在bash中,做echo Hello world | xsel -ib會將「Hello World」設置爲clipbord。使用IPC重定向stdin在一個while循環

我的代碼包含一個簡單的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循環對於我能夠不時地將不同的字符串輸出到剪貼板是非常重要的。我如何在不終止程序的情況下做到這一點。

+3

您正在泄漏父項中未封閉的文件描述符。該孩子沒有得到'EOF',因爲文件在父文件中沒有關閉,因此不會終止。最終,您將耗盡文件描述符,否則由於達到最大數量的用戶進程,fork()將失敗。 – EOF

+1

首先,您應該真的在檢查所有系統調用中的錯誤。其次,你應該['等待](http://man7.org/linux/man-pages/man2/wait.2.html)在父母的子進程。第三,沒有什麼大不了的,但是你不需要關閉標準輸入文件描述符,它可以通過['dup2']完成(http://man7.org/linux/man-pages/ man2/dup2.2.html)調用(你應該在'dup2'調用之後關閉'pipes [0]')。 –

+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 
} 
+0

謝謝!這工作。我所需要的只是失蹤的「關閉」(管道[1])。 (我確實在我的原始代碼中檢查了系統調用的錯誤,只是將其刪除以使我的代碼片段變小)。我是IPC的新手,很長一段時間後回到C隊。 :) – Irfan