export and source command
This commit is contained in:
parent
6e8a21ed66
commit
4e94a2a055
4 changed files with 82 additions and 7 deletions
11
README.md
11
README.md
|
@ -20,13 +20,22 @@ $ ./rush
|
||||||
- Syntax highlighting on valid commands using ANSI colors
|
- Syntax highlighting on valid commands using ANSI colors
|
||||||
- History navigation using up and down keys with history command
|
- History navigation using up and down keys with history command
|
||||||
- Built in commands
|
- Built in commands
|
||||||
|
- Export environment variable
|
||||||
|
- Source commands from a file
|
||||||
|
|
||||||
|
# Built in commands
|
||||||
|
- cd
|
||||||
|
- help
|
||||||
|
- exit
|
||||||
|
- history
|
||||||
|
- export
|
||||||
|
- source
|
||||||
|
|
||||||
# Todo Features
|
# Todo Features
|
||||||
- Pipe
|
- Pipe
|
||||||
- stdin, stdout, stderr redirect
|
- stdin, stdout, stderr redirect
|
||||||
- background jobs
|
- background jobs
|
||||||
- editing using left and right arrow keys
|
- editing using left and right arrow keys
|
||||||
- export command to setenv
|
|
||||||
- tab completion
|
- tab completion
|
||||||
|
|
||||||
# Credits
|
# Credits
|
||||||
|
|
63
commands.c
63
commands.c
|
@ -7,27 +7,35 @@
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
|
||||||
#include "commands.h"
|
#include "commands.h"
|
||||||
|
#include "constants.h"
|
||||||
#include "history.h"
|
#include "history.h"
|
||||||
|
#include "rush.h"
|
||||||
|
|
||||||
// Function declarations for builtin commands
|
// Function declarations for builtin commands
|
||||||
int cd(char **args);
|
int cd(char **args);
|
||||||
int help(char **args);
|
int help(char **args);
|
||||||
int quit(char **args);
|
int quit(char **args);
|
||||||
int history(char **args);
|
int history(char **args);
|
||||||
|
int export(char **args);
|
||||||
|
int source(char **args);
|
||||||
|
|
||||||
// List of builtin commands' names
|
// List of builtin commands' names
|
||||||
char *builtin_cmds[] = {
|
char *builtin_cmds[] = {
|
||||||
"cd",
|
"cd",
|
||||||
"help",
|
"help",
|
||||||
"exit",
|
"exit",
|
||||||
"history"
|
"history",
|
||||||
|
"export",
|
||||||
|
"source"
|
||||||
};
|
};
|
||||||
|
|
||||||
int (*builtin_func[]) (char **) = {
|
int (*builtin_func[]) (char **) = {
|
||||||
&cd,
|
&cd,
|
||||||
&help,
|
&help,
|
||||||
&quit, // cant name it exit as it is taken
|
&quit, // cant name it exit as it is taken
|
||||||
&history
|
&history,
|
||||||
|
&export,
|
||||||
|
&source
|
||||||
};
|
};
|
||||||
|
|
||||||
// number of built in commands
|
// number of built in commands
|
||||||
|
@ -80,6 +88,57 @@ int history(char **args) {
|
||||||
return 1;
|
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) {
|
bool is_builtin(char *command) {
|
||||||
for (int i = 0; i < num_builtins(); i++) {
|
for (int i = 0; i < num_builtins(); i++) {
|
||||||
if (strcmp(command, builtin_cmds[i]) == 0) {
|
if (strcmp(command, builtin_cmds[i]) == 0) {
|
||||||
|
|
9
rush.c
9
rush.c
|
@ -92,17 +92,18 @@ char *readline(char **paths) {
|
||||||
while (1) {
|
while (1) {
|
||||||
c = getchar(); // read a character
|
c = getchar(); // read a character
|
||||||
int buf_len = strlen(buffer);
|
int buf_len = strlen(buffer);
|
||||||
//printf("buflen %i\n", buf_len);
|
|
||||||
if (buf_len > 0) {
|
if (buf_len > 0) {
|
||||||
printf("\033[%ldD", strlen(buffer)); // move cursor to the beginning
|
printf("\033[%ldD", strlen(buffer)); // move cursor to the beginning
|
||||||
printf("\033[K"); // clear line to the right of cursor
|
printf("\033[K"); // clear line to the right of cursor
|
||||||
}
|
}
|
||||||
// check each character user has input
|
// check each character user has input
|
||||||
// printf("%i\n", c);
|
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case EOF:
|
case EOF:
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
case 10: // enter/new line feed
|
case 10: // enter/new line feed
|
||||||
|
if (buf_len == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
buffer[buf_len] = '\0';
|
buffer[buf_len] = '\0';
|
||||||
// clear all characters after the command
|
// clear all characters after the command
|
||||||
for (int start = buf_len + 1; buffer[start] != '\0'; start++) {
|
for (int start = buf_len + 1; buffer[start] != '\0'; start++) {
|
||||||
|
@ -124,14 +125,14 @@ char *readline(char **paths) {
|
||||||
char *last_command = read_command(1);
|
char *last_command = read_command(1);
|
||||||
if (last_command != NULL) {
|
if (last_command != NULL) {
|
||||||
strcpy(buffer, last_command);
|
strcpy(buffer, last_command);
|
||||||
buf_len = strlen(buffer);
|
buf_len = strlen(buffer) - 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
} else if (arrow_key == 66) { // down
|
} else if (arrow_key == 66) { // down
|
||||||
char *last_command = read_command(0);
|
char *last_command = read_command(0);
|
||||||
if (last_command != NULL) {
|
if (last_command != NULL) {
|
||||||
strcpy(buffer, last_command);
|
strcpy(buffer, last_command);
|
||||||
buf_len = strlen(buffer);
|
buf_len = strlen(buffer) - 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
} else if (arrow_key == 67) { // right
|
} else if (arrow_key == 67) { // right
|
||||||
|
|
6
rush.h
Normal file
6
rush.h
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
#ifndef RUSH_H_
|
||||||
|
#define RUSH_H_
|
||||||
|
|
||||||
|
char **argsplit(char * line);
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in a new issue