Thread: popen()

  1. #1
    Registered User
    Join Date
    Jan 2009
    Posts
    159

    popen()

    Hi,
    I wonder if I use popen(), the parent process will wait for the child process to finish or continue without waiting?
    Thanks and regards!

  2. #2
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    >> I wonder if I use popen(), the parent process will wait for the child process to finish or continue without waiting?

    Why ask when the compiler (or better yet, the docs) can answer that for you?
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  3. #3
    Registered User
    Join Date
    Jan 2009
    Posts
    159
    "popen is used to read and write to a unix pipe."
    So is it correct the parent process will wait for the child process to finish?

  4. #4
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    >> "popen is used to read and write to a unix pipe."

    I seriously doubt that's all your documentation has to say about it. And if it does, you need a better reference.

    Code:
     NAME
    
        popen - initiate pipe streams to or from a process 
    
     SYNOPSIS
    
    
    
        #include <stdio.h>
    
        FILE *popen(const char *command, const char *mode);
    
     DESCRIPTION
    
        The popen() function executes the command specified by the string command. It creates a pipe between the calling program and the executed command, and returns a pointer to a stream that can be used to either read from or write to the pipe.
    
        If the implementation supports the referenced XCU specification, the environment of the executed command will be as if a child process were created within the popen() call using fork(), and the child invoked the sh utility using the call:
    
    
        execl(shell path, "sh", "-c", command, (char *)0);
    
        where shell path is an unspecified pathname for the sh utility.
    
        The popen() function ensures that any streams from previous popen() calls that remain open in the parent process are closed in the new child process.
    
        The mode argument to popen() is a string that specifies I/O mode:
    
           1. If mode is r, when the child process is started its file descriptor STDOUT_FILENO will be the writable end of the pipe, and the file descriptor fileno(stream) in the calling process, where stream is the stream pointer returned by popen(), will be the readable end of the pipe.
    
           2. If mode is w, when the child process is started its file descriptor STDIN_FILENO will be the readable end of the pipe, and the file descriptor fileno(stream) in the calling process, where stream is the stream pointer returned by popen(), will be the writable end of the pipe.
    
           3. If mode is any other value, the result is undefined.
    
        After popen(), both the parent and the child process will be capable of executing independently before either terminates.
    
        Pipe streams are byte oriented. 
    
     RETURN VALUE
    
        On successful completion, popen() returns a pointer to an open stream that can be used to read or write to the pipe. Otherwise, it returns a null pointer and may set errno to indicate the error. 
    
     ERRORS
    
        The popen() function may fail if:
    
        [EMFILE]
            {FOPEN_MAX} or {STREAM_MAX} streams are currently open in the calling process. 
        [EINVAL]
            The mode argument is invalid. 
    
        The popen() function may also set errno values as described by fork() or pipe().
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  5. #5
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by lehe View Post
    "popen is used to read and write to a unix pipe."
    So is it correct the parent process will wait for the child process to finish?
    Even just sticking to this one simple quote, a little brain usage might suffice to draw a conclusion here: how could popen be used to read and write to a pipe to a "child" process without waiting? Perhaps it stops waiting, then you can use it as a pipe to the child process?

    If you don't want to wait, use fork() and exec() with no pipe.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  6. #6
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    popen() calls wait() to reap the child process when you close the popen descriptor, if that's what you mean. You do not have to reap it yourself.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  7. #7
    Registered User
    Join Date
    Jan 2009
    Posts
    159
    Thank you very much!

    I am not sure if I understand this correctly. Please correct if I am wrong.

    When with mode "w", the child process will run till it requires input from stdin, then it returns to the parent process which runs the code that feeds inputs to the file descriptor returned by popen, and then both parent and child processes continue to run independently.

    When with mode "r", the parent process will wait until the child process finish running, then it returns to the parent process which resumes its own running including reading from the file descriptor returned by popen(). So popen() with mode"r" is almost same as system(). Both makes the parent wait until the child process finish. However child process in system() has no communication with the parent while it does in popen()?

    Thanks and regards!

  8. #8
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by lehe View Post
    I am not sure if I understand this correctly. Please correct if I am wrong.
    I think you've got it. The difference between popen() in "r" mode and system() is that popen() pipes the output to your file descriptor rather than STDOUT, which is useful. system() is mostly for commands that have no input or (significant) output.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  9. #9
    Registered User
    Join Date
    Jan 2009
    Posts
    159
    Normally how could I know when the output of the child process to the file descriptor returned by popen() is finished, so that I can start read from it in the parent process?

  10. #10
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by lehe View Post
    Normally how could I know when the output of the child process to the file descriptor returned by popen() is finished, so that I can start read from it in the parent process?
    You probably don't have to wait, you can start reading right away. Just use a while loop with fread or fgets, the same way you would read from a file.

    I say probably because I have never seen a problem, so I suspect the file handle is not returned to you until the command has responded and there is output -- but you'd have to test that theory with a process that sleeps for say 5 seconds after invoked.
    Code:
    int main() {
          sleep(5);
          printf("hello world");
          return 0;
    }
    Try calling that with popen() and see.

    If you test it and I'm wrong, you'd want to use an infinite loop with a slight delay that keeps checking for input, then reads the first line or byte and breaks out of the loop.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  11. #11
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by lehe View Post
    Normally how could I know when the output of the child process to the file descriptor returned by popen() is finished, so that I can start read from it in the parent process?
    The sequencing between read and write is accomplished by the child process. If the child process requires all of the input data before outputting anything (as would be normal) then the logic of the child process will ensure that that occurs. If you attempt to read from the process before you have finished writing all the data, you would simply block forever.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  12. #12
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by brewbuck View Post
    The sequencing between read and write is accomplished by the child process. If the child process requires all of the input data before outputting anything (as would be normal) then the logic of the child process will ensure that that occurs. If you attempt to read from the process before you have finished writing all the data, you would simply block forever.
    Unfortunately popen() does not have a "rw" mode, so this situation is impossible.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. popen and fgets, underflow!
    By henrikstolpe in forum Linux Programming
    Replies: 0
    Last Post: 02-06-2009, 03:39 AM
  2. popen takes too long?
    By Largo in forum C Programming
    Replies: 2
    Last Post: 11-20-2006, 06:46 AM
  3. popen()
    By Cactus_Hugger in forum Windows Programming
    Replies: 2
    Last Post: 10-22-2005, 03:16 PM
  4. popen vs fopen
    By esme in forum Linux Programming
    Replies: 1
    Last Post: 11-25-2002, 10:37 AM