试图重新实现“ |” c

发布于 2025-01-22 13:06:49 字数 2619 浏览 0 评论 0原文

我正在尝试重新实现管道“ |”操作员。

该程序将执行如下:

$ ./exe Infile cmd cmd2 cmd2 cmd3 cmdn Outfile。

首先,我将通过命令从Infile Process Infile的数据中阅读,并最终将其输出以淘汰。

Impartaions

我的伪代码看起来如下:

change infile descriptor to stdin.
loop each command.
      pipe();
      fork();
      if (we're in the child process)
         change stdin to read_end of pipe.
         execute command.
      else if (we're in the parent process)
          change stdout to write_end of pipe.
          execute command.
          wait for child process.
change outfile descriptor to stdout.

代码:

int infile_fd = open(args->infile, O_RDONLY);
    dup2(infile_fd, STDIN_FILENO);
    // how many commands
    while(i < args->len)
    {
       // error handling stuff
       args->cmds[i].cmd = check_exist(args->cmds[i], args);       
    
       if (pipe(args->cmds[i].fd) == -1)
       {
           
           perror("piping failed\n");
           exit(EXIT_FAILURE);
       }
       
       if ((args->cmds[i].pid = fork()) == -1)
        {
            perror("fork failed\n");
            
            exit(EXIT_FAILURE);
        } else {
             // child process
            if (args->cmds[i].pid == 0)
            {
                close(args->cmds[i].fd[WRITE_END]);
                dup2(args->cmds[i].fd[READ_END], STDIN_FILENO);             
                if (execve(args->cmds[i].cmd, args->cmds[i].flags, env) == -1)
                {
                    perror("execve failed\n");
                    exit(EXIT_FAILURE);
                }
                i++; 
            }
            else 
            {
                // parent process
                close(args->cmds[i].fd[READ_END]);
                dup2(args->cmds[i].fd[WRITE_END], STDOUT_FILENO);             
                if (execve(args->cmds[i].cmd, args->cmds[i].flags, env) == -1)
                {
                    perror("execve failed\n");
                    exit(EXIT_FAILURE);
                }
                wait(NULL);
                i++;
                
            }

        }
    }
    int outfile_fd = open(args->outfile, O_WRONLY | O_CREAT | O_TRUNC, 0644);
    // change stdout to outfile
    dup2(outfile_fd, STDOUT_FILENO);

输出:

  • 输出是垃圾,命令从堆栈上读取数据并开始显示ENV变量。

预期输出:

  • 数据首先是从“ Infile”中读取的,然后通过命令,直到“ Outfile”的管道通道结束。

问我做错了什么是愚蠢的,因为我可能做错了,所以一个更好的问题:我该怎么做正确呢?

I'm trying to re-implement The pipe "|" operator.

The program will be executed as follows:

$ ./exe infile cmd cmd2 cmd3 cmdn outfile.

where at first i'm gonna read from infile process infile's data through the commands and finally pipe it to outfile.

IMPLEMENTAIONS:

My pseudo code looks like the following:

change infile descriptor to stdin.
loop each command.
      pipe();
      fork();
      if (we're in the child process)
         change stdin to read_end of pipe.
         execute command.
      else if (we're in the parent process)
          change stdout to write_end of pipe.
          execute command.
          wait for child process.
change outfile descriptor to stdout.

CODE:

int infile_fd = open(args->infile, O_RDONLY);
    dup2(infile_fd, STDIN_FILENO);
    // how many commands
    while(i < args->len)
    {
       // error handling stuff
       args->cmds[i].cmd = check_exist(args->cmds[i], args);       
    
       if (pipe(args->cmds[i].fd) == -1)
       {
           
           perror("piping failed\n");
           exit(EXIT_FAILURE);
       }
       
       if ((args->cmds[i].pid = fork()) == -1)
        {
            perror("fork failed\n");
            
            exit(EXIT_FAILURE);
        } else {
             // child process
            if (args->cmds[i].pid == 0)
            {
                close(args->cmds[i].fd[WRITE_END]);
                dup2(args->cmds[i].fd[READ_END], STDIN_FILENO);             
                if (execve(args->cmds[i].cmd, args->cmds[i].flags, env) == -1)
                {
                    perror("execve failed\n");
                    exit(EXIT_FAILURE);
                }
                i++; 
            }
            else 
            {
                // parent process
                close(args->cmds[i].fd[READ_END]);
                dup2(args->cmds[i].fd[WRITE_END], STDOUT_FILENO);             
                if (execve(args->cmds[i].cmd, args->cmds[i].flags, env) == -1)
                {
                    perror("execve failed\n");
                    exit(EXIT_FAILURE);
                }
                wait(NULL);
                i++;
                
            }

        }
    }
    int outfile_fd = open(args->outfile, O_WRONLY | O_CREAT | O_TRUNC, 0644);
    // change stdout to outfile
    dup2(outfile_fd, STDOUT_FILENO);

OUTPUT:

  • output is garbage, commands read data off the stack and start showing env variables.

EXPECTED OUTPUT:

  • data first being read from "infile" and then passed through commands until the end of the piping channel at "outfile".

It would be silly to ask what am I doing wrong, because I'm probably doing it all wrong, so a better question: How can I do it right?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文