I've been beating myself over the head for days now on this project, and I can't seem to find any kind of possible resolution.
To put it simply, the program is supposed to fork a process for each regular file in a directory specified at the command line (which each will enter a loop waiting for data from the parent), and use pipes to communicate with the parent.
The parent then askes the user for a character to search for, and pipes this to each one of the children. The children then search the files they have open and pipe a count back to the parent, who then totals these counts up and prints the sum.
For some reason, I cannot get the parent process to execute at all. I tried the program on a test directory with two files, and it seems that I get 2 processes forked, but then the parent never executes afterwards, leaving my program in kind of a deadlock.
Any help would be apperciated!
Code:
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/uio.h>
char searchChar;
int searchCharNum = 0, checkedFileCount=0, numFiles = 0;
/***********************************************************/
void die(const char*errmsg);
void* search(void* fileName, pid_t writeHandle, pid_t readHandle);
int main(int argc, char *argv[])
{
if (argc != 2)
die("Only accepts one arguement, a directoryname\n");
DIR *dirp = opendir(argv[1]);
if(!dirp)
die("The directory name you provided is an invalid directory.\n");
if(chdir(argv[1]) !=0)
die("Error changing directory");
pid_t pid;
char Buffer[1];
int c2p[256][2], p2c[1]; /* child to parent pipe */
struct dirent *dp;
pipe(p2c);
while((dp = readdir(dirp)) != NULL)
{
struct stat sb;
if(stat(dp->d_name, &sb) != -1)
{
if(S_ISREG(sb.st_mode))
{
numFiles = numFiles + 1;
if((pid = fork()) == 0)
{
pipe(c2p[numFiles]);
close(c2p[numFiles][0]); // close write end of the pipe
close(p2c[1]); // close write end
search(dp->d_name, c2p[numFiles][1], p2c[0]);
_exit(0);
}
}
}
}
while(1)
{
close(p2c[0]);
int i = 0;
while(i < numFiles)
close(c2p[i][1]);
int total = 0;
printf("Enter a character to search for(Ctrl+D and [enter] to stop): ");
searchChar = getchar(); //get the first char.
while(getchar() != '\n'); /* clear out anything else */
searchCharNum++; /* that may be in stdin */
if (searchChar == (char)EOF)
{
printf("Goodbye\n");
break;
}
write(p2c[1], Buffer, 1);
while(checkedFileCount != numFiles);
// do nothing
int j = 0;
printf("%d\n",numFiles);
while(j < numFiles)
{
read(c2p[j][0], Buffer, 1);
printf("%c\n",Buffer[0]);
total += (int)Buffer[0];
i++;
}
printf("\nThere where %d occurances of %c found in %d files listed in the directory %s\n", total, searchChar, numFiles, argv[1]);
searchCharNum = 0;
}
(void)closedir(dirp);
return 0;
}
void die(const char*errmsg)
{
printf("%s\n",errmsg);
exit(1);
}
void* search(void* fileName, pid_t writeHandle, pid_t readHandle)
{
char Buffer[1]; // we only need one character
while(1)
{
char x;
while(searchCharNum == 0)
sleep(1); // take a nap
read(readHandle, Buffer, 1);
int count = 0;
FILE *fd;
if((fd = fopen(fileName,"r")) !=NULL)
{
while((x = fgetc(fd)) != EOF)
if (x == Buffer[0])
count++;
}
else
die("error opening file");
Buffer[0] = count;
write(writeHandle, Buffer, 1);
}
}