I am learning the way to use ordinary pipeline in linux for the communication between parent and child process. The basic task is just to send a message to the child process from parent process, and then the child do some conversion and pass the result back to the parent. My result shown is some random character like ���. I have been contemplating for a long while and still couldn’t figure out the bug. Thanks for your help.
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#define READ_END 0
#define WRITE_END 1
void convert(char* str);
int main(int argc, char *argv[]){
int pid; /* Process ID */
int status;
char *input;
char *read_msg_c;
char *read_msg_p;
int pfd1[2], pfd2[2];
if (argc !=2){/* argc should be 2 for correct execution */
/* We print argv[0] assuming it is the program name */
printf("Please provide the string for conversion \n");
exit(-1);
}
input = argv[1];
if(pipe(pfd1) < 0 || pipe(pfd2) < 0){
printf("Failed to create a pipe between parent and child \n");
exit(-1);
}
if((pid = fork()) < 0){ /* Fork the process */
printf("Fork error \n");
exit(-1);
}
else if(pid > 0){ /* Parent code */
close(pfd1[READ_END]);
close(pfd2[WRITE_END]);
printf("Process ID of the parent is %d. \n", getpid()); /* Print parent's process ID */
write(pfd1[WRITE_END],input,strlen(input)+1);
close(pfd1[WRITE_END]);
read(pfd2[READ_END],read_msg_p,strlen(input)+1);
printf("%s\n",read_msg_p);
close(pfd2[READ_END]);
}
else if(pid == 0){ /* Child code */
close(pfd1[WRITE_END]);
close(pfd2[READ_END]);
printf("Process ID of the child is %d. \n", getpid()); /* Print child's process ID */
read(pfd1[READ_END],read_msg_c, strlen(input)+1);
printf("Child: Reversed the case of the received string. \n");
write(pfd2[WRITE_END],read_msg_c,strlen(input)+1);
close(pfd1[READ_END]);
close(pfd2[WRITE_END]);
exit(0); /* Child exits */
}
}
void convert(char *str){
int i = 0;
while (str[i]){
if (isupper(str[i])){
str[i] = tolower(str[i]);
}
else if (islower(str[i])){
str[i] = toupper(str[i]);
}
i++;
}
}
Your primary bug is that your variables
read_msg_pandread_msg_care uninitialized pointers.Make them into arrays:
You seem to be missing
<stdio.h>(but you don’t really need<sys/types.h>any more). You should error check your reads and writes; your reads will probably use a different maximum size once you’ve allocated the space for them. Etc.I spotted the problem by looking at the compiler warnings:
Ignore the line numbers; I’d moderately seriously hacked your code by the time these were the only warnings left. But the lines in question are the
read()calls.Example output form the hacked code, working correctly.
Note that the code below reads 18 bytes (including the null), but does not print the null (because of the
nbytes-1argument toprintf().As noted by WhozCraig, there are numerous other changes that could be made. This, however, gets things working reasonably cleanly. You were very close to OK.
Note the debugging techniques: