2016-02-26 1 views
0

Я пытаюсь написать строку в буфер обмена на linux с C. Я планирую использовать 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

Прежде всего, вы должны действительно проверять наличие ошибок во всех системных вызовах. Во-вторых, вы должны ['wait'] (http://man7.org/linux/man-pages/man2/wait.2.html) для дочернего процесса в родительском. В-третьих, и неважно, но вам не нужно «закрывать» стандартный дескриптор входного файла, это будет сделано с помощью ['dup2'] (http://man7.org/linux/man-pages/ man2/dup2.2.html) (вы должны закрывать 'pipe [0]', хотя после вызова 'dup2'). –

+0

Не могли бы вы рассказать о том, как программа, которую вы показываете «не работает»? * Как это не работает? Вы получаете ошибки сборки? Runtime падает? Неожиданные результаты? Что-то другое? –

ответ

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

Спасибо! Это сработало. Все, что мне было нужно, это отсутствие «закрытия» (pipe [1]) ». (У меня была проверка ошибок для системных вызовов в моем исходном коде. Просто удалите ее, чтобы уменьшить мой сниппп). Я новичок в IPC и возвращаюсь на C после долгого времени. :) – Irfan