fix: Fix some shell weirdness
This commit is contained in:
+78
-37
@@ -138,6 +138,11 @@ static void cmd_help() {
|
|||||||
zenith::print("Any .elf on the ramdisk is executable.\n");
|
zenith::print("Any .elf on the ramdisk is executable.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if a string already has a VFS drive prefix (e.g. "0:/")
|
||||||
|
static bool has_drive_prefix(const char* s) {
|
||||||
|
return s[0] >= '0' && s[0] <= '9' && s[1] == ':';
|
||||||
|
}
|
||||||
|
|
||||||
// ---- Builtin: ls ----
|
// ---- Builtin: ls ----
|
||||||
|
|
||||||
static void cmd_ls(const char* arg) {
|
static void cmd_ls(const char* arg) {
|
||||||
@@ -146,24 +151,24 @@ static void cmd_ls(const char* arg) {
|
|||||||
// Build the target directory (relative path from root)
|
// Build the target directory (relative path from root)
|
||||||
char dir[128];
|
char dir[128];
|
||||||
if (*arg) {
|
if (*arg) {
|
||||||
// ls <dir> -- combine cwd and arg
|
if (has_drive_prefix(arg)) {
|
||||||
if (cwd[0]) {
|
// Absolute VFS path: "0:/something"
|
||||||
int i = 0, j = 0;
|
scopy(dir, arg + 3, sizeof(dir));
|
||||||
while (cwd[j] && i < 126) dir[i++] = cwd[j++];
|
} else if (arg[0] == '/') {
|
||||||
dir[i++] = '/';
|
// Absolute path from root: "/something"
|
||||||
j = 0;
|
scopy(dir, arg + 1, sizeof(dir));
|
||||||
while (arg[j] && i < 126) dir[i++] = arg[j++];
|
} else if (cwd[0]) {
|
||||||
dir[i] = '\0';
|
// Relative path with CWD
|
||||||
|
scopy(dir, cwd, sizeof(dir));
|
||||||
|
scat(dir, "/", sizeof(dir));
|
||||||
|
scat(dir, arg, sizeof(dir));
|
||||||
} else {
|
} else {
|
||||||
int i = 0;
|
// Relative path at root
|
||||||
while (arg[i] && i < 126) { dir[i] = arg[i]; i++; }
|
scopy(dir, arg, sizeof(dir));
|
||||||
dir[i] = '\0';
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// ls with no arg -- use cwd
|
// ls with no arg -- use cwd
|
||||||
int i = 0;
|
scopy(dir, cwd, sizeof(dir));
|
||||||
while (cwd[i] && i < 126) { dir[i] = cwd[i]; i++; }
|
|
||||||
dir[i] = '\0';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char path[128];
|
char path[128];
|
||||||
@@ -225,19 +230,48 @@ static void cmd_cd(const char* arg) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build target directory path
|
// cd /path -> absolute path from root
|
||||||
|
if (arg[0] == '/') {
|
||||||
|
arg++;
|
||||||
|
if (*arg == '\0') { cwd[0] = '\0'; return; }
|
||||||
|
char path[128];
|
||||||
|
build_dir_path(arg, path, sizeof(path));
|
||||||
|
const char* entries[1];
|
||||||
|
if (zenith::readdir(path, entries, 1) < 0) {
|
||||||
|
zenith::print("cd: no such directory: ");
|
||||||
|
zenith::print(arg);
|
||||||
|
zenith::putchar('\n');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
scopy(cwd, arg, sizeof(cwd));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// cd 0:/path -> absolute VFS path
|
||||||
|
if (has_drive_prefix(arg)) {
|
||||||
|
const char* rel = arg + 3; // skip "0:/"
|
||||||
|
if (*rel == '\0') { cwd[0] = '\0'; return; }
|
||||||
|
char path[128];
|
||||||
|
build_dir_path(rel, path, sizeof(path));
|
||||||
|
const char* entries[1];
|
||||||
|
if (zenith::readdir(path, entries, 1) < 0) {
|
||||||
|
zenith::print("cd: no such directory: ");
|
||||||
|
zenith::print(arg);
|
||||||
|
zenith::putchar('\n');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
scopy(cwd, rel, sizeof(cwd));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build target directory path (relative to CWD)
|
||||||
char target[128];
|
char target[128];
|
||||||
if (cwd[0]) {
|
if (cwd[0]) {
|
||||||
int i = 0, j = 0;
|
scopy(target, cwd, sizeof(target));
|
||||||
while (cwd[j] && i < 126) target[i++] = cwd[j++];
|
scat(target, "/", sizeof(target));
|
||||||
target[i++] = '/';
|
scat(target, arg, sizeof(target));
|
||||||
j = 0;
|
|
||||||
while (arg[j] && i < 126) target[i++] = arg[j++];
|
|
||||||
target[i] = '\0';
|
|
||||||
} else {
|
} else {
|
||||||
int i = 0;
|
scopy(target, arg, sizeof(target));
|
||||||
while (arg[i] && i < 126) { target[i] = arg[i]; i++; }
|
|
||||||
target[i] = '\0';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate: try readdir on the target
|
// Validate: try readdir on the target
|
||||||
@@ -253,9 +287,7 @@ static void cmd_cd(const char* arg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set cwd
|
// Set cwd
|
||||||
int i = 0;
|
scopy(cwd, target, sizeof(cwd));
|
||||||
while (target[i] && i < 126) { cwd[i] = target[i]; i++; }
|
|
||||||
cwd[i] = '\0';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---- Builtin: man ----
|
// ---- Builtin: man ----
|
||||||
@@ -292,11 +324,6 @@ static bool try_exec(const char* path, const char* args) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if a string already has a VFS drive prefix (e.g. "0:/")
|
|
||||||
static bool has_drive_prefix(const char* s) {
|
|
||||||
return s[0] >= '0' && s[0] <= '9' && s[1] == ':';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Resolve arguments: expand relative file paths against CWD.
|
// Resolve arguments: expand relative file paths against CWD.
|
||||||
// Tokens that already have a drive prefix (e.g. "0:/foo") are left as-is.
|
// Tokens that already have a drive prefix (e.g. "0:/foo") are left as-is.
|
||||||
// Everything before the first space-delimited token that looks like a path
|
// Everything before the first space-delimited token that looks like a path
|
||||||
@@ -322,12 +349,26 @@ static void resolve_args(const char* args, char* out, int outMax) {
|
|||||||
bool resolve = cwd[0] && !has_drive_prefix(tokStart) && tokStart[0] != '-';
|
bool resolve = cwd[0] && !has_drive_prefix(tokStart) && tokStart[0] != '-';
|
||||||
|
|
||||||
if (resolve) {
|
if (resolve) {
|
||||||
// Write "0:/<cwd>/<token>"
|
// Build candidate resolved path and check if the file exists
|
||||||
if (o + 3 < outMax) { out[o++] = '0'; out[o++] = ':'; out[o++] = '/'; }
|
char candidate[256];
|
||||||
|
int r = 0;
|
||||||
|
candidate[r++] = '0'; candidate[r++] = ':'; candidate[r++] = '/';
|
||||||
int j = 0;
|
int j = 0;
|
||||||
while (cwd[j] && o < outMax - 1) out[o++] = cwd[j++];
|
while (cwd[j] && r < 255) candidate[r++] = cwd[j++];
|
||||||
if (o < outMax - 1) out[o++] = '/';
|
if (r < 255) candidate[r++] = '/';
|
||||||
for (int k = 0; k < tokLen && o < outMax - 1; k++) out[o++] = tokStart[k];
|
for (int k = 0; k < tokLen && r < 255; k++) candidate[r++] = tokStart[k];
|
||||||
|
candidate[r] = '\0';
|
||||||
|
|
||||||
|
// Only use the resolved path if the file actually exists;
|
||||||
|
// otherwise pass the argument through unchanged (it may be
|
||||||
|
// a hostname, IP address, URL, or other non-path argument).
|
||||||
|
int h = zenith::open(candidate);
|
||||||
|
if (h >= 0) {
|
||||||
|
zenith::close(h);
|
||||||
|
for (int k = 0; k < r && o < outMax - 1; k++) out[o++] = candidate[k];
|
||||||
|
} else {
|
||||||
|
for (int k = 0; k < tokLen && o < outMax - 1; k++) out[o++] = tokStart[k];
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
for (int k = 0; k < tokLen && o < outMax - 1; k++) out[o++] = tokStart[k];
|
for (int k = 0; k < tokLen && o < outMax - 1; k++) out[o++] = tokStart[k];
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user