syscalls: implement getcwd syscall

This commit is contained in:
2025-10-30 20:26:28 +03:00
parent 26c8280059
commit f4b0429062
9 changed files with 192 additions and 11 deletions
+47
View File
@@ -284,4 +284,51 @@ void follow_path(const char* path, l9660_file* file, l9660_dir* dir)
debug_log("\n");
//printf("buf: %s\n", buf);
debug_log("isdir: %X\n", isdir);
}
#ifdef L9660_BIG_ENDIAN
#define READ32(v) (((v).be[3]) | ((v).be[2] << 8) | ((v).be[1]) << 16 | ((v).be[0] << 24))
#else
#define READ32(v) (((v).le[0]) | ((v).le[1] << 8) | ((v).le[2]) << 16 | ((v).le[3] << 24))
#endif
bool is_root_dir(l9660_dir* dir) {
l9660_dirent* dent;
l9660_status status;
l9660_seekdir(dir, 0);//rewind to start
l9660_readdir(dir, &dent);//reaed .
l9660_readdir(dir, &dent);//read ..
//if .. reads to the directory itself it means that this is the root directory
if (dent != NULL && READ32(dent->sector) == dir->file.first_sector) {
return true;
}
return false;
}
/**
* I'm bad at such loops and ESPECIALLY at such loops which involve sectors and so on
*/
l9660_status find_name_for_sector(char* name_buf, int buf_len, l9660_dir* parent_dir, uint32_t child_sector) {
l9660_dirent* dent;
l9660_status status;
l9660_seekdir(parent_dir, 0); // Rewind parent to search from the start
while (true) {
status = l9660_readdir(parent_dir, &dent);
if (status != L9660_OK) return status;
if (dent == NULL) break; // End of directory
// Is this the entry we are looking for?
if (READ32(dent->sector) == child_sector) {
int len = dent->name_len;
if (len >= buf_len) len = buf_len - 1;
memcpy(name_buf, dent->name, len);
name_buf[len] = '\0';
return L9660_OK;
}
}
return L9660_ENOENT;
}
+1 -1
View File
@@ -136,7 +136,7 @@ void kmain(unsigned int magic, unsigned int info)
follow_path("/katau/caller.", &file, &dir);
exec_from_file(&file, ".");
exec_from_file(&file, &dir);
while(1)
{
+5 -5
View File
@@ -6,17 +6,17 @@
#include "../include/paging.h"
#include "../include/task.h"
void exec_from_file(l9660_file* fs_file, const char* dirname)
void exec_from_file(l9660_file* fs_file, l9660_dir* dir)
{
asm volatile("cli");
int err;
uint8_t* file;
l9660_dir dir;
//l9660_dir dir;
l9660_status status;
status = l9660_opendirat(&dir, root_dir, dirname);
debug_log("l9660_opendirat status: 0x%X\n", status);
//status = l9660_opendirat(&dir, root_dir, dirname);
//debug_log("l9660_opendirat status: 0x%X\n", status);
//list_files(&dir);
@@ -136,7 +136,7 @@ void exec_from_file(l9660_file* fs_file, const char* dirname)
set_page_dir(curr_pd_phys);
Process* p_task1 = task_create(elf_ehdr->e_entry, USER_STACK_TOP, 3, proc_pd);
*p_task1->cwd = dir;
p_task1->cwd = dir;
uint32_t brk_address = DivRoundUp(bss_end+1, 0x1000)*0x1000;
debug_log("initial brk address: 0x%X\n", brk_address);
+52 -2
View File
@@ -416,8 +416,56 @@ int sys_chdir(TrapFrame *tf)
return -1;
}
int sys_getcwd(TrapFrame *tf)
#include "../include/vfs.h"
/**
* I'm very sorry before myself for this but these directory traversing things are so hard, follow_path in vfs was pretty okay,
* this is when shit got real though
*/
uint32_t sys_getcwd(TrapFrame *tf)
{
l9660_dir current_dir = *(current->cwd);
char path_reversed[256] = {0};
char component_name[64];
while (!is_root_dir(&current_dir)) {
uint32_t child_sector = current_dir.file.first_sector;
// Open the parent directory
l9660_dir parent_dir;
l9660_opendirat(&parent_dir, &current_dir, "..");
// Find our previous directory's name within the parent
find_name_for_sector(component_name, sizeof(component_name), &parent_dir, child_sector);
// Prepend the name to our reversed path string (e.g., "dash/" + "katau/" -> "katau/dash/")
strcat(path_reversed, component_name);
strcat(path_reversed, "/");
// Move up one level
current_dir = parent_dir;
}
// Now, reverse the string "dash/katau/" to create the final path "/katau/dash"
char final_path[256] = "/";
char* token = strtok(path_reversed, "/");
while (token != NULL) {
// A bit of a trick to prepend tokens
char temp[256];
strcpy(temp, "/");
strcat(temp, token);
strcat(temp, final_path);
strcpy(final_path, temp);
token = strtok(NULL, "/");
}
// Handle the root case where the loop doesn't run
if (strlen(final_path) > 1) {
final_path[strlen(final_path) - 1] = '\0'; // Remove trailing slash
}
strcpy((char*)tf->ebx, final_path);
//strcpy((char*)tf->ebx, current->cwd->fat->path);
return tf->ebx;
@@ -489,6 +537,8 @@ void handle_syscall(TrapFrame *tf)
debug_log("EDX: %X\n", tf->edx);
*/
debug_log("calling 0x%X\n", tf->eax);
switch(tf->eax)
{
case 1://exit
@@ -544,7 +594,7 @@ void handle_syscall(TrapFrame *tf)
default:
debug_log("unknown syscall: %X\n", tf->eax);
tf->eax = -1;
tf->eax = -38;//-ENOSYS
break;
}
}
+80
View File
@@ -69,4 +69,84 @@ char *strcpy(char *dest, const char *src) {
;
return original_dest;
}
static char *next_token = NULL;
static char *strpbrk_custom(const char *str, const char *delim) {
if (!str || !delim) {
return NULL;
}
while (*str) {
const char *d = delim;
while (*d) {
if (*str == *d) {
return (char *)str;
}
d++;
}
str++;
}
return NULL;
}
char *strtok(char *str, const char *delim) {
char *token_start;
char *token_end;
if (str != NULL) {
next_token = str;
}
if (next_token == NULL || *next_token == '\0') {
return NULL;
}
token_start = next_token;
while (*token_start) {
const char *d = delim;
int is_delim = 0;
while (*d) {
if (*token_start == *d) {
is_delim = 1;
break;
}
d++;
}
if (!is_delim) {
break;
}
token_start++;
}
if (*token_start == '\0') {
next_token = NULL;
return NULL;
}
token_end = token_start;
while (*token_end) {
const char *d = delim;
int is_delim = 0;
while (*d) {
if (*token_end == *d) {
is_delim = 1;
break;
}
d++;
}
if (is_delim) {
break;
}
token_end++;
}
if (*token_end == '\0') {
next_token = NULL;
} else {
*token_end = '\0';
next_token = token_end + 1;
}
return token_start;
}