Compare commits
2 commits
d341e947b0
...
43d3716aff
| Author | SHA1 | Date | |
|---|---|---|---|
| 43d3716aff | |||
| 997cf0c2a7 |
7 changed files with 127 additions and 126 deletions
2
Makefile
2
Makefile
|
|
@ -1,4 +1,4 @@
|
||||||
SOURCES := src/main.c src/util/calloc.c src/util/string.c src/util/hash.c src/lexer/lexer.c src/builtins/builtins.c src/util/memset.c
|
SOURCES := src/main.c src/exec.c src/util/calloc.c src/util/string.c src/util/hash.c src/lexer/lexer.c src/builtins/builtins.c src/util/memset.c
|
||||||
CFLAGS := -g -Oz -nostdlib
|
CFLAGS := -g -Oz -nostdlib
|
||||||
LDFLAGS :=
|
LDFLAGS :=
|
||||||
|
|
||||||
|
|
|
||||||
122
src/exec.c
Normal file
122
src/exec.c
Normal file
|
|
@ -0,0 +1,122 @@
|
||||||
|
#include "builtins/builtins.h"
|
||||||
|
#include "lexer/lexer.h"
|
||||||
|
#include "system/system.h"
|
||||||
|
|
||||||
|
static int do_exec(msh_lexer *lexer, char *cmd, char **args, int *n,
|
||||||
|
int *exec_status) {
|
||||||
|
char full_path[4096];
|
||||||
|
char is_first_arg = 0, exec_success = 0;
|
||||||
|
unsigned short i = 0, j = 0, counter = 0;
|
||||||
|
|
||||||
|
args[*n] = 0;
|
||||||
|
|
||||||
|
/* Do nothing on blank commands */
|
||||||
|
if (*cmd == '\0') {
|
||||||
|
exec_success = 1;
|
||||||
|
}
|
||||||
|
/* Check if the command is a built-in */
|
||||||
|
else if (msh_try_builtin(cmd, args)) {
|
||||||
|
exec_success = 1;
|
||||||
|
}
|
||||||
|
/* If the command is a folder, cd to it */
|
||||||
|
else if (msh_path_is_directory(cmd)) {
|
||||||
|
msh_builtin_cd(cmd);
|
||||||
|
exec_success = 1;
|
||||||
|
}
|
||||||
|
/* If the command is a file, first try and execute it. */
|
||||||
|
else if (msh_path_exists(cmd)) {
|
||||||
|
msh_system_execute(cmd, args);
|
||||||
|
exec_success = 1;
|
||||||
|
} else {
|
||||||
|
/* loop through all the path entries and check if the file exists in them.
|
||||||
|
*/
|
||||||
|
i = 0, *n = 0, j = 0;
|
||||||
|
while (j <= lexer->path_count) {
|
||||||
|
full_path[*n] = lexer->path[j];
|
||||||
|
*n += 1;
|
||||||
|
if (lexer->path[j] == '\0') {
|
||||||
|
full_path[*n - 1] = msh_path_seperator;
|
||||||
|
for (i = 0; cmd[i] != 0; i++) {
|
||||||
|
full_path[i + *n] = cmd[i];
|
||||||
|
}
|
||||||
|
*n += i;
|
||||||
|
full_path[*n] = '\0';
|
||||||
|
*n += 1;
|
||||||
|
|
||||||
|
if (msh_path_exists(full_path)) {
|
||||||
|
msh_system_execute(full_path, args);
|
||||||
|
exec_success = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
counter++;
|
||||||
|
if (counter > 2) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*n = 0;
|
||||||
|
} else {
|
||||||
|
counter = 0;
|
||||||
|
}
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!exec_success) {
|
||||||
|
msh_print_strings("msh: ", cmd, ": command not found\n\r", 0);
|
||||||
|
}
|
||||||
|
/* flush out args */
|
||||||
|
for (i = 0; i < 512; i++) {
|
||||||
|
if (args[i] == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
args[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int msh_execute(msh_lexer *lexer) {
|
||||||
|
msh_lexer_item_list *list = lexer->item_list_head;
|
||||||
|
char *cmd = list->item->str;
|
||||||
|
SIZE_TYPE cmd_size;
|
||||||
|
int i = 0, n = 0, exec_status = 0;
|
||||||
|
SIZE_TYPE args_size = 0;
|
||||||
|
char *args[512];
|
||||||
|
|
||||||
|
while (list != 0) {
|
||||||
|
if (!list->item) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
switch (list->item->type) {
|
||||||
|
case MSH_LEXER_ITEM_TYPE_UNKNOWN:
|
||||||
|
break;
|
||||||
|
case MSH_LEXER_ITEM_TYPE_WORD:
|
||||||
|
if (cmd == 0 && *list->item->str != '\0') {
|
||||||
|
cmd = list->item->str;
|
||||||
|
} else {
|
||||||
|
args[n++] = list->item->str;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MSH_LEXER_ITEM_TYPE_COMMENT:
|
||||||
|
break;
|
||||||
|
case MSH_LEXER_ITEM_TYPE_OP_OR:
|
||||||
|
break;
|
||||||
|
case MSH_LEXER_ITEM_TYPE_OP_AND:
|
||||||
|
do_exec(lexer, cmd, args, &n, &exec_status);
|
||||||
|
n = 0;
|
||||||
|
cmd = 0;
|
||||||
|
break;
|
||||||
|
case MSH_LEXER_ITEM_TYPE_OP_PIPE:
|
||||||
|
break;
|
||||||
|
case MSH_LEXER_ITEM_TYPE_OP_CONTROL:
|
||||||
|
break;
|
||||||
|
case MSH_LEXER_ITEM_TYPE_OP_SEMICOLON:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
list = list->next;
|
||||||
|
}
|
||||||
|
do_exec(lexer, cmd, args, &n, &exec_status);
|
||||||
|
|
||||||
|
msh_lexer_flush(lexer);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
@ -29,9 +29,7 @@
|
||||||
*/
|
*/
|
||||||
#include "lexer.h"
|
#include "lexer.h"
|
||||||
|
|
||||||
#include "../builtins/builtins.h"
|
|
||||||
#include "../system/system.h"
|
#include "../system/system.h"
|
||||||
#include <linux/limits.h>
|
|
||||||
|
|
||||||
msh_lexer msh_lexer_new() {
|
msh_lexer msh_lexer_new() {
|
||||||
msh_lexer l = {0};
|
msh_lexer l = {0};
|
||||||
|
|
@ -148,125 +146,6 @@ lexer_cancel:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int do_exec(msh_lexer *lexer, char *cmd, char **args, int *n,
|
|
||||||
int *exec_status) {
|
|
||||||
char full_path[PATH_MAX];
|
|
||||||
char is_first_arg = 0, exec_success = 0;
|
|
||||||
unsigned short i = 0, j = 0, counter = 0;
|
|
||||||
|
|
||||||
args[*n] = 0;
|
|
||||||
|
|
||||||
/* Do nothing on blank commands */
|
|
||||||
if (*cmd == '\0') {
|
|
||||||
exec_success = 1;
|
|
||||||
}
|
|
||||||
/* Check if the command is a built-in */
|
|
||||||
else if (msh_try_builtin(cmd, args)) {
|
|
||||||
exec_success = 1;
|
|
||||||
}
|
|
||||||
/* If the command is a folder, cd to it */
|
|
||||||
else if (msh_path_is_directory(cmd)) {
|
|
||||||
msh_builtin_cd(cmd);
|
|
||||||
exec_success = 1;
|
|
||||||
}
|
|
||||||
/* If the command is a file, first try and execute it. */
|
|
||||||
else if (msh_path_exists(cmd)) {
|
|
||||||
msh_execute(cmd, args);
|
|
||||||
exec_success = 1;
|
|
||||||
} else {
|
|
||||||
/* loop through all the path entries and check if the file exists in them.
|
|
||||||
*/
|
|
||||||
i = 0, *n = 0, j = 0;
|
|
||||||
while (j <= lexer->path_count) {
|
|
||||||
full_path[*n] = lexer->path[j];
|
|
||||||
*n += 1;
|
|
||||||
if (lexer->path[j] == '\0') {
|
|
||||||
full_path[*n - 1] = msh_path_seperator;
|
|
||||||
for (i = 0; cmd[i] != 0; i++) {
|
|
||||||
full_path[i + *n] = cmd[i];
|
|
||||||
}
|
|
||||||
*n += i;
|
|
||||||
full_path[*n] = '\0';
|
|
||||||
*n += 1;
|
|
||||||
|
|
||||||
if (msh_path_exists(full_path)) {
|
|
||||||
msh_execute(full_path, args);
|
|
||||||
exec_success = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
counter++;
|
|
||||||
if (counter > 2) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
*n = 0;
|
|
||||||
} else {
|
|
||||||
counter = 0;
|
|
||||||
}
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!exec_success) {
|
|
||||||
msh_print_strings("msh: ", cmd, ": command not found\n\r", 0);
|
|
||||||
}
|
|
||||||
/* flush out args */
|
|
||||||
for (i = 0; i < 512; i++) {
|
|
||||||
if (args[i] == 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
args[i] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int msh_lexer_execute(msh_lexer *lexer) {
|
|
||||||
msh_lexer_item_list *list = lexer->item_list_head;
|
|
||||||
char *cmd = list->item->str;
|
|
||||||
SIZE_TYPE cmd_size;
|
|
||||||
int i = 0, n = 0, exec_status = 0;
|
|
||||||
SIZE_TYPE args_size = 0;
|
|
||||||
char *args[512];
|
|
||||||
|
|
||||||
while (list != 0) {
|
|
||||||
if (!list->item) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
switch (list->item->type) {
|
|
||||||
case MSH_LEXER_ITEM_TYPE_UNKNOWN:
|
|
||||||
break;
|
|
||||||
case MSH_LEXER_ITEM_TYPE_WORD:
|
|
||||||
if (cmd == 0 && *list->item->str != '\0') {
|
|
||||||
cmd = list->item->str;
|
|
||||||
} else {
|
|
||||||
args[n++] = list->item->str;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case MSH_LEXER_ITEM_TYPE_COMMENT:
|
|
||||||
break;
|
|
||||||
case MSH_LEXER_ITEM_TYPE_OP_OR:
|
|
||||||
break;
|
|
||||||
case MSH_LEXER_ITEM_TYPE_OP_AND:
|
|
||||||
do_exec(lexer, cmd, args, &n, &exec_status);
|
|
||||||
n = 0;
|
|
||||||
cmd = 0;
|
|
||||||
break;
|
|
||||||
case MSH_LEXER_ITEM_TYPE_OP_PIPE:
|
|
||||||
break;
|
|
||||||
case MSH_LEXER_ITEM_TYPE_OP_CONTROL:
|
|
||||||
break;
|
|
||||||
case MSH_LEXER_ITEM_TYPE_OP_SEMICOLON:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
list = list->next;
|
|
||||||
}
|
|
||||||
do_exec(lexer, cmd, args, &n, &exec_status);
|
|
||||||
|
|
||||||
msh_lexer_flush(lexer);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
void msh_lexer_flush(msh_lexer *lexer) {
|
void msh_lexer_flush(msh_lexer *lexer) {
|
||||||
msh_lexer_item_list *list = lexer->item_list_head;
|
msh_lexer_item_list *list = lexer->item_list_head;
|
||||||
while (list->item != 0) {
|
while (list->item != 0) {
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ void msh_lexer_push_item(msh_lexer *lexer, msh_lexer_item_type type, char *buf,
|
||||||
|
|
||||||
void msh_lexer_flush(msh_lexer *lexer);
|
void msh_lexer_flush(msh_lexer *lexer);
|
||||||
|
|
||||||
int msh_lexer_execute(msh_lexer *lexer);
|
int msh_execute(msh_lexer *lexer);
|
||||||
|
|
||||||
void msh_lexer_free(msh_lexer *lexer);
|
void msh_lexer_free(msh_lexer *lexer);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,7 @@ static void loop_func(int action) {
|
||||||
if (*ctx.buf != '\0') {
|
if (*ctx.buf != '\0') {
|
||||||
int ret;
|
int ret;
|
||||||
msh_lexer_parse(&ctx.lexer, ctx.buf, ctx.sz + 1);
|
msh_lexer_parse(&ctx.lexer, ctx.buf, ctx.sz + 1);
|
||||||
ret = msh_lexer_execute(&ctx.lexer);
|
ret = msh_execute(&ctx.lexer);
|
||||||
|
|
||||||
itoa(ret, ctx.result_str, 10);
|
itoa(ret, ctx.result_str, 10);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -173,7 +173,7 @@ void msh_move_cursor(signed int offset) {
|
||||||
|
|
||||||
void msh_write(char *st, SIZE_TYPE size) { SYSCALL(write, 1, st, size); }
|
void msh_write(char *st, SIZE_TYPE size) { SYSCALL(write, 1, st, size); }
|
||||||
|
|
||||||
int msh_execute(char *cmd, char **args) {
|
int msh_system_execute(char *cmd, char **args) {
|
||||||
SIZE_TYPE fork;
|
SIZE_TYPE fork;
|
||||||
|
|
||||||
if (*cmd == '\0') {
|
if (*cmd == '\0') {
|
||||||
|
|
|
||||||
|
|
@ -145,7 +145,7 @@ typedef struct msh_process_t {
|
||||||
* Non-zero return values are the exit status. -1 implies the command was not
|
* Non-zero return values are the exit status. -1 implies the command was not
|
||||||
* found.
|
* found.
|
||||||
*/
|
*/
|
||||||
int msh_execute(char *cmd, char **args);
|
int msh_system_execute(char *cmd, char **args);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Get an environment variable with the given key.
|
Get an environment variable with the given key.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue