|
|
|
@ -9,6 +9,9 @@ int get_alias(Alias *alias, State *state, char *name);
@@ -9,6 +9,9 @@ int get_alias(Alias *alias, State *state, char *name);
|
|
|
|
|
int add_alias(State* state, char *name, char *substitution);
|
|
|
|
|
int del_alias(State *state, char *name);
|
|
|
|
|
int repl(State* state, FILE *input);
|
|
|
|
|
int run_command(State *state, int argc, char *argv[]);
|
|
|
|
|
int get_array_element(ArrayElement **ret, GrowingArray* array, char* key);
|
|
|
|
|
int del_array_element(GrowingArray* array, char* key);
|
|
|
|
|
|
|
|
|
|
GrowingArray get_growing_array(size_t num_elements, size_t size_elem) { |
|
|
|
|
GrowingArray arr; |
|
|
|
@ -199,14 +202,83 @@ void shutdown(State *state) {
@@ -199,14 +202,83 @@ void shutdown(State *state) {
|
|
|
|
|
exit(0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int check_pipes(State* state, int num_args, char* args[]) { |
|
|
|
|
|
|
|
|
|
int left = 0; |
|
|
|
|
int num_commands = 0; |
|
|
|
|
int space = 10; |
|
|
|
|
// an array of string-arrays which end in NULL
|
|
|
|
|
char** *pipes = calloc(space, sizeof(char***));
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < num_args; i++) { |
|
|
|
|
if (!strcmp(args[i], "|") || i == num_args - 1) { |
|
|
|
|
int command_length = i - left + 1 + num_commands; |
|
|
|
|
char **command = calloc(command_length, sizeof(char**)); |
|
|
|
|
// copy the command into the array
|
|
|
|
|
for (int k = 0; k < command_length - 1; k++) { |
|
|
|
|
command[k] = args[left + k]; |
|
|
|
|
} |
|
|
|
|
command[command_length - 1] = 0; |
|
|
|
|
|
|
|
|
|
// grow the array if needed
|
|
|
|
|
if (num_commands == space - 2) { |
|
|
|
|
pipes = calloc((space *= 2), sizeof(char***)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
pipes[num_commands] = command; |
|
|
|
|
num_commands++; |
|
|
|
|
|
|
|
|
|
left = i + 1; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (num_commands == 1) { |
|
|
|
|
return ER_NOT_EXISTS; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int pipein[2]; |
|
|
|
|
int pipeout[2]; |
|
|
|
|
memset(pipein, 0, sizeof(int) * 2); |
|
|
|
|
memset(pipeout, 0, sizeof(int) * 2); |
|
|
|
|
|
|
|
|
|
pipe(pipein); |
|
|
|
|
pipe(pipeout); |
|
|
|
|
// 0 is read, 1 is write
|
|
|
|
|
|
|
|
|
|
pid_t child; |
|
|
|
|
|
|
|
|
|
int in; |
|
|
|
|
int out; |
|
|
|
|
|
|
|
|
|
in = 0; |
|
|
|
|
out = pipeout[1]; |
|
|
|
|
|
|
|
|
|
for (int i = 0; i < num_commands; i++) { |
|
|
|
|
execute(in, out, pipes[i], &child); |
|
|
|
|
if (i != num_commands - 1) { |
|
|
|
|
if (in == pipein[0]) { |
|
|
|
|
in = pipeout[0]; |
|
|
|
|
out = pipein[1]; |
|
|
|
|
} else { |
|
|
|
|
in = pipein[0]; |
|
|
|
|
out = pipeout[1]; |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
out = 1;
|
|
|
|
|
in = out - 1; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return ER_SUCCESS; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int check_builtins(State *state, int num_args, char *args[]) { |
|
|
|
|
char *builtins[NUM_BUILTINS] = { |
|
|
|
|
"cd", |
|
|
|
|
"alias", |
|
|
|
|
"unalias" |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
if (!strcmp(args[0], "cd")) { |
|
|
|
|
if (!strcmp(args[0], "cd")) { |
|
|
|
|
if (num_args == 1) { |
|
|
|
|
chdir(getenv("HOME")); |
|
|
|
|
return ER_SUCCESS; |
|
|
|
@ -343,15 +415,12 @@ int check_aliases(State *state, char **substitution, char *name) {
@@ -343,15 +415,12 @@ int check_aliases(State *state, char **substitution, char *name) {
|
|
|
|
|
return ER_FAILURE; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int run_command(State *state, int argc, char *argv[]) { |
|
|
|
|
pid_t child; |
|
|
|
|
|
|
|
|
|
int expand_command(State *state, int argc, char* argv[]) { |
|
|
|
|
if (argc == 0) { |
|
|
|
|
return ER_FAILURE; |
|
|
|
|
} |
|
|
|
|
char *substitution; |
|
|
|
|
|
|
|
|
|
char *substitution; |
|
|
|
|
if (!check_aliases(state, &substitution, argv[0])) { |
|
|
|
|
strip_char(argv[0], ' '); |
|
|
|
|
argv[0] = reallocarray(argv[0], strlen(substitution) + 1, sizeof(char)); |
|
|
|
@ -362,25 +431,29 @@ int run_command(State *state, int argc, char *argv[]) {
@@ -362,25 +431,29 @@ int run_command(State *state, int argc, char *argv[]) {
|
|
|
|
|
join_string(&joined, argc, argv, " "); |
|
|
|
|
split_string(&new_argv, &len, joined, ' '); |
|
|
|
|
|
|
|
|
|
//run_command(state, len, new_argv);
|
|
|
|
|
execute(stdin, stdout, new_argv, &child); |
|
|
|
|
waitpid(child, NULL, 0); |
|
|
|
|
return ER_SUCCESS; |
|
|
|
|
run_command(state, len, new_argv); |
|
|
|
|
|
|
|
|
|
for (int i = 0 ; i < len; i ++) { |
|
|
|
|
free(new_argv[i]); |
|
|
|
|
} |
|
|
|
|
free(new_argv); |
|
|
|
|
return ER_SUCCESS; |
|
|
|
|
} else { |
|
|
|
|
run_command(state, argc, argv); |
|
|
|
|
} |
|
|
|
|
return ER_SUCCESS; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int run_command(State *state, int argc, char *argv[]) { |
|
|
|
|
pid_t child; |
|
|
|
|
if (check_builtins(state, argc, argv) == ER_NOT_EXISTS) { |
|
|
|
|
execute(stdin, stdout, argv, &child); |
|
|
|
|
execute(0,1, argv, &child); |
|
|
|
|
waitpid(child, NULL, 0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return ER_SUCCESS; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* read eval print loop until EOF */ |
|
|
|
|
int repl(State* state, FILE *input) { |
|
|
|
|
while (true) { |
|
|
|
|
char *line; |
|
|
|
@ -398,7 +471,11 @@ int repl(State* state, FILE *input) {
@@ -398,7 +471,11 @@ int repl(State* state, FILE *input) {
|
|
|
|
|
|
|
|
|
|
split_string(&sep_string, &num_words, line, ' '); |
|
|
|
|
|
|
|
|
|
run_command(state, num_words, sep_string); |
|
|
|
|
int err = check_pipes(state, num_words, sep_string); |
|
|
|
|
if (err == ER_NOT_EXISTS) { |
|
|
|
|
expand_command(state, num_words, sep_string); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < num_words; i++) { |
|
|
|
|
free(sep_string[i]); |
|
|
|
|