c - 管道实现停留在 dup2 命令

标签 c shell pipe

我想制作一个简单的 shell,但我无法实现管道。这是我的代码中与管道有关的部分。如果您认为它会有所帮助,我可以提供更多信息,但其余部分完全按预期工作。

    args[i] = NULL;
    p_flag = 1;
    int stop = i;
    // we have to fork again so we can write to a buffer file.
    // First we creat the pipe.
    if (pipe(p_file) == -1) {
      //check if the pipe failed
      fprintf(stderr, "There was an error creating the pipe\n");
    }
    switch (pid = fork()) {
    case 0:
      //Open up the input end of the pipe for writing.
      printf("test1\n");
      close(p_file[0]);
      printf("test2\n");
      dup2(p_file[1], 1);
      printf("test3\n");
      execvp(args[0], args);
      fprintf(stderr, "ERROR %s no such program.\n", line);
      exit(1);
      break;
    case -1:
      fprintf(stderr, "ERROR can't create child process!\n");
      break;
    default:
      wait();
      break;
    }
    /*
      at this point only the first child should still be running
      and since we waited we know that the buffer file has our input.
      Now we have to redirect our input to read from the buffer and
      run the rest of the commands normally. first the args array has
      to be cleaned up we want the commands past the pipe symbol to be
      in front.
    */
    int j = 0;
    stop++;
    while (args[stop] != NULL) {
      args[j] = args[stop];
      j++;
      stop++;
    }
    args[j] = NULL;
    close(p_file[1]);
    dup2(p_file[0], 0);

如您所见,我已经输入了一些打印语句来尝试找出卡住的确切位置,并且我之前得到了 test1test2 输出该程序一直在处理,永远旋转着它的轮子。我必须按 ctrl+c 才能恢复提示。我不知道为什么它在执行 dup2 命令时卡住了。此代码片段中唯一重要的事情是 p_file 的初始化,它是一个大小为 2 的数组(即 int p_file[2];)。

最佳答案

你有一个严重的误解。管道是一种进程间通信机制。通过管道通信的进程通常同时运行,而不是顺序运行。它们必须在通用实现中同时运行,例如由 shell 提供的实现,因为每个管道只有一个有限的缓冲区,并且当缓冲区填满时写入它会阻塞或失败。除非您可以确定写入器在退出之前不会填充管道的缓冲区,否则读取器必须准备好并等待在您可以期待写入器之前从管道的读取端使用数据完成。

因此,在开始第二个进程之前为第一个进程 wait() 是错误的,这可能就是您的程序挂起的原因。相反,shell 必须为管道的每一端启动一个子进程,然后等待两者。

此外,正如我在评论中所写,您调用 wait() 时没有正确的参数。这会产生未定义的行为,它本身可能是无限期等待,但也可能是几乎任何其他行为。

至于你的调试输出,@Ctx 在他自己的评论中解释了为什么你没有看到你期望的一切。但是,我看不出有任何理由怀疑您关于程序挂起直到您中断它的说法。

关于c - 管道实现停留在 dup2 命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35584730/

相关文章:

c - linux 编程,标准输出到管道在 execve 之前不起作用

c - 服务器编程错误

Python:在特定目录中运行shell命令

shell - GUNZIP/解压文件 "portion by portion"

shell - 获取路径或卷标识符的设备名称

C - 将输入从一个程序传送到另一个程序

c# - 检查 NamedPipeServerStream 是否在客户端启动的方法

c - linux 是否允许从信号处理程序进行任何系统调用?

c - 大型字符缓冲区是否可以在 C 中使用

c++ - CreateFile 异常安全吗?