90s

Minimalist, customizable shell written in C99 with syntax highlighting
git clone https://codeberg.org/night0721/90s
Log | Files | Refs | README | LICENSE

commit 4e94a2a055d5a8d4c6abe648010310963d3694e4
parent 6e8a21ed66304aee7c5f88aa9b4fa89a9b7a11f6
Author: night0721 <[email protected]>
Date:   Fri,  2 Feb 2024 16:52:21 +0000

export and source command

Diffstat:
MREADME.md | 11++++++++++-
Mcommands.c | 63+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
Mrush.c | 9+++++----
Arush.h | 6++++++
4 files changed, 82 insertions(+), 7 deletions(-)

diff --git a/README.md b/README.md @@ -20,13 +20,22 @@ $ ./rush - Syntax highlighting on valid commands using ANSI colors - History navigation using up and down keys with history command - Built in commands +- Export environment variable +- Source commands from a file + +# Built in commands +- cd +- help +- exit +- history +- export +- source # Todo Features - Pipe - stdin, stdout, stderr redirect - background jobs - editing using left and right arrow keys -- export command to setenv - tab completion # Credits diff --git a/commands.c b/commands.c @@ -7,27 +7,35 @@ #include <sys/wait.h> #include "commands.h" +#include "constants.h" #include "history.h" +#include "rush.h" // Function declarations for builtin commands int cd(char **args); int help(char **args); int quit(char **args); int history(char **args); +int export(char **args); +int source(char **args); // List of builtin commands' names char *builtin_cmds[] = { "cd", "help", "exit", - "history" + "history", + "export", + "source" }; int (*builtin_func[]) (char **) = { &cd, &help, &quit, // cant name it exit as it is taken - &history + &history, + &export, + &source }; // number of built in commands @@ -80,6 +88,57 @@ int history(char **args) { return 1; } +int export(char **args) { + args++; // skip the command + while (*args != NULL) { + char *variable = strtok(*args, "=\n"); + char *value = strtok(NULL, "=\n"); + if (variable != NULL && value != NULL) { + if (setenv(variable, value, 1) != 0) { + fprintf(stderr, "rush: Error setting environment variable\n"); + return 0; + } + } else { + printf("rush: [arg0: %s] [arg1: %s]", args[0], args[1]); + printf("rush: [Variable: %s] [Value: %s]\n", variable, value); + fprintf(stderr, "rush: Syntax error when setting environment variable\nUse \"export VARIABLE=VALUE\"\n"); + return 0; + } + args++; + } + return 1; +} + +int source(char **args) { + if (args[1] == NULL) { + fprintf(stderr, "rush: not enough arguments\n"); + return -1; + } + + FILE *file = fopen(args[1], "r"); + + if (file == NULL) { + fprintf(stderr, "rush: no such file or directory '%s'\n", args[1]); + return -1; + } + + char line[RL_BUFSIZE]; + int status; + while (fgets(line, sizeof(line), file) != NULL) { + // Remove newline character if present + size_t len = strlen(line); + if (len > 0 && line[len - 1] == '\n') { + line[len - 1] = '\0'; + } + + char **args = argsplit(line); + status = execute(args); + } + + fclose(file); + return status; // Indicate success +} + bool is_builtin(char *command) { for (int i = 0; i < num_builtins(); i++) { if (strcmp(command, builtin_cmds[i]) == 0) { diff --git a/rush.c b/rush.c @@ -92,17 +92,18 @@ char *readline(char **paths) { while (1) { c = getchar(); // read a character int buf_len = strlen(buffer); - //printf("buflen %i\n", buf_len); if (buf_len > 0) { printf("\033[%ldD", strlen(buffer)); // move cursor to the beginning printf("\033[K"); // clear line to the right of cursor } // check each character user has input - // printf("%i\n", c); switch (c) { case EOF: exit(EXIT_SUCCESS); case 10: // enter/new line feed + if (buf_len == 0) { + break; + } buffer[buf_len] = '\0'; // clear all characters after the command for (int start = buf_len + 1; buffer[start] != '\0'; start++) { @@ -124,14 +125,14 @@ char *readline(char **paths) { char *last_command = read_command(1); if (last_command != NULL) { strcpy(buffer, last_command); - buf_len = strlen(buffer); + buf_len = strlen(buffer) - 1; } break; } else if (arrow_key == 66) { // down char *last_command = read_command(0); if (last_command != NULL) { strcpy(buffer, last_command); - buf_len = strlen(buffer); + buf_len = strlen(buffer) - 1; } break; } else if (arrow_key == 67) { // right diff --git a/rush.h b/rush.h @@ -0,0 +1,6 @@ +#ifndef RUSH_H_ +#define RUSH_H_ + +char **argsplit(char * line); + +#endif