build.bat can create the image if missing, split the shell into native, posix and win32, clean up the build by moving executables into directories, the bootloader is no longer responsible to resolve drivers, fix ResolvePath, every process gets a copy of a module (dll), the child always inherits the cwd, fix function exports in posix, add unlink and exit to posix, add path translator to win32, first bugcheck.
This commit is contained in:
1 parent
0c7f461c6d
commit
f80e66ecde
38 files changed
+1620
-462
No files matched your search
@@ -0,0 +1,247 @@
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <syscall.h>
|
||||
#include <io_file.h>
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Output helpers
|
||||
// ---------------------------------------------------------------------------
|
||||
static void print(const char* s) {
|
||||
SysWriteConsole(s, strlen(s));
|
||||
}
|
||||
|
||||
static void printUInt(uint32_t n) {
|
||||
char buf[12];
|
||||
int i = 0;
|
||||
if (n == 0) { print("0"); return; }
|
||||
while (n > 0) { buf[i++] = (char)('0' + n % 10); n /= 10; }
|
||||
char rev[12];
|
||||
int j = 0;
|
||||
while (i > 0) rev[j++] = buf[--i];
|
||||
rev[j] = '\0';
|
||||
print(rev);
|
||||
}
|
||||
|
||||
static void printInt(int32_t n) {
|
||||
if (n < 0) {
|
||||
print("-");
|
||||
printUInt((uint32_t)-(n + 1) + 1);
|
||||
} else {
|
||||
printUInt((uint32_t)n);
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Line editor
|
||||
// ---------------------------------------------------------------------------
|
||||
#define MAX_CMD 256
|
||||
|
||||
static void readLine(char* buf, int len) {
|
||||
int pos = 0;
|
||||
while (true) {
|
||||
char c = SysKbReadChar();
|
||||
if (!c) {
|
||||
SysYield();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c == '\r' || c == '\n') {
|
||||
print("\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if ((c == '\b' || c == 127) && pos > 0) {
|
||||
pos--;
|
||||
print("\b \b");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c < 0x20 || c == 127)
|
||||
continue;
|
||||
|
||||
if (pos < len - 1) {
|
||||
buf[pos++] = c;
|
||||
char echo[2] = { c, '\0' };
|
||||
print(echo);
|
||||
}
|
||||
}
|
||||
buf[pos] = '\0';
|
||||
}
|
||||
|
||||
static char* trim(char* s) {
|
||||
while (*s == ' ') s++;
|
||||
int len = (int)strlen(s);
|
||||
while (len > 0 && s[len - 1] == ' ') len--;
|
||||
s[len] = '\0';
|
||||
return s;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Built-in commands
|
||||
// ---------------------------------------------------------------------------
|
||||
static void cmd_help() {
|
||||
print("Available commands:\n"
|
||||
" help - Show this list\n"
|
||||
" dir - List files\n"
|
||||
" cd <path> - Change directory\n"
|
||||
" type <file> - Display file contents\n"
|
||||
" del <file> - Delete a file\n"
|
||||
" write <file> <tx> - Create a file with text\n"
|
||||
" exit - Close the shell\n");
|
||||
}
|
||||
|
||||
static void cmd_write(const char* args) {
|
||||
char filename[MAX_CMD];
|
||||
int i = 0;
|
||||
while (args[i] != ' ' && args[i] != '\0' && i < MAX_CMD - 1) {
|
||||
filename[i] = args[i];
|
||||
i++;
|
||||
}
|
||||
filename[i] = '\0';
|
||||
|
||||
if (args[i] == '\0' || args[i+1] == '\0') {
|
||||
print("write: usage: write <filename> <text>\n");
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t hFile;
|
||||
if (SysCreateFile(filename, &hFile) != 0) {
|
||||
print("write: could not create file\n");
|
||||
return;
|
||||
}
|
||||
|
||||
const char* text = args + i + 1;
|
||||
size_t written;
|
||||
SysWriteFile(hFile, text, strlen(text), &written);
|
||||
SysCloseHandle(hFile);
|
||||
print("File written successfully.\n");
|
||||
}
|
||||
|
||||
static void cmd_dir(const char* path) {
|
||||
uint32_t hDir;
|
||||
|
||||
// Validate input
|
||||
if (path == NULL || path[0] == '\0') {
|
||||
path = "."; // Default to current directory if empty
|
||||
}
|
||||
|
||||
// SysOpenDir (Syscall 54) handles the const char* path directly
|
||||
if (SysOpenDir(path, &hDir) != 0) {
|
||||
SysDebugPrint("dir: failed to open directory\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// Assuming KDIR_ENTRY is your structure for directory entries
|
||||
KDIR_ENTRY ke;
|
||||
|
||||
// SysReadDir (Syscall 55) populates the buffer with entry data
|
||||
// It typically returns 0 on success and non-zero (or error) when done
|
||||
while (SysReadDir(hDir, &ke) == 0) {
|
||||
// We assume ke.Name is a null-terminated string within the struct
|
||||
print(ke.Name);
|
||||
print("\n");
|
||||
}
|
||||
|
||||
// Always close the handle (Syscall 26) to prevent leaks
|
||||
SysCloseHandle(hDir);
|
||||
}
|
||||
|
||||
static void cmd_type(const char* filename) {
|
||||
uint32_t hFile;
|
||||
if (SysOpenFile(filename, &hFile) != 0) {
|
||||
print("type: error opening file\n");
|
||||
return;
|
||||
}
|
||||
|
||||
char buffer[512];
|
||||
size_t bytesRead;
|
||||
while (SysReadFile(hFile, buffer, sizeof(buffer) - 1, &bytesRead) == 0 && bytesRead > 0) {
|
||||
buffer[bytesRead] = '\0';
|
||||
print(buffer);
|
||||
}
|
||||
|
||||
SysCloseHandle(hFile);
|
||||
print("\n");
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Run one command
|
||||
// ---------------------------------------------------------------------------
|
||||
static int runCommand(const char* cmd) {
|
||||
if (!cmd || *cmd == '\0') return 0;
|
||||
|
||||
if (strcmp(cmd, "exit") == 0) return 1;
|
||||
if (strcmp(cmd, "help") == 0) { cmd_help(); return 0; }
|
||||
if (strcmp(cmd, "crash") == 0) { *(int*)0 = 42; return 0; }
|
||||
if (strcmp(cmd, "dir") == 0) {
|
||||
cmd_dir(".");
|
||||
return 0;
|
||||
}
|
||||
if (strncmp(cmd, "dir ", 4) == 0) {
|
||||
cmd_dir(cmd + 4);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strcmp(cmd, "clear") == 0) {
|
||||
SysScreenClear(0x00000000);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strncmp(cmd, "cd ", 3) == 0) {
|
||||
SysSetCwd(cmd + 3);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strncmp(cmd, "del ", 4) == 0) {
|
||||
SysDeleteFile(cmd + 4);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strncmp(cmd, "type ", 5) == 0) {
|
||||
cmd_type(cmd + 5);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strncmp(cmd, "write ", 6) == 0) {
|
||||
cmd_write(cmd + 6);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// --- External Process Execution ---
|
||||
uint32_t hProc;
|
||||
if (SysCreateProcess(cmd, &hProc, cmd) == 0) {
|
||||
SysWaitForProcess(hProc);
|
||||
int exitCode = 0;
|
||||
SysGetProcessExitCode(hProc, &exitCode);
|
||||
SysCloseHandle(hProc);
|
||||
while (SysKbPoll()) {
|
||||
(void)SysKbReadChar();
|
||||
}
|
||||
} else {
|
||||
print("shell: launch failed\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Entry point
|
||||
// ---------------------------------------------------------------------------
|
||||
int main(int argc, char** argv) {
|
||||
char lineBuf[MAX_CMD];
|
||||
|
||||
print("shell: ready\n");
|
||||
|
||||
while (true) {
|
||||
print("> ");
|
||||
readLine(lineBuf, MAX_CMD);
|
||||
if (runCommand(trim(lineBuf)))
|
||||
break;
|
||||
}
|
||||
|
||||
print("shell: goodbye\n");
|
||||
SysExitProcess(0);
|
||||
return 0;
|
||||
}
|
||||
Reference in new issue
Block a user