syscalls: hopefully fix chdir syscall breaking sometimes

This commit is contained in:
2025-11-20 21:12:05 +03:00
parent 1f90fb5825
commit 697029016e
3 changed files with 45 additions and 37 deletions
+33 -37
View File
@@ -442,59 +442,55 @@ int sys_execve(TrapFrame *tf) {
int sys_chdir(TrapFrame *tf)
{
l9660_dir new_cwd;
const char* path = (const char*)tf->ebx;
size_t path_len = strlen(path);
l9660_file placeholder_file;
l9660_dir target_dir;
new_cwd = *current->cwd;
target_dir = *current->cwd;
int status = follow_path(path, &placeholder_file, &target_dir);
int status = follow_path((char*)tf->ebx, &placeholder_file, &new_cwd);
// Case 1: The path does not end with a slash (e.g., "/path/to/dir" or "/path/to/file")
if (path_len == 0 || path[path_len - 1] != '/') {
// If follow_path succeeded, it means the path was a file, which is an error for chdir.
if (status == L9660_OK) {
return -20; // Return -ENOTDIR
}
if(status == L9660_OK)
{
*(current->cwd) = new_cwd;
// If it failed with L9660_ENOTFILE, it means we found a directory when expecting a file.
// This is the expected outcome for a directory path.
if (status == L9660_ENOTFILE) {
// The safe way to proceed is to re-traverse the path with a trailing slash.
// This avoids using the potentially corrupt 'target_dir' left by the failed call.
char new_path[path_len + 2];
memcpy(new_path, path, path_len);
new_path[path_len] = '/';
new_path[path_len + 1] = '\0';
// Reset target_dir and try again with the corrected path.
target_dir = *current->cwd;
status = follow_path(new_path, &placeholder_file, &target_dir);
}
}
if(status == L9660_ENOTFILE)
{
l9660_dir dir1;
l9660_status err = l9660_opendirat(&dir1, &new_cwd, (char*)tf->ebx);
if(err != L9660_ENOTDIR)
{
*(current->cwd) = dir1;
return 0;
}
// At this point, 'status' should be L9660_OK if the path was a valid directory.
if (status == L9660_OK) {
*current->cwd = target_dir;
return 0;
}
switch(status)
{
case L9660_EIO:
return -5;//-EIO
break;
case L9660_EBADFS:
return -5;//EIO as well
break;
return -5; // -EIO
case L9660_ENOENT:
return -2;
break;
return -2; // -ENOENT
case L9660_ENOTDIR:
return -20;//ENOTDIR
break;
case L9660_OK:
return 0;
break;
return -20; // -ENOTDIR
default:
return -5;//EIO
break;
return -1; // Generic error
}
//strcat(current->cwd->fat->path, "/");
//strcat(current->cwd->fat->path, (char*)tf->ebx);
int result = 0;//fat_opendir(current->cwd, (const char*)tf->ebx);
if(result == 0)
return 0;
return -1;
}
#include "../include/vfs.h"
+11
View File
@@ -149,4 +149,15 @@ char *strtok(char *str, const char *delim) {
}
return token_start;
}
char *strrchr(const char *s, int c) {
const char *p = NULL;
for (;;) {
if (*s == (char)c)
p = s;
if (*s++ == '\0')
return (char *)p;
}
}