October 23, 2024
Chicago 12, Melborne City, USA
C#

Multiple pipes implementation for an exact command


I created my own shell and try to execute a command in my shell using multiple pipes. I implemented the shell so that I can run this command

cat a.txt b.txt | egrep 'g' | sort | more > ab.txt

The contents of the a.txt file is

alligator
agile
metro 
plane

The contents of the b.txt file is

spring
age
hot
high
cold

The output of the ab.txt file should be

alligator
agile
spring
age
high

But after running the code I received an empty ab.txt file. I do not understand what is wrong in my code.

The code block is as follows

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "fcntl.h"
#include "sys/stat.h"
#include "sys/wait.h"
#include "unistd.h"


#define MAX_LINE 50 
#define MAX_PIPES 5 

void execute_command(char *args[], int in_fd, int out_fd);

int main(void) {
    char *args[MAX_LINE/2 + 1]; 
    char line[MAX_LINE]; 
    int a = 1; 

    while (a) {
        printf(" ");
       

        if (fgets(line, MAX_LINE, stdin) == NULL) {
            break; /* End of file (Ctrl+D) */
        }

        line[strcspn(line, "\n")] = 0;

        /* Parse the line into separate commands for pipes */
        char *commands[MAX_PIPES + 1];
        int num_cmds = 0;
        char *cmd = strtok(line, "|");
        while (cmd != NULL && num_cmds < MAX_PIPES) {
            commands[num_cmds++] = cmd;
            cmd = strtok(NULL, "|");
        }
        commands[num_cmds] = NULL;

        if (num_cmds == 0) {
            continue;
        }

        if (strcmp(commands[0], "exit") == 0) {
            should_run = 0;
            continue;
        } else if (strncmp(commands[0], "cd ", 3) == 0) {
            char *dir = commands[0] + 3;
            if (chdir(dir) != 0) {
                perror("chdir");
            }
            continue;
        }

        /* Create pipes for the commands */
        int pipe_fds[MAX_PIPES][2];
        for (int i = 0; i < num_cmds - 1; i++) {
            if (pipe(pipe_fds[i]) == -1) {
                perror("pipe");
                exit(1);
            }
        }

        /* Execute each command in the pipeline */
        for (int i = 0; i < num_cmds; i++) {
            /* Parse the command into arguments */
           
            }
            args[argc] = NULL;

            pid_t pid = fork();
            if (pid == 0) { 
                
                if (i > 0) {
                    dup2(pipe_fds[i - 1][0], STDIN_FILENO);
                }

                if (i < num_cmds - 1) {
                    dup2(pipe_fds[i][1], STDOUT_FILENO);
                }

                /* Close all pipes */
                //closing pipe logic
                }

                if (i == num_cmds - 1) {
                    for (int j = 0; args[j] != NULL; j++) {
                        if (strcmp(args[j], ">") == 0) {
                            args[j] = NULL;
                            int fd = open(args[j + 1], O_WRONLY | O_CREAT | O_TRUNC, 0644);
                            if (fd == -1) {
                                perror("open");
                                exit(1);
                            }
                            dup2(fd, STDOUT_FILENO);
                            close(fd);
                            break;
                        }
                    }
                }

                /* Execute the command */
                execvp(args[0], args);
                perror("execvp");
                exit(1);
            } else if (pid < 0) { /* Fork failed */
                perror("fork");
                exit(1);
            }
        }

       //close pipe logic
        }

        for (int i = 0; i < num_cmds; i++) {
            wait(NULL);
        }
    }

    return 0;
}

I am using the operating system Ubuntu 20.04. Any help would be appreciated.



You need to sign in to view this answers

Leave feedback about this

  • Quality
  • Price
  • Service

PROS

+
Add Field

CONS

+
Add Field
Choose Image
Choose Video