I need to create a function that, among other things, spawns a child process.
I'd like to pass to this function an optional list of file discriptors so that, depending on the user needs, the child process input/output can be redirected.

I have seen dozens of people talking about how to do this using `dup2` somewhat like this:

```
if( pid < 0 )   // error forking.
{
//...
}
else if( pid != 0 ) // Parent process.
{
    ret = waitpid( pid, &status, 0 );
    return  WEXITSTATUS( status );
}
else    // Child process.
{
    dup2( fd, STDIN_FILENO );   // Clone passed file discriptor.
    close( fd );            // Close the passed one, since we have already cloned.
    execvp( arglist[ 0 ], arglist );
}

```

Alright. All of this is in the Internet.
My question now is, how (or what is the best way) to redirect to `/dev/null`?

Should I force the user to `open( /dev/null)` and pass it as `fd` or is there any better way?

---

EDIT:

This is not as pretty as I wanted, but I could not find any better way, so I ended up passing an array of file names to wherever a user could want to redirect, respectively, STDIN, STDOUT and STDERR:

```
static int  do_exec( arglist_t arglist, const char *fio[ 3 ] )
{
DEBUG__( OSU_DEBUG_LEVEL_1, "fio = %p\n", fio );

    if ( fio )
    {
        if ( fio[ STDIN_FILENO ] )
        {
            int fd = open( fio[ STDIN_FILENO ], O_RDONLY );

            if ( -1 < fd )
            {
                dup2( fd, STDIN_FILENO );
                close( fd );
            }
        }

        if ( fio[ STDOUT_FILENO ] )
        {
            int fd = open( fio[ STDOUT_FILENO ], O_WRONLY | O_CREAT | O_APPEND );

            if ( -1 < fd )
            {
                dup2( fd, STDOUT_FILENO );
                close( fd );
            }
        }

        if ( fio[ STDERR_FILENO ] )
        {
            int fd = open( fio[ STDERR_FILENO ], O_WRONLY | O_CREAT | O_APPEND );

            if ( -1 < fd )
            {
                dup2( fd, STDERR_FILENO );
                close( fd );
            }
        }
    }

    return  execvp( arglist[ 0 ], arglist );
}

```

* I haven't yet fully tested it, so it may have some bugs.

Really thanks to @Zack and @gbulmer.