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?