我自己的shell程序中的后台进程忽略标准输入

问题描述 投票:0回答:1

我正在用C语言开发自己的小Shell程序。当将子进程作为后台进程运行时,我想忽略来自父进程的用户输入。我当前正在尝试通过管道将其关闭,然后为孩子关闭stdin,但输入仍将输入给孩子。

    else // A process
    {
        pid_t child_pid;
        char lastArgument = args[currArgsIndex-1][0];
        if (lastArgument != '&'){ //Normal process
            if((child_pid = fork()) == 0) {
                execvp(filepath, args);
                exit(0);
            }
            else
            {
                while(wait(NULL) != child_pid);
            }
        }
        else { // Background
            args[currArgsIndex-1] = NULL; 
            int process_pipe[2];
            pipe(process_pipe); // Piping
            if((child_pid = fork()) == 0) {
                close(process_pipe[0]); // Ignore stdin for child
                execvp(filepath, args);
                exit(0);
            }
        }
    }
shell fork c99
1个回答
0
投票

您创建了一个管道并关闭了读取端,但是您从未说过管道应该是标准输入。

听起来您的意图是改为1.仅在子级中打开管道,2.关闭write端,3.将read端设置为stdin:

    else { // Background
        args[currArgsIndex-1] = NULL; 
        if((child_pid = fork()) == 0) {
            int process_pipe[2];
            pipe(process_pipe); // Piping
            dup2(process_pipe[0], 0); // Copy read end as stdin
            close(process_pipe[0]);   // Close FD that is now unused
            close(process_pipe[1]);   // Close write end so no data can be read
            execvp(filepath, args);
            perror("execvp failed");
            exit(1); // exit with error 
        }
    }

虽然没有管道是没有意义的。您可以更轻松地打开/dev/null进行读取并将其设置为标准输入。或者,只需完全关闭stdin(一些程序会抱怨):

    else { // Background
        args[currArgsIndex-1] = NULL; 
        if((child_pid = fork()) == 0) {
            close(0); // Close stdin
            execvp(filepath, args);
            /* error handling */
    }
© www.soinside.com 2019 - 2024. All rights reserved.