|
|
|
@ -17,8 +17,7 @@ int repl(State* state, FILE *input);
@@ -17,8 +17,7 @@ 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);
|
|
|
|
|
|
|
|
|
|
const int GLOB_DEBUG; |
|
|
|
|
int expand_command(State *state, int *argc, char** ret_argv[]);
|
|
|
|
|
|
|
|
|
|
GrowingArray get_growing_array(size_t num_elements, size_t size_elem) { |
|
|
|
|
GrowingArray arr; |
|
|
|
@ -260,6 +259,7 @@ int run_pipes(State *state, int num_args, char *args []) {
@@ -260,6 +259,7 @@ int run_pipes(State *state, int num_args, char *args []) {
|
|
|
|
|
for (int i = 0; i < num_commands; i++) { |
|
|
|
|
char **command; |
|
|
|
|
int words; |
|
|
|
|
|
|
|
|
|
int err = split_string(&command, &words, sep_commands[i], ' '); |
|
|
|
|
|
|
|
|
|
if (i == 0) { |
|
|
|
@ -273,12 +273,26 @@ int run_pipes(State *state, int num_args, char *args []) {
@@ -273,12 +273,26 @@ int run_pipes(State *state, int num_args, char *args []) {
|
|
|
|
|
out = pipes[2*i + 1]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
printf("in %d out: %d exec: ", in, out); |
|
|
|
|
for (int i = 0; i < words; i++) { |
|
|
|
|
int command_len = 0; |
|
|
|
|
for (int i = 0; command[i] != 0; i++) { |
|
|
|
|
command_len++; |
|
|
|
|
} |
|
|
|
|
//free(command[i]); // free the null pointer on the end
|
|
|
|
|
expand_command(state, &command_len, &command); |
|
|
|
|
for (int i = 0; i < command_len; i++) { |
|
|
|
|
printf("%s ", command[i]); |
|
|
|
|
} |
|
|
|
|
printf("\n"); |
|
|
|
|
|
|
|
|
|
command = reallocarray(command, command_len+1, sizeof(char*)); |
|
|
|
|
command[command_len] = 0; |
|
|
|
|
|
|
|
|
|
execute(in, out, command, &child); |
|
|
|
|
|
|
|
|
|
for (int i = 0; i < command_len; i++) { |
|
|
|
|
free(command[i]); |
|
|
|
|
} |
|
|
|
|
free(command); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int status; |
|
|
|
@ -294,7 +308,6 @@ int run_pipes(State *state, int num_args, char *args []) {
@@ -294,7 +308,6 @@ int run_pipes(State *state, int num_args, char *args []) {
|
|
|
|
|
return ER_SUCCESS; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int check_builtins(State *state, int num_args, char *args[]) { |
|
|
|
|
char *builtins[NUM_BUILTINS] = { |
|
|
|
|
"cd", |
|
|
|
@ -372,6 +385,7 @@ int check_builtins(State *state, int num_args, char *args[]) {
@@ -372,6 +385,7 @@ int check_builtins(State *state, int num_args, char *args[]) {
|
|
|
|
|
int err = join_string(&substitution, num_args - 1,
|
|
|
|
|
args + 1, " "); |
|
|
|
|
if (err) { |
|
|
|
|
free(substitution); |
|
|
|
|
return err; |
|
|
|
|
} |
|
|
|
|
int eqcount = 0; |
|
|
|
@ -380,10 +394,22 @@ int check_builtins(State *state, int num_args, char *args[]) {
@@ -380,10 +394,22 @@ int check_builtins(State *state, int num_args, char *args[]) {
|
|
|
|
|
|
|
|
|
|
// exit if alias contains an =
|
|
|
|
|
if (num_parts != 2 || err) { |
|
|
|
|
free(substitution); |
|
|
|
|
for (int i =0; i < num_parts; i++) { |
|
|
|
|
free(new_split[i]); |
|
|
|
|
} |
|
|
|
|
free(new_split); |
|
|
|
|
return ER_FAILURE; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
err = add_alias(state, new_split[0], new_split[1]); |
|
|
|
|
|
|
|
|
|
free(substitution); |
|
|
|
|
for (int i =0; i < num_parts; i++) { |
|
|
|
|
free(new_split[i]); |
|
|
|
|
} |
|
|
|
|
free(new_split); |
|
|
|
|
|
|
|
|
|
return err; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -427,7 +453,7 @@ int check_builtins(State *state, int num_args, char *args[]) {
@@ -427,7 +453,7 @@ int check_builtins(State *state, int num_args, char *args[]) {
|
|
|
|
|
return ER_NOT_EXISTS; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int check_aliases(State *state, char **substitution, char *name) { |
|
|
|
|
int check_aliase(State *state, char **substitution, char *name) { |
|
|
|
|
Alias alias; |
|
|
|
|
for (int i = 0; i < state->num_aliases; i++) { |
|
|
|
|
if (!get_alias(&alias, state, name)) { |
|
|
|
@ -438,32 +464,40 @@ int check_aliases(State *state, char **substitution, char *name) {
@@ -438,32 +464,40 @@ int check_aliases(State *state, char **substitution, char *name) {
|
|
|
|
|
return ER_FAILURE; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int expand_command(State *state, int argc, char* argv[]) { |
|
|
|
|
if (argc == 0) { |
|
|
|
|
int expand_command(State *state, int* argc, char** ret_argv[]) { |
|
|
|
|
if (*argc == 0) { |
|
|
|
|
return ER_FAILURE; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
char **argv = *ret_argv; |
|
|
|
|
|
|
|
|
|
char *substitution; |
|
|
|
|
if (!check_aliases(state, &substitution, argv[0])) { |
|
|
|
|
strip_char(argv[0], ' '); |
|
|
|
|
argv[0] = reallocarray(argv[0], strlen(substitution) + 1, sizeof(char)); |
|
|
|
|
strcpy(argv[0], substitution); |
|
|
|
|
char *joined; |
|
|
|
|
char **new_argv; |
|
|
|
|
int len; |
|
|
|
|
join_string(&joined, argc, argv, " "); |
|
|
|
|
split_string(&new_argv, &len, joined, ' '); |
|
|
|
|
|
|
|
|
|
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); |
|
|
|
|
for (int i = 0; i < *argc; i++) { |
|
|
|
|
if (!check_aliase(state, &substitution, argv[i])) { |
|
|
|
|
|
|
|
|
|
strip_char(argv[i], ' ');
|
|
|
|
|
|
|
|
|
|
// copy substitution into argv array
|
|
|
|
|
*ret_argv[i] = reallocarray(*ret_argv[i], strlen(substitution) + 1, sizeof(char)); |
|
|
|
|
strcpy(*ret_argv[0], substitution); |
|
|
|
|
|
|
|
|
|
// expand substituted piece into the erray splitting over spaces
|
|
|
|
|
char *joined; |
|
|
|
|
char **new_argv; |
|
|
|
|
join_string(&joined, *argc, *ret_argv, " "); |
|
|
|
|
split_string(&new_argv, argc, joined, ' '); |
|
|
|
|
|
|
|
|
|
for (int j = 0 ; j < *argc;j ++) { |
|
|
|
|
free(*ret_argv[j]); |
|
|
|
|
} |
|
|
|
|
free(*ret_argv); |
|
|
|
|
|
|
|
|
|
*ret_argv = new_argv; |
|
|
|
|
/***************************************/ |
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return ER_SUCCESS; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -476,19 +510,33 @@ int run_command(State *state, int argc, char *argv[]) {
@@ -476,19 +510,33 @@ int run_command(State *state, int argc, char *argv[]) {
|
|
|
|
|
return ER_SUCCESS; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* read eval print loop until EOF */ |
|
|
|
|
/* read eval print loop until SIGTERM or end of non-interact file*/ |
|
|
|
|
int repl(State* state, FILE *input) { |
|
|
|
|
while (true) { |
|
|
|
|
char *line; |
|
|
|
|
|
|
|
|
|
if (state->interactive) { |
|
|
|
|
line = readline(state->ps1); |
|
|
|
|
if (!line)
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
char ** ps1_sep; |
|
|
|
|
int num; |
|
|
|
|
split_string(&ps1_sep, &num, state->ps1, ' '); |
|
|
|
|
run_command(state, num, ps1_sep); |
|
|
|
|
for (int i = 0; i < num; i ++) { |
|
|
|
|
free(ps1_sep[i]); |
|
|
|
|
} |
|
|
|
|
free(ps1_sep); |
|
|
|
|
|
|
|
|
|
line = readline("$ "); |
|
|
|
|
if (!line) { |
|
|
|
|
printf("EOF\n"); |
|
|
|
|
return ER_SUCCESS; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
add_history(line); |
|
|
|
|
} else { |
|
|
|
|
if (get_line(input, &line)) { |
|
|
|
|
if (line) |
|
|
|
|
free(line); |
|
|
|
|
return ER_SUCCESS; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -497,27 +545,27 @@ int repl(State* state, FILE *input) {
@@ -497,27 +545,27 @@ int repl(State* state, FILE *input) {
|
|
|
|
|
int num_words; |
|
|
|
|
|
|
|
|
|
split_string(&sep_string, &num_words, line, ' '); |
|
|
|
|
free(line); |
|
|
|
|
|
|
|
|
|
if (num_words == 0) { |
|
|
|
|
if (num_words == 0 // line is empty
|
|
|
|
|
|| sep_string[0][0] == '#') { // line is comment
|
|
|
|
|
for (int i = 0; i <= num_words; i ++)
|
|
|
|
|
free(sep_string[i]); |
|
|
|
|
free(sep_string); |
|
|
|
|
free(line); |
|
|
|
|
continue; |
|
|
|
|
continue; // skip execution
|
|
|
|
|
} |
|
|
|
|
// int err = check_pipes(state, num_words, sep_string);
|
|
|
|
|
|
|
|
|
|
int err = run_pipes(state, num_words, sep_string); |
|
|
|
|
|
|
|
|
|
if (err == ER_NOT_EXISTS) { |
|
|
|
|
expand_command(state, num_words, sep_string); |
|
|
|
|
expand_command(state, &num_words, &sep_string); |
|
|
|
|
run_command(state, num_words, sep_string); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i <= num_words; i ++) { |
|
|
|
|
for (int i = 0; i < num_words; i ++) { |
|
|
|
|
free(sep_string[i]); |
|
|
|
|
} |
|
|
|
|
free(sep_string); |
|
|
|
|
free(line); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -525,7 +573,7 @@ int startup(State *state, int argc, char **argv) {
@@ -525,7 +573,7 @@ int startup(State *state, int argc, char **argv) {
|
|
|
|
|
state->output = stdout; |
|
|
|
|
|
|
|
|
|
state->ps1 = calloc(3, sizeof(char)); |
|
|
|
|
strcpy(state->ps1, "$ "); |
|
|
|
|
strcpy(state->ps1, "pwd"); |
|
|
|
|
|
|
|
|
|
state->variables = get_growing_array(INITIAL_NUM_VARIABLES, sizeof(char*)); |
|
|
|
|
|
|
|
|
|