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:
maksw committed 2026-05-13 09:24:16 +02:00
1 parent 0c7f461c6d
commit f80e66ecde
38 files changed
+1620 -462

No files matched your search

+231
View File
@@ -0,0 +1,231 @@
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#include <string.h>
#define NAME_MAX 259
typedef struct dirent {
char d_name[NAME_MAX + 1];
unsigned char d_type; // DT_REG or DT_DIR
} dirent;
typedef struct DIR {
uint32_t KHandle; // kernel DIR_OBJECT handle
dirent Current;
bool Valid;
} DIR;
extern int read(int fd, void *buf, size_t count);
extern int write(int fd, const void *buf, size_t count);
extern int open(const char *pathname, int flags, ...);
extern int close(int fd);
extern int chdir(const char *path);
extern DIR* opendir(const char* path);
extern dirent* readdir(DIR* d);
extern int closedir(DIR* d);
extern int unlink(const char *pathname);
extern int posix_spawn(int *pid, const char *path, const void *file_act, const void *attr, char *const argv[], char *const envp[]);
extern int waitpid(int pid, int *status, int options);
extern void exit(int status);
extern void PosixFdInit(void);
extern int ClearConsoleScreenBuffer(void* hConsole);
// ---------------------------------------------------------------------------
// Global handles
// ---------------------------------------------------------------------------
static int hIn = 0; // stdin
static int hOut = 1; // stdout
// ---------------------------------------------------------------------------
// Output helpers
// ---------------------------------------------------------------------------
static void print(const char* s) {
write(hOut, 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("-"); n = -n; }
printUInt((uint32_t)n);
}
// ---------------------------------------------------------------------------
// Line editor
// ---------------------------------------------------------------------------
#define MAX_CMD 256
static void readLine(char* buf, int len) {
int pos = 0;
while (true) {
char c;
if (read(hIn, &c, 1) <= 0) break;
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 [path] - List directory contents\n"
" cd <path> - Change directory\n"
" type <file> - Display file contents\n"
" del <file> - Delete a file\n"
" write <file> <txt> - 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') return;
// Open with O_WRONLY | O_CREAT | O_TRUNC (typical flags: 0x0001 | 0x0040 | 0x0200)
int fd = open(filename, 0x0241, 0644);
if (fd < 0) return;
write(fd, args + i + 1, strlen(args + i + 1));
close(fd);
}
static void cmd_dir(const char* path) {
// If no path is provided, default to current directory
const char* target = (path && *path != '\0') ? path : ".";
DIR* d = opendir(target);
if (!d) {
print("dir: cannot access '");
print(target);
print("'\n");
return;
}
dirent* entry;
while ((entry = readdir(d)) != NULL) {
// Filter out the current and parent directory markers
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
continue;
}
// Display type (Assuming 1=DIR, 2=REG based on common custom POSIX layouts)
if (entry->d_type == 1) {
print("<DIR> ");
} else {
print(" ");
}
print(entry->d_name);
print("\n");
}
closedir(d);
}
static void cmd_type(const char* filename) {
int fd = open(filename, 0); // O_RDONLY
if (fd < 0) return;
char buffer[512];
int n;
while ((n = read(fd, buffer, 511)) > 0) {
buffer[n] = '\0';
print(buffer);
}
close(fd);
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) {
ClearConsoleScreenBuffer(0);
return 0;
}
if (strncmp(cmd, "cd ", 3) == 0) { chdir(cmd + 3); return 0; }
if (strncmp(cmd, "del ", 4) == 0) { unlink(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 (No Fork) ---
int pid;
char *argv[] = {(char*)cmd, NULL};
if (posix_spawn(&pid, cmd, NULL, NULL, argv, NULL) == 0) {
int status;
waitpid(pid, &status, 0);
} else {
print("shell: error launching\n");
}
return 0;
}
int main(const char* args) {
PosixFdInit();
char lineBuf[MAX_CMD];
print("shell: ready\n");
while (true) {
print("> ");
readLine(lineBuf, MAX_CMD);
if (runCommand(trim(lineBuf))) break;
}
print("shell: goodbye\n");
exit(0);
}