【问题标题】:Redirecting child process without redirecting parent process重定向子进程而不重定向父进程
【发布时间】:2020-09-01 03:08:15
【问题描述】:

我正在尝试重定向子进程的输入和输出流,没有重定向父进程的输入和输出流。 我的想法是检查命令行中是否有输入\输出,如果有则重定向到它,然后分叉并等待孩子在必要时完成它的过程,并最终重定向回stdin和@987654322 @。问题是这段代码不会以某种方式重定向回stdinstdout,并且父进程保留在先前的流中。 这是我的代码:

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);
    }
}

我应该如何正确优雅地做?

注意:不使用 dup2 和 pipe,或任何其他库,而不是那些:unistd.h,stdio.h,stdlib.h,string.h,sys/wait.h

【问题讨论】:

  • 不需要管道,但为什么不使用dupdup2
  • 这是我们的要求,指令是通过关闭标准输入流或标准输出流,并打开一个新文件,然后自动分配最低可用文件描述符索引。这有效地覆盖了stdinstdout

标签: c redirect process execvp


【解决方案1】:

重定向应通过分别关闭和重新打开标准输入和标准输出来完成。 并且只能在子进程中完成。

这可以通过在子分支中完成

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);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-04
    • 2021-03-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多