#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, 128); 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")) { setenv(result[1], result[2]); } else { printf("No such executable file: `%s`\n\n", programName); } } } }