Home > Net >  Using pipes to pass struct information
Using pipes to pass struct information

Time:04-14

I am trying to passing struct information between the parent and the child process using pipes but couldn't manage to catch my error. I would be really grateful if you can show me the way or give suggestions to improve the problem.

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

struct Student {
    int ID;
    char Name[10];
};


int main() {
    int i;
    struct Student student[5] = {0, '\0'};
    char *Names[5] = {"David", "Roger", "Syd", "Richard", "Nick"};
    pid_t pid = fork();
    char *info[3];
    int fd[2];
    pipe(fd);
    if (pid < 0) {
        printf("Fork failed.");
        exit(1);

    }


    else if (pid == 0) {// Child
        close(fd[1]);
        printf("Child Process: \n");

        for (i = 0; i < 5;   i) {
            student[i].ID = i   1;
            strcpy(student[i].Name, Names[i]);
        }

        write(fd[0], student[0].ID, sizeof(int));

        for (i = 0; i < 5;   i) {
            printf("Student name is: %s, ID is: %d\n", student[i].Name, student[i].ID);
        }

        printf("Child Process has been completed.\n");


    }

    else {// Parent
        wait(NULL);
        close(fd[0]);


        read(fd[1], student[0].ID, sizeof(student));

        printf("\nParent Process Print\n");

        for (i = 0; i < 5;   i) {
            printf("Student name is: %s, ID is: %d\n", student[i].Name, student[i].ID);
        }
    }


    return 0;
}

and the output is:

Child Process:
Student name is: David, ID is: 1
Student name is: Roger, ID is: 2
Student name is: Syd, ID is: 3
Student name is: Richard, ID is: 4
Student name is: Nick, ID is: 5
Child Process has been completed.

Parent Process Print
Student name is: , ID is: 0
Student name is: , ID is: 0
Student name is: , ID is: 0
Student name is: , ID is: 0
Student name is: , ID is: 0

CodePudding user response:

Say, I have a parent process and a few child processes, and a structure as so:

Code:

typedef stuct{
        char a[101];
        int b;
}cs;

And I want to pass this through a pipe.

Assume

CS[0]->a = RAT CS[0]->b = 469

I was told that I can simply use:

write(fd[1], CS[0], sizeof(CS*)); read(fd[0], CS[0], sizeof(CS*));

Then I try printf("%s",CS[0]->a);

Returns null.

CodePudding user response:

I fixed the following issues:

  1. Initialization of student was wrong. Reduced scope to either child and parent, and just initialized the two variables to focus on problem at hand.
  2. Swapped pipe used between client and server
  3. Fixed write to send each student id (integer used as address, and student array not being index)
  4. Fixed read to read each student it (integer used as address, not being read in a loop)
  5. Reduced scope of i to a loop variable
  6. Enhanced to send and receive Name, too.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>

struct Student {
    int ID;
    char Name[10];
};

int main() {
    int fd[2];
    if(pipe(fd)) {
        printf("pipe failed\n");
        return 1;
    }
    switch(fork()) {
        case -1:
            printf("Fork failed.");
            return 1;
            break;
        case 0: {
            close(fd[0]);
            struct Student student[5] = {
                { 1, "David" },
                { 2, "Roger" },
                { 3, "Syd" },
                { 4, "Richard" },
                { 5, "Nick" },
            };
            printf("Child Process: \n");
            for (int i = 0; i < 5; i  ) {
                printf("Student name is: %s, ID is: %d\n", student[i].Name, student[i].ID);
                write(fd[1], &student[i].ID, sizeof(student[i].ID));
                size_t len = strlen(student[i].Name);
                write(fd[1], &len, sizeof(len));
                write(fd[1], student[i].Name, len);
            }
            printf("Child Process has been completed.\n");
            break;
        }
        default: {
            struct Student student[5] = { 0 };
            wait(NULL);
            close(fd[1]);
            printf("\nParent Process Print\n");
            for (int i = 0; i < 5; i  ) {
                read(fd[0], &student[i].ID, sizeof(student[i].ID));
                size_t len;
                read(fd[0], &len, sizeof(len));
                read(fd[0], student[i].Name, len);
                printf("Student name is: %s, ID is: %d\n", student[i].Name, student[i].ID);
            }
            break;
        }
    }
    return 0;
}

and the resulting output:

Child Process:
Student name is: David, ID is: 1
Student name is: Roger, ID is: 2
Student name is: Syd, ID is: 3
Student name is: Richard, ID is: 4
Student name is: Nick, ID is: 5
Child Process has been completed.

Parent Process Print
Student name is: David, ID is: 1
Student name is: Roger, ID is: 2
Student name is: Syd, ID is: 3
Student name is: Richard, ID is: 4
Student name is: Nick, ID is: 5
  • Related