代码之家  ›  专栏  ›  技术社区  ›  Evan Teran

为什么在这里使用进程替换会导致挂起?

  •  2
  • Evan Teran  · 技术社区  · 6 年前

    我有一个程序需要启动其他程序,可能用文件和管道替换它们的stdio。虽然子进程确实从源管道获得了I/O,但它似乎“起作用”,不幸的是,它也会导致挂起。子进程似乎永远不会得到 EOF .

    这里是代码的最小复制,为什么在打印后会挂起 "Hello World\n" ?

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/wait.h>
    #include <unistd.h>
    
    int main(int argc, char *argv[]) {
    
        switch (pid_t pid = fork()) {
        case 0: {
            // in child
    
            // replace the child's stdin with whatever filename is given as argv[1]
            freopen(argv[1], "r+b", stdin);
    
            // construct an argv array for to exec, no need for anything except 
            // argv[0] since we want it to use stdin
            char path[]  = "/bin/cat";
            char *args[] = {path, NULL};
    
            // run it!
            execv(args[0], args);
            abort(); // we should never get here!
        }
        case -1:
            // error
            return -1;
        default: {
            // in parent, just wait for the sub-process to terminate
            int status;
            const auto r = waitpid(pid, &status, __WALL);
    
            if (r == -1) {
                perror("waitpid");
                return -1;
            }
            break;
        }
        }
    }
    
    # runs printf creating a pipe, which is then passed as the argv of my test program
    ./test >(printf "Hello\n")
    
    1 回复  |  直到 6 年前
        1
  •  1
  •   John Kugelman Michael Hodel    6 年前
    ./test <(printf "Hello\n")
    

    切换到 >(...) <(...) 阅读 printf 而不是写信给它。

    freopen(argv[1], "rb", stdin);
    

    r+ . 你只是在读文件,所以你要做 r .