I need to write a program that create pipe send filename from command line to child process. In child read that file and send it back using pipe. Parent process should print the file. if error occur in child process error must be send to parent process.
here is my code, it print some junk along file file (and also it disable scrolling in terminal emulator when I run it).
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
void main(int argc, char *argv[]) {
int pipefd[2];
char buff[100];
int childpid;
int size;
FILE *file;
if (argc != 2) {
printf("usage:\n%s <filename>\n", argv[0]);
exit(1);
}
if (pipe(pipefd) < 0) {
perror("can't open pipe\n");
}
if ((childpid = fork()) == 0) {
sleep(1);
size = read(pipefd[0], buff, sizeof(buff));
file = fopen(buff, "r");
if (file == NULL) {
write(pipefd[1], "Can't open file", 15);
exit(1);
}
while (!feof(file)) {
if (fgets(buff, sizeof(buff), file) == NULL) {
write(pipefd[1], "Error reading file", 18);
} else {
write(pipefd[1], buff, sizeof(buff));
}
}
} else if (childpid > 0) {
size = strlen(argv[1]);
if (write(pipefd[1], argv[1], size) != size) {
perror("Error writing to pipe\n");
}
wait(NULL);
while ((size = read(pipefd[0], buff, sizeof(buff))) > 0) {
write(1, buff, size);
}
}
exit(0);
}
Your program works as intended after quite a few changes. Lets list out what all changes are required and why-
I) Both in the child and parent, close the respective pipes as soon as you are done with them. From man page of
read(3),So do something like this in your code everywhere where the job pipes is over,
You hadn’t closed the write end of of the pipe in the child and your parent was blocking in the
readII) You are using something like
while(fgets(...))in a loop to read data from file. This will bomb when there are newlines in the file andfgetsreturns multiple times, overwriting thebuffereverytime during the processI always use simple
fgetcandfeofcombination to read from file. So, change your file reading mechanism to something likeIII) While writing the file data from the child, you should use
strlen(as we have already made sure buffer is null terminated, see above ) and notsizeofas the buffer may not be full at all and you will end up writing junk. So, changeto
IV) Follow a safe
exitfrom the child and parent after their job is done. Something likeand
PS: I’ve changed the file reading logic, so your compiler error is gone now and do follow the advice given by n.m.