Lab13

Run Settings
LanguageC
Language Version
Run Command
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/wait.h> #include <string.h> #define UNUSED(x) (void)(x) void execute_pipeline( char *commands[], char **commands_args[], int number_commands ) { int pipe_fd[number_commands - 1][2]; // Create pipes in a for loop for (int i = 0; i < number_commands - 1; i++) { if (pipe(pipe_fd[i]) == -1) { perror("pipe"); exit(EXIT_FAILURE); } } // Parent forks children in a for loop for (int i = 0; i < number_commands; i++) { pid_t pid = fork(); int status; if (pid == 0) // Child process { // If not the first command, redirect stdin to read end of previous pipe if (i > 0) { if (dup2(pipe_fd[i-1][0], STDIN_FILENO) == -1) { perror("dup2"); exit(EXIT_FAILURE); } } // If not the last command, redirect stdout to write end of pipe if (i < number_commands - 1) { if (dup2(pipe_fd[i][1], STDOUT_FILENO) == -1) { perror("dup2"); exit(EXIT_FAILURE); } } // Close all pipe ends for (int j = 0; j < number_commands - 1; j++) { close(pipe_fd[j][0]); close(pipe_fd[j][1]); } // Execute the command with arguments execvp(commands[i], commands_args[i]); perror("execvp"); exit(EXIT_FAILURE); } else if (pid < 0) { // error in fork perror("fork"); exit(EXIT_FAILURE); } else { // parent process if (i > 0) { close(pipe_fd[i-1][0]); // close read end of previous pipe close(pipe_fd[i-1][1]); // close write end of previous pipe } if (i == number_commands - 1) { // last command, wait for all children to finish for (int j = 0; j < number_commands; j++) { wait(&status); } } } } // Close all pipe ends for (int i = 0; i < number_commands - 1; i++) { close(pipe_fd[i][0]); close(pipe_fd[i][1]); } } int main() { // List of available commands on a command line // You can add to it if you like char *commands[] = { "ls", "grep", "sort", "uniq", "head", "tail", "wc", "ps", "who", "find", "xargs", "awk", "cut", NULL}; // Select commands from commands[] char *pipeline_commands[] = {commands[0], commands[1]}; // Set arguments char *cmd1_args[] = {commands[0], NULL}; char *cmd2_args[] = {commands[1], "c", NULL}; // Pack arguments into an array char **pipeline_args[] = {cmd1_args, cmd2_args}; int number_commands = sizeof(pipeline_commands) / sizeof(pipeline_commands[0]); printf("Executing the following pipeline:\n"); for (int i = 0; i < number_commands; i++) { printf("%s", pipeline_commands[i]); for (int j = 1; pipeline_args[i][j]!= NULL; j++) { printf(" %s", pipeline_args[i][j]); } if (i != number_commands - 1) { printf(" | "); } } printf("\n"); execute_pipeline( pipeline_commands, pipeline_args, number_commands ); return 0; }
Editor Settings
Theme
Key bindings
Full width
Lines