syscalls: implement getcwd syscall
This commit is contained in:
+2
-2
@@ -9,7 +9,7 @@ int main() {
|
|||||||
|
|
||||||
// Arguments for the new program
|
// Arguments for the new program
|
||||||
// The first argument is conventionally the program name
|
// The first argument is conventionally the program name
|
||||||
char *argv[] = { "/katau/core", "--help", NULL };
|
char *argv[] = { "/katau/dash", "--help", NULL };
|
||||||
|
|
||||||
// Environment variables for the new program
|
// Environment variables for the new program
|
||||||
char *envp[] = { "CUSTOM_VAR=Hello from caller!", "ANOTHER_VAR=123", NULL };
|
char *envp[] = { "CUSTOM_VAR=Hello from caller!", "ANOTHER_VAR=123", NULL };
|
||||||
@@ -18,7 +18,7 @@ int main() {
|
|||||||
// The first argument is the path to the executable
|
// The first argument is the path to the executable
|
||||||
// The second is the array of arguments
|
// The second is the array of arguments
|
||||||
// The third is the array of environment variables
|
// The third is the array of environment variables
|
||||||
execve("/katau/core.", argv, envp);
|
execve("/katau/dash.", argv, envp);
|
||||||
|
|
||||||
// This part of the code will only be reached if execve fails
|
// This part of the code will only be reached if execve fails
|
||||||
perror("execve failed");
|
perror("execve failed");
|
||||||
|
|||||||
@@ -9,4 +9,4 @@
|
|||||||
#define USER_STACK_SIZE 0x4000 // 16KB stack (4 pages)
|
#define USER_STACK_SIZE 0x4000 // 16KB stack (4 pages)
|
||||||
#define USER_STACK_BOTTOM (USER_STACK_TOP - USER_STACK_SIZE)
|
#define USER_STACK_BOTTOM (USER_STACK_TOP - USER_STACK_SIZE)
|
||||||
|
|
||||||
void exec_from_file(l9660_file* fs_file, const char* dirname);
|
void exec_from_file(l9660_file* fs_file, l9660_dir* dir);
|
||||||
@@ -10,5 +10,6 @@ void* memset(void*, int, size_t);
|
|||||||
size_t strlen(const char*);
|
size_t strlen(const char*);
|
||||||
char *strcat(char *dest, const char *src);
|
char *strcat(char *dest, const char *src);
|
||||||
char *strcpy(char *dest, const char *src);
|
char *strcpy(char *dest, const char *src);
|
||||||
|
char *strtok(char *str, const char *delim);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -22,4 +22,7 @@ void test_iso9660();
|
|||||||
int vfs_read_file_by_path(const char* path, uint8_t** buffer);
|
int vfs_read_file_by_path(const char* path, uint8_t** buffer);
|
||||||
void follow_path(const char* path, l9660_file* file, l9660_dir* dir);
|
void follow_path(const char* path, l9660_file* file, l9660_dir* dir);
|
||||||
|
|
||||||
|
l9660_status find_name_for_sector(char* name_buf, int buf_len, l9660_dir* parent_dir, uint32_t child_sector);
|
||||||
|
bool is_root_dir(l9660_dir* dir);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -284,4 +284,51 @@ void follow_path(const char* path, l9660_file* file, l9660_dir* dir)
|
|||||||
debug_log("\n");
|
debug_log("\n");
|
||||||
//printf("buf: %s\n", buf);
|
//printf("buf: %s\n", buf);
|
||||||
debug_log("isdir: %X\n", isdir);
|
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);
|
follow_path("/katau/caller.", &file, &dir);
|
||||||
|
|
||||||
exec_from_file(&file, ".");
|
exec_from_file(&file, &dir);
|
||||||
|
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,17 +6,17 @@
|
|||||||
#include "../include/paging.h"
|
#include "../include/paging.h"
|
||||||
#include "../include/task.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");
|
asm volatile("cli");
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
uint8_t* file;
|
uint8_t* file;
|
||||||
l9660_dir dir;
|
//l9660_dir dir;
|
||||||
l9660_status status;
|
l9660_status status;
|
||||||
|
|
||||||
status = l9660_opendirat(&dir, root_dir, dirname);
|
//status = l9660_opendirat(&dir, root_dir, dirname);
|
||||||
debug_log("l9660_opendirat status: 0x%X\n", status);
|
//debug_log("l9660_opendirat status: 0x%X\n", status);
|
||||||
|
|
||||||
//list_files(&dir);
|
//list_files(&dir);
|
||||||
|
|
||||||
@@ -136,7 +136,7 @@ void exec_from_file(l9660_file* fs_file, const char* dirname)
|
|||||||
|
|
||||||
set_page_dir(curr_pd_phys);
|
set_page_dir(curr_pd_phys);
|
||||||
Process* p_task1 = task_create(elf_ehdr->e_entry, USER_STACK_TOP, 3, proc_pd);
|
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;
|
uint32_t brk_address = DivRoundUp(bss_end+1, 0x1000)*0x1000;
|
||||||
debug_log("initial brk address: 0x%X\n", brk_address);
|
debug_log("initial brk address: 0x%X\n", brk_address);
|
||||||
|
|||||||
+52
-2
@@ -416,8 +416,56 @@ int sys_chdir(TrapFrame *tf)
|
|||||||
return -1;
|
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);
|
//strcpy((char*)tf->ebx, current->cwd->fat->path);
|
||||||
|
|
||||||
return tf->ebx;
|
return tf->ebx;
|
||||||
@@ -489,6 +537,8 @@ void handle_syscall(TrapFrame *tf)
|
|||||||
debug_log("EDX: %X\n", tf->edx);
|
debug_log("EDX: %X\n", tf->edx);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
debug_log("calling 0x%X\n", tf->eax);
|
||||||
|
|
||||||
switch(tf->eax)
|
switch(tf->eax)
|
||||||
{
|
{
|
||||||
case 1://exit
|
case 1://exit
|
||||||
@@ -544,7 +594,7 @@ void handle_syscall(TrapFrame *tf)
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
debug_log("unknown syscall: %X\n", tf->eax);
|
debug_log("unknown syscall: %X\n", tf->eax);
|
||||||
tf->eax = -1;
|
tf->eax = -38;//-ENOSYS
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,4 +69,84 @@ char *strcpy(char *dest, const char *src) {
|
|||||||
;
|
;
|
||||||
|
|
||||||
return original_dest;
|
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