The UNIX and Linux Forums  

Go Back   The UNIX and Linux Forums > Top Forums > High Level Programming
Google UNIX.COM
Home Forums Register Rules & FAQ Members List Arcade Search Today's Posts Mark Forums Read


High Level Programming Post questions about C, C++, Java, SQL, and other programming languages here.


Other UNIX.COM Threads You Might Find Helpful
Thread Thread Starter Forum Replies Last Post
parent shell is waiting upon the child shell ruchirmayank Shell Programming and Scripting 0 05-06-2008 01:08 AM
shared memory between parent and child, when execl() rvan High Level Programming 1 01-17-2007 03:05 AM
Parent/Child Processes yoi2hot4ya Shell Programming and Scripting 2 05-31-2006 10:27 AM
How hard can it be? ps child/parent velde046 Filesystems, Disks and Memory 2 05-25-2002 01:36 PM
what are parent and child processes all about? xyyz UNIX for Dummies Questions & Answers 1 04-26-2002 12:53 PM

Reply
 
Submit Tools LinkBack Thread Tools Search this Thread Display Modes
  #1 (permalink)  
Old 04-17-2008
Registered User
 

Join Date: Mar 2008
Posts: 15
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiReddit! Stumble this Post!Spurl this Post!
parent not waiting until child complete executing another program through execl()

Hi,
I am calling a program that greps and returns 72536 bytes of data on STDOUT, say about 7000 lines of data on STDOUT.

I use pipe from the program am calling the above program. Naturally, I execute the above program (through execl() ) throught the child process and try to read the STDOUT data through parent process by doing dup2(inpipe[1], STDOUT_FILENO) on child and doing read(inpipe[0], line, 10000), line = char[10000];

I am unable to read all 7000 lines of data from STDOUT into the character array. If I run it straight, only around 450 lines of data is obtained. Then, if I put a sleep(5) function / getchar() in the parent process, the number of lines that I read increases to 900 and 1300. waitpid() is not helping me here. This seems to be some memory problem, but there is no problem with the size of the char array.

Following is the program:

The executable program that prodoces 7000 lines (dfs-zgrep.cc) is:


Code:
# include <stdio.h>
# include <iostream>

using namespace std;

int
main(int argc, char * argv[])
{

	string file_list = "";
   	string search_string = "a";

        file_list = "/home/vivekv/input_file-2.txt";	// file contains 7366 lines of character a (one char only for each line)

  	string query_string = "grep -nr " + search_string + " " + file_list + " | awk -F: '{printf \"%s %s\", $1 \" -\", $2 \" \\n\"}' ";

   	system(query_string.c_str());

 	exit(0);
}

The program (check_pipes.cc) from which am calling the above binary is:


Code:
# include <stdio.h>
# include <iostream>
# include <signal.h>
# include <sys/wait.h>

# define MAXLINE        100000


using namespace std;

int
main(int argc, char * argv[])
{
        int inpipe[2];
        pid_t pid;
        pid_t child_pid;

        if (  pipe(inpipe) < 0 )
        {
                cerr << "PIPE ERROR" << endl;
                return -2;
        }
        if ( (pid = fork()) < 0 )
        {
                cerr << "FORK ERROR" << endl;
                return -3;
        }
        else if (pid == 0)   // CHILD PROCESS
        {
                child_pid = getpid();
                cout << endl << endl << "INSIDE CHILD:-----> pid = " << child_pid << endl << endl;

                close(inpipe[0]);

                if (inpipe[1] != STDOUT_FILENO)
                {
                        if (dup2(inpipe[1], STDOUT_FILENO) != STDOUT_FILENO)
                        {
                                cerr << "dup2 error to stdout" << endl;
                        }

                        execl("/home/vivekv/dfs-fm-1.0.0/dfs-zgrep", "dfs-zgrep", NULL );

                        close(inpipe[1]);
                }


                return 0;
        }
        else    // PARENT PROCESS
        {
                // sleep(5);

                cout << endl << endl << "INSIDE PARENT: waiting for " << pid << " to finish " << endl << endl;

                cout << endl << endl << "CHILD: -----> child_pid = " << child_pid << endl << endl;
                cout << endl << endl << "PARENT:-----> pid = " << pid << endl << endl;

                // waitpid(child_pid, 0, 0);

                int rv;
                char line[MAXLINE];
                close(inpipe[1]);


                if ( (rv = read(inpipe[0], line, MAXLINE)) < 0 )
                {
                        cerr << "READ ERROR FROM PIPE" << endl;
                }
                else if (rv == 0)
                {
                        cerr << "Child Closed Pipe" << endl;
                        return 0;
                }
                cout << endl << endl << "INSIDE PARENT PROCESS...." << endl << line << endl;

                close(inpipe[0]);

                return 0;
        }
        return 0;
}

How do I read all the data and pass it to STDOUT (through cout) without losing data?

Thanks,
vivek

Last edited by vvaidyan : 04-17-2008 at 03:07 PM.
Reply With Quote
Forum Sponsor
  #2 (permalink)  
Old 04-24-2008
Registered User
 

Join Date: Feb 2008
Posts: 18
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiReddit! Stumble this Post!Spurl this Post!
putting read statement in a for loop should help you with this problem ?
Reply With Quote
  #3 (permalink)  
Old 05-15-2008
Registered User
 

Join Date: Mar 2008
Posts: 15
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiReddit! Stumble this Post!Spurl this Post!
you are right!

Thanks for the help gautham... yes, if I execute the read statement one more time with the same pipe and another char array, I am able to read the next set of buffered output in the pipe. Which means that consecutive read()s does help in displaying complete output.

I am just thinking of framing a correct while / for loop for this. Let me know if something crosses your mind - a while / for loop for doing COMPLETE read().

Thanks,
Vivek
Reply With Quote
  #4 (permalink)  
Old 05-15-2008
Registered User
 

Join Date: Mar 2008
Posts: 15
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiReddit! Stumble this Post!Spurl this Post!
# define MAXLINE 1024

char line[MAXLINE];

while( (rv = read(fd2[0], line, MAXLINE)) != 0)
{
// do whatever
}
Reply With Quote
  #5 (permalink)  
Old 05-16-2008
Registered User
 

Join Date: Feb 2008
Posts: 18
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiReddit! Stumble this Post!Spurl this Post!
This should work. You should check for read() > 0 instead of !=0.

Code:
while( (rv = read(fd2[0], line, MAXLINE)) > 0)
Usually for any file, socket, pipe and any other stream read, we should always read in a loop and check for various conditions.

- Dheeraj
Reply With Quote
Google UNIX.COM
Reply



Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



All times are GMT -7. The time now is 08:08 PM.


Powered by: vBulletin, Copyright ©2000 - 2006, Jelsoft Enterprises Limited.
The UNIX and Linux Forums Content Copyright ©1993-2008 The CEP Blog All Rights Reserved -Ad Management by RedTyger

Search Engine Optimization by vBSEO 3.1.0

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102