2013-09-26 42 views
1

我想要獲得主文件和幫助程序文件之間的雙向通信。 主要的文件叉,和孩子做一些管道工作,然後運行一個exec。 我的問題是,我可以從兒童執行官發送信息給家長,但不是相反。 下面是我的兩個文件的完整代碼,所以你應該可以運行它。 獲得雙向溝通工作的任何幫助將非常有幫助。我已經連續近8個小時了。用叉子和管道之間的雙向通信

當你運行它時,你會看到它打印出「喲0」。這是我測試它從主文件獲取一個整數,將它發送給幫助者,在它前面添加喲並將其發回。第一塊代碼是主文件,第二塊是助手,第三塊是運行它所需的映射文件。確保最後一行下面沒有空行,第四行是運行它所需的代理文件。

正在運行的是[./handler mapfile 20代理文件。] int 20還沒有做任何事,但你需要它在那裏運行文件。 如果有人真的去努力做這一切,並幫助我,我感激不盡

主文件(handler.c)

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <ctype.h> 
#include <unistd.h> 
#include <sys/wait.h> 


enum ErrorCode { 
     SHOW_USAGE = 1, BAD_STEPS, OPEN_MAP_ERROR, CORRUPT_MAP, 
     OPEN_AGENT_ERROR, CORRUPT_AGENTS, AGENT_ERROR, 
     AGENT_WALLED, AGENT_COLLIDED, TOO_MANY_STEPS, INVALID_AGENT_RESPONSE, 
     AGENT_CLOSED, AGENT_DIED, SIGINT_REC 
}; 

typedef struct { 
     int valid; 
     int row, col; 
} Point; 

typedef struct { 
     Point point; 
     int number; 
     char name; 
     char param[20]; 
     char type[20]; 
} Agent; 

typedef struct { 
     int rows, cols; 
     char **grid; 
} Map; 

Map map; 
Map agentMap; 
int listSize = 0; 

void error(enum ErrorCode e) { 
     switch(e) { 
     case SHOW_USAGE: 
       fprintf(stderr, "Usage: handler mapfile maxsteps agentfile\n"); 
       break; 
     case BAD_STEPS: 
       fprintf(stderr, "Invalid maxsteps.\n"); 
       break; 
     case OPEN_MAP_ERROR: 
       fprintf(stderr, "Unable to open map file.\n"); 
       break; 
     case CORRUPT_MAP: 
       fprintf(stderr, "Corrupt map.\n"); 
       break; 
     case OPEN_AGENT_ERROR: 
       fprintf(stderr, "Unable to open agent file.\n"); 
       break; 
     case CORRUPT_AGENTS: 
       fprintf(stderr, "Corrupt agents.\n"); 
       break; 
     case AGENT_ERROR: 
       fprintf(stderr, "Error running agent.\n"); 
       break; 
     case AGENT_WALLED: 
       fprintf(stderr, "Agent walled.\n"); // needs fixing, check spec sheet 
       break; 
     case AGENT_COLLIDED: 
       fprintf(stderr, "Agent collided.\n"); // same as AGENT_WALLED 
       break; 
     case TOO_MANY_STEPS: 
       fprintf(stderr, "Too many steps.\n"); 
       break; 
     case INVALID_AGENT_RESPONSE: 
       fprintf(stderr, "Agent sent invalid response.\n"); // fixiing 
       break; 
     case AGENT_CLOSED: 
       fprintf(stderr, "Agent exited with status.\n"); // fixiing 
       break; 
     case AGENT_DIED: 
       fprintf(stderr, "Agent exited due to signal.\n"); // fixing 
       break; 
     case SIGINT_REC: 
       fprintf(stderr, "Exiting due to INT signal.\n"); 
       break; 
     } 
     exit(e); 
} 


void print_map(Map map) 
{ 
     int r; 
     for (r = 0; r < map.rows; ++r) { 
       printf("%s", map.grid[r]); 
     } 
     puts(""); 
} 

void print_agents(Agent *agents, int size) 
{ 
     int i; 
     for (i = 0; i < size; i++) { 
       Agent temp = agents[i]; 
       printf("%d %d %c %d %s %s %i\n", temp.point.row, temp.point.col, temp.name, temp.number, temp.type, temp.param, i); 
     } 
     puts(""); 
} 


void readMap(char *file) 
{ 
     int r; 
     FILE *fd = fopen(file, "r"); 
     char buffer[20]; 
     char d; 

     if (!fd) { 
       error(OPEN_MAP_ERROR); 
     } 

     if (fgets(buffer, 20, fd) == NULL) { 
       error(CORRUPT_MAP); 
     } 

     if (sscanf(buffer, "%d %d%1[^\n]\n", &map.rows, &map.cols, &d) != 2 || 
      map.rows < 1 || map.rows > 999 || map.cols < 1 || map.cols > 999) { 
       error(CORRUPT_MAP); 
     } 

     map.grid = malloc(map.rows * sizeof(char *)); 
     for (r = 0; r < map.rows; ++r) { 
       map.grid[r] = calloc(map.cols + 2, sizeof(char)); 
       if (fgets(map.grid[r], map.cols + 2, fd) == NULL || 
             map.grid[r][map.cols] != '\n') { 
         error(CORRUPT_MAP); 
       } 
     } 

     fclose(fd); 

} 

void checkAgent(char *file) 
{ 
     FILE *fd = fopen(file, "r"); 
     if (!fd) { 
       error(AGENT_ERROR); 
     } 
     fclose(fd); 
} 

int growList (Agent **agentList, int curSize, int increaseNum) 
{ 
     const int newSize = curSize + increaseNum; 
     Agent *temp = (Agent*) realloc(*agentList, (newSize * sizeof(Agent))); 

     if (temp == NULL) { 
       exit(20); 
     } 
     else { 
       *agentList = temp; 
       return newSize; 
     } 
} 


Agent* readAgentFile(char *file, Agent *agentList) 
{ 
     int readCount = 0; 
     FILE *fp = fopen(file, "r"); 
     char buffer[80]; 

     listSize = 0; 
     if (!fp) { 
       error(OPEN_AGENT_ERROR); 
     } 

     if (fgets(buffer, 80, fp) == NULL) { 
       error(CORRUPT_AGENTS); 
     } 

     rewind(fp); 
     while (fgets(buffer, 80, fp) != NULL) { 
       if (buffer[0] != '#') { 
         Agent agent; 
         sscanf(buffer, "%d %d %c %s %s" ,&agent.point.row, &agent.point.col, &agent.name, agent.type, agent.param); 
         checkAgent(agent.type); 
         agent.number = readCount+1; 
         listSize = growList(&agentList, listSize, 1); 
         agentList[readCount] = agent; 
         readCount++; 
       } 
     } 
     if (readCount == 0) { 
       error(CORRUPT_AGENTS); 
     } 

     fclose(fp); 
     return agentList; 
} 

void createAgentMap() 
{ 
     int i,j; 
     agentMap = map; 
     for (i=0; i < map.rows; i++) { 
       for (j=0; j < map.cols; j++) { 
         char c = map.grid[i][j]; 
         if (c == '.') { 
           agentMap.grid[i][j] = ' '; 
         } 
       } 
     } 
} 

int main(int argc, char **argv) 
{ 
     int steps; 
     int pid; 
     int returnStatus; 
     int i; 
     int out_pipe[2]; 
     int in_pipe[2]; 
     char ch[20]; 

     Agent firstAgent; 
     Agent *agentList =(Agent *) calloc(1, sizeof(Agent)); 

     if (argc != 4) { 
       error(SHOW_USAGE); 
     } 

     sscanf(argv[2], "%d", &steps); 
     if ((steps < 1)) { 
       error(BAD_STEPS); 
     } 

     readMap(argv[1]); 
     agentList = readAgentFile(argv[3], agentList); 
     firstAgent = agentList[0]; 
     createAgentMap(); 

     for (i=0; i < listSize; i++) { 

       if (pipe(out_pipe) < 0) { 
         perror("Pipe Error"); 
       } 
       if (pipe(in_pipe) < 0) { 
         perror("Child pipe error"); 
       } 

       Agent temp; 
       temp = agentList[i]; 

       switch (pid = fork()) 
       { 
         case -1: 
           perror("Can't fork.\n"); 
           exit(20); 
         case 0: 
           /* Child */ 
           /*close(1); 
           dup(in_pipe[1]); 
           close(0); 
           dup(out_pipe[0]); 
           close(in_pipe[0]); 
           close(out_pipe[1]);*/ 

           dup2(out_pipe[0], 0); 
           dup2(in_pipe[1], 1); 

           execlp(temp.type, temp.type, temp.param, (char *)0); 
           perror("No exec"); 
         default: 
           //close(1); 
           //dup(handlerChild[1]); 
           //fprintf(stdout, "%d", listSize); 

           write(out_pipe[1], "%d", listSize); 

           close(in_pipe[1]); 
           close(0); 
           dup(in_pipe[0]); 

           if (fgets(ch, 20, stdin) == NULL) { 
             break; 
           } 
           printf("%s\n", ch); 
       } 

     } 

     while (steps > 0) { 


       steps -= 1; 

     } 

     return 0; 

} 

幫助文件(simple.c)

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <unistd.h> 

typedef struct { 
     int valid; 
     int row, col; 
} Point; 

typedef struct { 
     int numAgents; 
     char agentNames[80]; 
     int agentNumber; 
} Info; 

typedef struct { 
     int rows, cols; 
     char **grid; 
} Map; 

Map agent_map; 

int main(int argc, char **argv) 
{ 
     int steps = 10; 
     int simple_pipe[2]; 
     int dir; 
     char inputDir; 
     char input_stream[20]; 
     int in = dup(0); 
     Info info; 

     if (argc == 2) { 
       sscanf(argv[1], "%c1", &inputDir); 
       switch (inputDir) { 
         case 'N': dir = 0; break; 
         case 'E': dir = 1; break; 
         case 'S': dir = 2; break; 
         case 'W': dir = 3; break; 
         default : fprintf(stdout, "Invalid params.\n"); exit(2); 
       } 

     } 
     else { 
       fprintf(stdout, "Incorrect number of params.\n"); 
       exit(1); 
     } 

     close(0); 
     dup(simple_pipe[0]); 
     fgets(input_stream, 20, stdin); 

     sscanf(input_stream, "%d", &info.numAgents); 
     //printf("%d", info.numAgents); 
     //printf("this is the input: %s\n", input_stream);  // This is successfully printing to stdout in the pipe 
     fprintf(stderr, "yo %d \n", info.numAgents); 
     while (steps > 0) { 


     steps -= 1; 
     } 
     exit(0); 


} 

地圖文件

6 6 
##..## 
#....# 
#.##.# 
#....# 
##.... 
###### 

代理文件

1 1 A ./simple E 
2 2 B ./simple N 
5 2 C ./simple S 

回答

1

管道是跨過程的單向連接。在fork之前,您打開管道並保留兩個文件描述符,其中可讀取fd [0]並可寫入fd [1]。

所以,當你想要雙向平行時,你需要創建兩個管道,然後使用一個用於讀取父級寫入的子節點和第二個管道。

一些示例代碼

更詳細的解釋可以foun dhere:http://linux.die.net/man/2/pipe

+0

我想我已經明白你的什麼管,我只是不知道,如果我這樣做是正確使用是什麼意思2執行函數之間的分配 –

+0

您正在調用dup(),但不要將新的fd分配給任何地方。 – Devolus