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>
// Max command size and token count
#define MAX_CMD_LEN 1024
#define MAX_TOKENS 64
// Function to handle the 'list' built-in command
void handle_list(char **args) {
if (args[1] == NULL || args[2] == NULL) {
printf("Usage: list [f|n|i] dirname\n");
return;
}
DIR *dir = opendir(args[2]);
if (!dir) {
fprintf(stderr, "Error: Could not open directory '%s'\n", args[2]);
perror("Reason");
return;
}
struct dirent *entry;
int count = 0;
int found = 0;
if (strcmp(args[1], "f") == 0) {
while ((entry = readdir(dir)) != NULL) {
if (entry->d_name[0] != '.') {
printf("%s\n", entry->d_name);
found = 1;
}
}
if (!found) printf("No visible entries found.\n");
} else if (strcmp(args[1], "n") == 0) {
while ((entry = readdir(dir)) != NULL) {
if (entry->d_name[0] != '.') {
count++;
}
}
printf("Number of entries: %d\n", count);
} else if (strcmp(args[1], "i") == 0) {
while ((entry = readdir(dir)) != NULL) {
if (entry->d_name[0] != '.') {
printf("%s\tInode: %lu\n", entry->d_name, entry->d_ino);
found = 1;
}
}
if (!found) printf("No visible entries found.\n");
} else {
printf("Invalid option for 'list'. Use: f, n, or i\n");
}
closedir(dir);
}
// Tokenize the input line into arguments
void parse_input(char *input, char **args) {
int i = 0;
char *token = strtok(input, " \t\r\n");
while (token != NULL && i < MAX_TOKENS - 1) {
args[i++] = token;
token = strtok(NULL, " \t\r\n");
}
args[i] = NULL;
}
int main() {
char input[MAX_CMD_LEN];
char *args[MAX_TOKENS];
while (1) {
printf("myshell$ ");
fflush(stdout);
if (fgets(input, sizeof(input), stdin) == NULL) {
printf("\n");
break; // Exit on Ctrl+D
}
// Remove newline at end
input[strcspn(input, "\n")] = '\0';
// Skip empty input
if (strlen(input) == 0)
continue;
// Parse the input
parse_input(input, args);
// Handle built-in 'exit'
if (strcmp(args[0], "exit") == 0) {
break;
}
// Handle built-in 'list'
if (strcmp(args[0], "list") == 0) {
handle_list(args);
continue;
}
// Otherwise, fork and exec external command
pid_t pid = fork();
if (pid < 0) {
perror("Fork failed");
continue;
}
if (pid == 0) {
// Child process
if (execvp(args[0], args) == -1) {
perror("Execution failed");
}
exit(EXIT_FAILURE);
} else {
// Parent process waits for child
wait(NULL);
}
}
return 0;
}
myshell$ list f .
myshell$ list n /bin
myshell$ list i /etc
set c
(1)
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 ‘typeline’ as
myshell$ typeline n filename: It will display first n lines of the file.
myshell$ typeline -n filename: It will display last n lines of the file.
myshell$ typeline a filename: It will display all the lines of the file.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
#include <ctype.h>
#define MAX_CMD_LEN 1024
#define MAX_ARGS 64
void typeline(char **args) {
if (args[1] == NULL || args[2] == NULL) {
printf("Usage: typeline [n|-n|a] filename\n");
return;
}
char *filename = args[2];
FILE *fp = fopen(filename, "r");
if (!fp) {
perror("Error opening file");
return;
}
if (strcmp(args[1], "a") == 0) {
char line[1024];
while (fgets(line, sizeof(line), fp)) {
printf("%s", line);
}
} else if (args[1][0] == '-' && isdigit(args[1][1])) {
int n = atoi(args[1] + 1);
// Count total lines
int total = 0;
char line[1024];
while (fgets(line, sizeof(line), fp)) total++;
rewind(fp);
int skip = total - n;
int current = 0;
while (fgets(line, sizeof(line), fp)) {
if (current++ >= skip) {
printf("%s", line);
}
}
} else if (isdigit(args[1][0])) {
int n = atoi(args[1]);
char line[1024];
int count = 0;
while (fgets(line, sizeof(line), fp) && count++ < n) {
printf("%s", line);
}
} else {
printf("Invalid typeline option. Use: n, -n, or a\n");
}
fclose(fp);
}
void parse_input(char *input, char **args) {
int i = 0;
char *token = strtok(input, " \t\r\n");
while (token != NULL && i < MAX_ARGS - 1) {
args[i++] = token;
token = strtok(NULL, " \t\r\n");
}
args[i] = NULL;
}
int main() {
char input[MAX_CMD_LEN];
char *args[MAX_ARGS];
while (1) {
printf("myshell$ ");
fflush(stdout);
if (!fgets(input, sizeof(input), stdin)) {
printf("\n");
break;
}
parse_input(input, args);
if (args[0] == NULL)
continue;
if (strcmp(args[0], "exit") == 0)
break;
if (strcmp(args[0], "typeline") == 0) {
typeline(args);
continue;
}
// External command
pid_t pid = fork();
if (pid == 0) {
execvp(args[0], args);
perror("exec failed");
exit(1);
} else {
wait(NULL);
}
}
return 0;
}
myshell$ typeline 5 file.txt # first 5 lines
myshell$ typeline -3 file.txt # last 3 lines
myshell$ typeline a file.txt # all lines
(2)
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 ‘search’ as
myshell$ search f filename pattern : It will search the first occurrence of pattern
in the given
file
myshell$ search a filename pattern : It will search all the occurrence of pattern
in the given file
myshell$ search c filename pattern : It will count the number of occurrence of
pattern in the
given file
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
#define MAX_CMD_LEN 1024
#define MAX_ARGS 64
void search(char **args) {
if (args[1] == NULL || args[2] == NULL || args[3] == NULL) {
printf("Usage: search [f|a|c] filename pattern\n");
return;
}
FILE *fp = fopen(args[2], "r");
if (!fp) {
perror("Error opening file");
return;
}
char *mode = args[1];
char *pattern = args[3];
char line[1024];
int count = 0;
int found = 0;
while (fgets(line, sizeof(line), fp)) {
if (strstr(line, pattern)) {
if (strcmp(mode, "f") == 0) {
printf("First match: %s", line);
found = 1;
break;
} else if (strcmp(mode, "a") == 0) {
printf("%s", line);
found = 1;
} else if (strcmp(mode, "c") == 0) {
count++;
}
}
}
if (strcmp(mode, "c") == 0) {
printf("Total occurrences: %d\n", count);
} else if (!found && (strcmp(mode, "f") == 0 || strcmp(mode, "a") == 0)) {
printf("Pattern not found.\n");
}
fclose(fp);
}
void parse_input(char *input, char **args) {
int i = 0;
char *token = strtok(input, " \t\r\n");
while (token != NULL && i < MAX_ARGS - 1) {
args[i++] = token;
token = strtok(NULL, " \t\r\n");
}
args[i] = NULL;
}
int main() {
char input[MAX_CMD_LEN];
char *args[MAX_ARGS];
while (1) {
printf("myshell$ ");
fflush(stdout);
if (!fgets(input, sizeof(input), stdin)) {
printf("\n");
break;
}
parse_input(input, args);
if (args[0] == NULL)
continue;
if (strcmp(args[0], "exit") == 0)
break;
if (strcmp(args[0], "search") == 0) {
search(args);
continue;
}
// External command
pid_t pid = fork();
if (pid == 0) {
execvp(args[0], args);
perror("exec failed");
exit(1);
} else {
wait(NULL);
}
}
return 0;
}
myshell$ search f file.txt hello # first occurrence
myshell$ search a file.txt hello # all occurrences
myshell$ search c file.txt hello # count occurrences