Write a C program that behaves like a 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 ‘list’ as myshell$ list f dirname: It will display filenames in a given directory. myshell$ list n dirname: It will count the number of entries in a given directory. myshell$ list i dirname: It will display filenames and their inode number for the files in a given directory.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <dirent.h>
#include <sys/stat.h>
#include <fcntl.h>
#define MAX_INPUT_SIZE 1024
#define MAX_ARGS 10
void execute_command(char *args[], int count) {
pid_t pid = fork();
if (pid == -1) {
perror("fork failed");
exit(EXIT_FAILURE);
} else if (pid == 0) {
// Child process
execvp(args[0], args);
perror("execvp failed");
exit(EXIT_FAILURE);
} else {
// Parent process
wait(NULL); // Wait for the child to complete
}
}
void list_files(char *dirname, char *option) {
struct dirent *entry;
DIR *dir = opendir(dirname);
if (dir == NULL) {
perror("opendir");
return;
}
while ((entry = readdir(dir)) != NULL) {
if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {
char full_path[MAX_INPUT_SIZE];
sprintf(full_path, "%s/%s", dirname, entry->d_name);
struct stat file_stat;
if (stat(full_path, &file_stat) == 0) {
if (strcmp(option, "f") == 0) {
printf("%s\n", entry->d_name); // Display filenames
} else if (strcmp(option, "n") == 0) {
// Count the number of entries
} else if (strcmp(option, "i") == 0) {
printf("%s (Inode: %ld)\n", entry->d_name, file_stat.st_ino); // Display filenames and inode numbers
}
}
}
}
closedir(dir);
}
int main() {
char input[MAX_INPUT_SIZE];
char *args[MAX_ARGS];
int arg_count;
while (1) {
printf("myshell$ ");
if (fgets(input, sizeof(input), stdin) == NULL) {
break; // Exit the loop on EOF
}
input[strcspn(input, "\n")] = 0; // Remove the newline character
// Tokenize the input
arg_count = 0;
char *token = strtok(input, " ");
while (token != NULL) {
args[arg_count] = token;
arg_count++;
token = strtok(NULL, " ");
}
args[arg_count] = NULL; // Null-terminate the argument list
// Handle the "list" command
if (arg_count >= 3 && strcmp(args[0], "list") == 0) {
list_files(args[2], args[1]);
} else {
execute_command(args, arg_count);
}
}
return 0;
}
Comments
Post a Comment