Write a C program to implement the shell which displays the command prompt “myshell$”. It accepts the command, tokenize the command line and execute it by creating the child process. Also implement the additional command ‘typeline’ as
typeline +n   filename :- To print first n lines in the file.
typeline -a         filename:- To print all lines in the file.


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>

#define MAX_INPUT_SIZE 1024
#define MAX_ARG_SIZE 100

// Function to execute a command
void executeCommand(char *cmd) {
    char *args[MAX_ARG_SIZE];
    char *token = strtok(cmd, " \t\n");
    int i = 0;

    while (token != NULL) {
        args[i++] = token;
        token = strtok(NULL, " \t\n");
    }
    args[i] = NULL; // Null-terminate the argument list

    if (strcmp(args[0], "typeline") == 0) {
        if (i < 3) {
            printf("Usage: typeline +n filename | typeline -a filename\n");
            return;
        }
        if (strcmp(args[1], "+n") == 0) {
            int n = atoi(args[2]);
            if (n <= 0) {
                printf("Invalid number of lines: %d\n", n);
                return;
            }
            FILE *file = fopen(args[3], "r");
            if (file == NULL) {
                perror("Error opening file");
                return;
            }
            char line[MAX_INPUT_SIZE];
            for (int count = 0; count < n && fgets(line, sizeof(line), file) != NULL; count++) {
                printf("%s", line);
            }
            fclose(file);
        } else if (strcmp(args[1], "-a") == 0) {
            FILE *file = fopen(args[2], "r");
            if (file == NULL) {
                perror("Error opening file");
                return;
            }
            char line[MAX_INPUT_SIZE];
            while (fgets(line, sizeof(line), file) != NULL) {
                printf("%s", line);
            }
            fclose(file);
        } else {
            printf("Usage: typeline +n filename | typeline -a filename\n");
        }
    } else {
        pid_t pid = fork();
        if (pid == 0) {
            // Child process
            execvp(args[0], args);
            perror("execvp failed");
            exit(1);
        } else if (pid > 0) {
            // Parent process
            wait(NULL);
        } else {
            perror("fork failed");
        }
    }
}

int main() {
    char input[MAX_INPUT_SIZE];

    while (1) {
        printf("myshell$ ");
        if (fgets(input, sizeof(input), stdin) == NULL) {
            break; // Exit on EOF
        }
        // Remove the trailing newline character from the input
        input[strcspn(input, "\n")] = 0;

        if (strcmp(input, "exit") == 0) {
            break; // Exit the shell
        }

        executeCommand(input);
    }

    return 0;
}