2013-05-04 4 views
0

im пытается передать значения из одной программы в другую с помощью трубки.Определите тот же канал для двух разных программ

Первая программа создала трубу, а затем процесс сына с вилкой и в процессе обработки сына, которую она выполнила с помощью другой программы.

Я хочу отправить символы от первой программы к другой, пока они работают с трубой, но я не знаю, как это сделать, потому что fd [2] определяется только в первой программе.

код первой программы:

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <stdbool.h> 
#include <termios.h> 
#include <signal.h> 

char getch(); 

int main() 
{ 
    bool selected; 
    int fd[2],pid; 
    char choice; 
    pipe(fd); 
    pid=fork(); 
    if(pid==0) 
    { 
     execlp("./draw.out", "draw.out", NULL); 
    } 
    else 
    { 
     do 
     { 
      choice=getch(); 
      close(fd[0]); 
      write(fd[1],&choice,1); 
      close(fd[1]); 
      kill(pid,SIGUSR2); 
     }while(choice!='q'); 

    } 

    return 1; 
    //getchar(); 

} 

Код второй программы:

#

include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <stdbool.h> 
#include <signal.h> 


typedef struct 
{ 
    int x; 
    int y; 
}Point; 

typedef struct 
{ 
    Point dots[3]; 
}Tool; 

void drawBoard(int array[][20]); 
void initBoard(int array[][20]); 
Tool retrieveTool(); 
bool changeLocation(int array[][20],Tool* tool); 
void my_handler(int signum); 

int main() 
{ 
    bool nextTool=true; 
    Tool temp=retrieveTool(); 
    int gameBoard[20][20]; 
    signal(SIGUSR2, my_handler); 
    initBoard(gameBoard); 
    changeLocation(gameBoard,&temp); 
    drawBoard(gameBoard); 
    while(true) 
    { 
     sleep(1); 
     system("clear"); 
     if(!changeLocation(gameBoard,&temp)) 
      temp=retrieveTool(); 
     drawBoard(gameBoard); 
    } 
    return 1; 
    //getchar(); 

} 

void my_handler(int signum) 
{ 
    char geth='a'; 
    if (signum == SIGUSR2) 
    { 


    close(fd[1]); 
    read(fd[0],&geth,1); 
    close(fd[0]); 

    printf("Received SIGUSR2!%c\n",geth); 
    } 
} 

Как вы можете видеть в первой программе я определить FD [2 ] в трубку, и я посылаю символ от пользователя к трубе. Я хочу, чтобы обработчик сигнала «my_handler» в другой программе читал из того же самого канала, но fd здесь не определен (во второй программе).

Как мне это сделать?

ответ

1

Пока переменная pipe fd находится только в родительском, фактические дескрипторы файлов являются общими. Они могут использоваться, если ваша программа знает, что они (как целые числа). Итак, есть несколько вариантов

  1. Передайте номер дескриптора в программе детского в ехес вызова (так что-то вроде

    Sprintf (Buf1, "% D", Fd [0]);

    функции имеют ("./ draw.out", "draw.out", "-в", buf1, NULL);

    А затем прочитать дескриптор из ARGV в розыгрыше

  2. A. во-вторых, довольно распространенный вариант i s использовать соглашение о вводе fd 0 и вывод fd 1. Это работает, только если ваша дочерняя программа не использует stdin (или std :: cin). В противном случае вы можете просто выбрать другой дескриптор, который, как вы уверены, будет доступен (это сложнее, чем кажется). Для этого вам нужно скопировать дескриптор после вилки, но перед exec. Что-то вроде

    dup2 (fd [0], 0);

    закрыть (fd [0]);

    закрыть (fd [1]); // Ребенок не нуждается в Fd [1]

    (.... функций имеют)

Во всех случаях необходимо, чтобы убедиться, что все неиспользуемые дескрипторы, включая старые копии, закрываются. Я бы посоветовал сделать закрытые звонки как можно скорее (в начале каждого блока после вилки). В противном случае вы не столкнетесь с EOF в дескрипторе. BTW, ваши программы закрывают дескрипторы либо в цикле, либо в обработчике, который может быть вызван несколько раз - ни один из них не может быть прав. Вы должны проверить возвращаемые значения из чтения, записи и закрыть, чтобы помочь отлаживать вещи.

Смежные вопросы