1

メイン ファイルとヘルパー ファイル間の双方向通信を取得しようとしています。メイン ファイルが分岐し、子ファイルがパイプ作業を行ってから、exec を実行します。私の問題は、子 exec から親 exec に情報を送信できるが、その逆はできないことです。以下は、2 つのファイルからのコード全体です。実行できるはずです。双方向通信を機能させるためのヘルプは非常に役立ちます。私はこれでほぼ8時間続けています。

実行すると、「yo 0」と出力されます。これは、メイン ファイルから整数を取得し、それをヘルパーに送信し、その前に yo を追加して送り返すことをテストしたものです。コードの最初のスラブはメイン ファイル、2 番目はヘルパー、3 番目は実行に必要なマップ ファイルです。最後の行の下に空白行がないことを確認してください。4 行目は、実行に必要なエージェント ファイルです。

実行中は [./handler mapfile 20 agentfile.] 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
4

1 に答える 1

1

パイプは、プロセス間の単方向接続です。フォークする前に、パイプを開くと、fd[0] を読み取り、fd[1] を書き込むことができる 2 つのファイル記述子が予約されます。

したがって、双方向の通信が必要な場合は、2 つのパイプを作成する必要があります。次に、1 つを親の書き込みに使用し、2 つ目のパイプをその逆に使用します。

詳細な説明といくつかのサンプル コードについては、http://linux.die.net/man/2/pipe を参照してください。

于 2013-09-26T07:32:11.637 に答える