| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Name | Name | Last commit date | ||
|---|---|---|---|---|
This project is a simple shell implementation written in C, designed to provide basic shell functionality such as parsing commands, searching for executables in the system's PATH, handling built-in commands (cd, exit), and executing external programs. The shell provides a controlled environment for process management and command execution.
The Shell Implementation in C provides fundamental features for executing user commands. It includes:
make./mainTo ensure there are no memory leaks:
make valgrind./maincd /home/userpwdls -lexitThe parse function takes a user input string, tokenizes it into arguments, and constructs a command structure:
command* parse(char* line) {
// Clone input to avoid modifying original
char* line_copy = new char[strlen(line) + 1];
strcpy(line_copy, line);
// Tokenize input and count arguments
int argc = 0;
char* currentToken = strtok(line_copy, " \t\n");
while (currentToken != NULL) {
argc++;
currentToken = strtok(NULL, " \t\n");
}
// Create command structure
command* cmd = create_command(argc);
if (!cmd) return NULL;
// Populate arguments
strcpy(line_copy, line); // Reset line_copy
currentToken = strtok(line_copy, " \t\n");
for (int i = 0; i < argc && currentToken != NULL; i++) {
strncpy(cmd->argv[i], currentToken, MAX_ARG_LEN - 1);
cmd->argv[i][MAX_ARG_LEN - 1] = '\0';
currentToken = strtok(NULL, " \t\n");
}
delete[] line_copy;
return cmd;
}Support for built-in commands cd and exit is implemented in the do_builtin function:
int do_builtin(command* cmd) {
if (strcmp(cmd->argv[0], "exit") == 0) {
exit(SUCCESS);
}
if (cmd->argc == 1) {
return chdir(getenv("HOME")); // cd with no arguments
} else if (cmd->argc == 2) {
return chdir(cmd->argv[1]); // cd with one argument
} else {
fprintf(stderr, "cd: Too many arguments\n");
return ERROR;
}
}The shell uses execv to execute external commands, following a search in the PATH environment variable:
bool find_full_path(command* cmd) {
char* path_env = getenv("PATH");
if (!path_env) return false;
char* path_copy = new char[strlen(path_env) + 1];
strcpy(path_copy, path_env);
char* currentToken = strtok(path_copy, ":");
while (currentToken != NULL) {
char full_path[MAX_LINE_SIZE];
snprintf(full_path, sizeof(full_path), "%s/%s", currentToken, cmd->argv[0]);
struct stat buffer;
if (stat(full_path, &buffer) == 0 && S_ISREG(buffer.st_mode)) {
delete[] cmd->argv[0];
cmd->argv[0] = new char[strlen(full_path) + 1];
strcpy(cmd->argv[0], full_path);
delete[] path_copy;
return true;
}
currentToken = strtok(NULL, ":");
}
delete[] path_copy;
return false;
}Memory is managed using new and delete throughout the project, ensuring no leaks.
Unit tests are provided in the tests.cpp file to verify the shell's functionality. The tests cover parsing, built-in commands, external command execution, and memory management. To run the tests, compile the project with the tests target:
make testsTests are provided using the Google Test framework. You might need to install the Google Test library to run the tests.
This shell was built as part of a project to understand and implement fundamental system programming concepts in C. It incorporates concepts like dynamic memory allocation, process creation, and system calls, inspired by Unix-based shell functionality.
Son Nguyen
GitHub: hoangsonww
Created with ❤️ by Son Nguyen in 2024.
| Back | FazBrowse Home | New Git URL |