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:
- Initialization of
student
was wrong. Reduced scope to either child and parent, and just initialized the two variables to focus on problem at hand. - Swapped pipe used between client and server
- Fixed write to send each student id (integer used as address, and student array not being index)
- Fixed read to read each student it (integer used as address, not being read in a loop)
- Reduced scope of
i
to a loop variable - 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