As a practice for multiprocessor programming in C, I have been trying to make a program that can use files as a way of communication between processes. This part of the program is supposed to use a child process to read the contents of a file and copy them into a temporal file, and then copying them from the temporal file into an output file (preferably doing this line by line). The problem is that after reading all the lines of the file without seeming to present any problems, the loop just goes back to the 2nd line and starts again, and again, and again... for some reason.
It works fine when I use a single process but that is not the goal I'm trying to achieve. Other things that seemed to help were replacing the fprintf()
calls with write()
calls (got rid of lines getting repeated along the way in the output file). I want to think that the problem has something to do with fgets
not returning NULL
when I think it should, but I have no idea why that could happen. The only lesson I think I'm getting from this at this point is to never use fork()
inside loops, since that was pretty much the one thing that my problems and the solutions I found didn't have in common lol. Here are some details of the code I'm using:
Libraries:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <string.h>
The program in question (it is in main() after some assertions):
//opening files with pathnames given as input, creates or overwrites output file
FILE *Nombres = fopen(argv[1], "r");
FILE *Apellidos = fopen(argv[2], "r");
FILE *Output = fopen(argv[3], "w");
//temp file with a fixed name so i can test around
char *tempname = "aaa.txt";
FILE *Tmp = fopen(tempname, "w+");
char linea[MAXIMA_LONGITUD_LINEA];
pid_t hijoid;
while (fgets(linea, MAXIMA_LONGITUD_LINEA, Nombres) != NULL) {
printf("%s\n", linea);
Tmp = fopen(tempname, "w+"); //clear tempfile contents
hijoid = fork();
if (hijoid == 0) {
write(fileno(Tmp), linea, strlen(linea));
exit(0);
} else {
waitpid(hijoid, NULL, 0);
rewind(Tmp);
if (fgets(linea, MAXIMA_LONGITUD_LINEA, Tmp) != NULL) {
write(fileno(Output), linea, strlen(linea));
} else {
printf("Line couldn't be read.\n");
}
}
}
}
Edit: This is a college assignment that was intended to measure the time difference between using pipes and signals vs. using neither of them, now seeing that there was no progress with this method, and its not the way it should be done anyway, I just went ahead and used pipes instead without many issues. Wouldn't mind sharing that code but I think that's already kind of out of the topic.