Thread: Need some help with pipes please.

  1. #1
    Registered User carrja99's Avatar
    Join Date
    Oct 2002
    Posts
    56

    Need some help with pipes please.

    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); 	 
    		}
    	}
    I am Error. When all else fails, use fire.

    My Current Screenshot

  2. #2
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    Here's a couple of things:

    What terminates this loop:
    Code:
        while (i < numFiles)
        {
          close(c2p[i][1]);
        }
    >>int p2c[1]
    How many elements in that array? Don't you need two?

    >>printf("Enter ...
    Use fflush(stdout); after this line to force the text to the screen.

    >>searchChar == (char) EOF)
    Don't use a cast here. Make searchChar an int. See:
    http://faq.cprogramming.com/cgi-bin/...&id=1043284351

    >>write(p2c[1], Buffer, 1);
    Which child are you intending to write to? I'm not sure that the data will go to all children (have to look that one up).
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Pipes sometimes fail
    By EVOEx in forum Linux Programming
    Replies: 2
    Last Post: 05-02-2009, 01:47 PM
  2. Pipes
    By Martin Kovac in forum C Programming
    Replies: 1
    Last Post: 03-31-2009, 03:09 AM
  3. Help - newbie playing with pipes
    By kotoko in forum C Programming
    Replies: 14
    Last Post: 10-21-2008, 04:41 PM
  4. pipes in c
    By ajal1 in forum C Programming
    Replies: 6
    Last Post: 10-29-2005, 03:29 PM
  5. Services and Pipes
    By nickname_changed in forum Windows Programming
    Replies: 0
    Last Post: 07-16-2003, 06:46 AM