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);
}
}
}
}