How do you use dup2 and fork together?

I take the operating system course, and it’s hard for me how input is redirected using dup2 when you have the plugs. I wrote this small program to try to understand it, but I could not pass the child a grandiose child. I am trying to mimic a unix command: ps -A | wc-1. I am new to Unix, but I believe that this should count the lines of the list of running processes. Therefore, my conclusion should be a single number.

#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <iostream>

using namespace std;

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

    char *searchArg = argv[ 1 ];
    pid_t pid;

    if ( ( pid = fork() ) > 0 ) {
        wait( NULL );
        cout << "Inside parent" << endl;
    } 
    else if ( pid == 0 ) {
            int fd1[ 2 ];
            pipe( fd1 );
            cout << "Inside child" << endl;

            if ( pid = fork() > 0 ) {
                dup2( fd1[ 0 ], 0 );
                close( fd1[ 0 ] );
                execlp( "/bin/wc", "-l", NULL );
            }
            else if ( pid == 0 ) {
                cout << "Inside grand child" << endl;
                execlp( "/bin/ps", "-A", NULL );
            }
        }
    return 0;
}

I don't have it in the code above, but here is my guess about how things should go:

  • We need to redirect the standard output of the ps -A command (which usually prints on the screen, right?) So that the wc -l command can use it to count lines.
  • dup2, dup2 (?, 1), ?. ?.

: ? , , , wc ?

  • wc - .

: wc ? execlp? ?

  • wc -l.

wc ps? , , ps wc... , , grand-child.

pipe dream

+5
1

, , , ; :

else if ( pid == 0 ) {
        int fd1[ 2 ];
        pipe( fd1 );
        cout << "Inside child" << endl;

        if ( pid = fork() > 0 ) {
            if (dup2( fd1[ 0 ] , 0 ) < 0) {
              cerr << "Err dup2 in child" << endl;
            }
            close( fd1[ 0 ] );
            close( fd1[ 1 ] ); // important; see below
            // Note: /usr/bin, not /bin
            execlp( "/usr/bin/wc", "wc", "-l", NULL );
            cerr << "Err execing in child" << endl;
        }
        else if ( pid == 0 ) {
            cout << "Inside grand child" << endl;
            if (dup2( fd1[ 1 ] , 1 ) < 0) {
              cerr << "Err dup2 in gchild" << endl;
            }
            close( fd1[ 0 ] );
            close( fd1[ 1 ] );
            execlp( "/bin/ps", "ps", "-A", NULL );
            cerr << "Err execing in grandchild" << endl;
        }
}

:

  • : ? , , , wc ?

    Unix 0, 1 2 , , . wc , dup ed 0.

  • : wc ? execlp? ?

    , , exec, , exec. ( CLOSE_ON_EXEC, ). , dup2 - 0, wc .

  • wc ps?

    , , , . , . close - , "", - .

    : , grand-child , . dup wc . wc , , , . , grand-child, , , ps -A , 1, ps -A , , . , fd[0], wc -, 0. , wc , .

    , , close, , "", , wc ps , , , , . dup2 , close, .

EDIT: execlp.

+4

All Articles