107 lines
2.3 KiB
C
107 lines
2.3 KiB
C
#include "common/common.h"
|
|
|
|
void readline(char* buf, uint32_t lim) {
|
|
uint32_t idx = 0;
|
|
while (1) {
|
|
char c;
|
|
if (idx == lim) {
|
|
printf("\n");
|
|
break;
|
|
}
|
|
if (read(1, 1, &c)) {
|
|
if (c == '\n') {
|
|
write(1, 0, &c);
|
|
break;
|
|
} else if (c == '\b') {
|
|
if (idx > 0) {
|
|
buf[--idx] = 0;
|
|
write(1, 0, &c);
|
|
}
|
|
} else if (c == 0) {
|
|
continue;
|
|
} else {
|
|
buf[idx++] = c;
|
|
write(1, 0, &c);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
typedef enum {
|
|
Normal,
|
|
StringLiteral,
|
|
Escaped
|
|
} ParseState;
|
|
|
|
int main(int argc, char** argv, char** envp) {
|
|
// XOSH - The XnoeOS Shell
|
|
// XoSH is going to be a simple shell that can be used to execute programs.
|
|
|
|
printf("Welcome to %s!\n\n", argv[0]);
|
|
|
|
printf("Environment:\n");
|
|
for (int i=0; envp[i]; i++)
|
|
printf("- %s\n", envp[i]);
|
|
printf("\n");
|
|
|
|
while (1) {
|
|
printf("\x1b[0m# ");
|
|
char input[128];
|
|
memset(input, 0, 128);
|
|
readline(input, 128);
|
|
|
|
// Parse the input
|
|
char* result[32];
|
|
uint32_t ridx=0;
|
|
memset(result, 0, 32 * sizeof(char));
|
|
char c;
|
|
uint32_t idx=0;
|
|
char* lp = input;
|
|
ParseState s = Normal;
|
|
while (c=input[idx++]) {
|
|
switch (s) {
|
|
case Normal:
|
|
switch (c) {
|
|
case '"':
|
|
s = StringLiteral;
|
|
break;
|
|
case '\\':
|
|
s = Escaped;
|
|
break;
|
|
case ' ':
|
|
input[idx-1] = 0;
|
|
result[ridx++] = lp;
|
|
lp = (char*)(input+idx);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
case StringLiteral:
|
|
if (c == '"') {
|
|
s = Normal;
|
|
}
|
|
break;
|
|
case Escaped:
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
result[ridx++] = lp;
|
|
|
|
if (ridx > 0) {
|
|
char* programName = result[0];
|
|
if (exists(programName)) {
|
|
char** argv = result;
|
|
uint32_t program = fopen(programName);
|
|
uint32_t e = execv(program, argv);
|
|
printf("\nExit code: %d\n\n", e);
|
|
} else if (strcmp(result[0], "set")) {
|
|
if (result[1] && result[2]) setenv(result[1], result[2]);
|
|
} else {
|
|
printf("No such executable file: `%s`\n\n", programName);
|
|
}
|
|
}
|
|
}
|
|
} |