syscalls: implement getcwd syscall
This commit is contained in:
@@ -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
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
@@ -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(¤t_dir)) {
|
||||
uint32_t child_sector = current_dir.file.first_sector;
|
||||
|
||||
// Open the parent directory
|
||||
l9660_dir parent_dir;
|
||||
l9660_opendirat(&parent_dir, ¤t_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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user