简体   繁体   中英

Redirecting child process without redirecting parent process

I'm trying to redirect child process's input and output stream, without redirect parent process input and output stream. My idea was to check whether or not there is an input\output in the command line, if so to redirect to it, then fork and wait for child to complete it's process if necessary, and eventually redirect back to stdin and stdout . The problem is that this code somehow doesn't redirect back to stdin and stdout and the parent process stays in the previous streams. Here is my code:

typedef struct cmdLine
{
    char * const arguments[MAX_ARGUMENTS]; /* command line arguments (arg 0 is the command)*/
    int argCount;       /* number of arguments */
    char const *inputRedirect;  /* input redirection path. NULL if no input redirection */
    char const *outputRedirect; /* output redirection path. NULL if no output redirection */
    char blocking;  /* boolean indicating blocking/non-blocking */
    int idx;                /* index of current command in the chain of cmdLines (0 for the first) */
    struct cmdLine *next;   /* next cmdLine in chain */
} cmdLine;

void execute(cmdLine *pCmdLine){
    FILE * input = NULL;
    FILE * output = NULL;
    if(pCmdLine->inputRedirect != NULL){
        close(fileno(stdin));
        input = fopen(pCmdLine->inputRedirect, "r+"); //open for child
    }
    if(pCmdLine->outputRedirect != NULL){
        close(fileno(stdout));
        output = fopen(pCmdLine->outputRedirect, "ab+"); //open for child
    }
    pid = fork();
    if(pCmdLine->blocking == 1) {
        waitpid(pid, NULL, 0);  //wait for chile to finish
        if (input){     //redirect to stdin
            close(input);
            fopen(stdin, "r+");
            fflush(stdin);
        }

        if (output){    //redirect to stdout
            close(output);
            fopen(stdout, "ab+");
            fflush(stdout);
        }
    }
    if(pid == 0){
        execvp(pCmdLine-> arguments[0],pCmdLine->arguments);    //exec child
        perror("execution went wrong!");
        exit(-1);
    }
}

How should I do in correctly and elegant?

Notes: without using dup2 and pipe, or any other libraries rather than those: unistd.h,stdio.h,stdlib.h,string.h,sys/wait.h

Redirecting shall be done by closing and reopening standard input and standard output respectively. And it shall be done in the child process only.

This may be done by doing it in the child branch

pid_t pid = fork();
if (pid == -1) {
    // error handling
    perror("fork");
} else if (pid == 0) {
    // Now we're in the child process
    if (pCmdLine->inputRedirect != NULL) {
        fclose(stdin);
        input = fopen(pCmdLine->inputRedirect, "r+"); // open for child
    }

    if (pCmdLine->outputRedirect != NULL) {
        fclose(stdout);
        output = fopen(pCmdLine->outputRedirect, "ab+"); // open for child
    }

    execvp(pCmdLine->arguments[0], pCmdLine->arguments); // exec child
    perror("execution went wrong!");
    exit(-1);
} else {
    // Now we're in the parent process
    waitpid(pid, NULL, 0);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM