Member Avatar for rafi1082

i need to write a program that get the argument through argv[] and do a checksum to the input files where:
argv[1]-the program to run eg.md5sum
argv[2]-the output file with all results
argv[3..]- the files
the program need to run all checks in parallel using fork() an the output file suppose to be saved in the same order of the file input.
eg ./a.out md5dum output test test2 test3
the program suppose to run 3 child process an send the result to parent that will write
buhdubhaug80u48y9 test
ugahwerg8yu089gaw test2
uohgsdog8h840hgas test3
i wrote a good code but i can only see the first file output (test) and can't see the rest. if i dont use the dup2 command i can see the output but to console and i need ot to go to a file so i'm sure the problem is in the pipe somewhere
i really hope you can help
tnx
btw is there a way do debug child? (my compiler is eclipse)

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/wait.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 60

int main (int argc, char* argv[]){
	int fdfork, fdfile,fdf;
	int pfd[argc - 3][2];
	char temp_arr[SIZE];
	int i,k,j;

//in order to create son processes and pipe matrix for all son

	for(i = 0 ; i < argc-3 ; i++){
		if(pipe(pfd[i]) == -1)// if pipe() didnt succeed exit
			exit(1);
	
		fdfork = fork();
		if(fdfork == -1) // if fork() didnt succeed exit
			exit(1);

		if (fdfork > 0) // father close the writing entrence in the pipe matrix
			close(pfd[i][1]);
		
		else if(fdfork==0)//for each son determin an index i and exit the loop
			break;
	}
	if(fdfork==0){
	//son process only will enter open files on argv simultanesly and write to father process 
		close(pfd[i][0]);//close reading pipe
		dup2(pfd[i][1],1);//change output to pipe
		execlp(argv[1],argv[1],argv[i+3],NULL);//run program
		exit(-1);//if running program failed
	}
	//father wait for the all children
	for(j = 0 ; j< argc-3 ; j++)
		wait(NULL);

	for(j = 0 ; j< argc-3 ; j++)
		close(pfd[j][1]);//close writing pipe

	fdfile = open(argv[2],O_WRONLY|O_CREAT|O_TRUNC,0600);  // the file for writing
	dup2(fdfile,1);//chane output to write to file
	for(k = 0 ; k < argc-3 ; k++){
		fdf = read(pfd[k][0], temp_arr ,sizeof(temp_arr));//read from pipe
		temp_arr[fdf-1]='\n'; //add \n to add a row
		temp_arr[fdf]='\0';//so we can print
		printf("%s\n",temp_arr);//clear array (not neccesary?
		for (i=0 ; i<SIZE ; i++)
			temp_arr[i]='0';
	}
	return 0;
}

The problem is with parent closing the write ends too early, so that the corresponding file descriptor is reused in the next pipe() call; bottom line is, at the read() time parent attempts to read from the closed descriptor.
Comment out lines 28-29 and see for yourself.

PS: always test errno after every system call.
PPS: I don't know how to debug a child in eclipse.

commented: helped me solve a bug +0
Member Avatar for rafi1082

thank u so much i was looking for this bug for houres.
just wanna know
when am i suppose to close a pipe?
why did the first one work?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.