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
+1
View File
@@ -11,5 +11,6 @@ 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); char *strtok(char *str, const char *delim);
char *strrchr(const char *s, int c);
#endif #endif
+33 -37
View File
@@ -442,59 +442,55 @@ int sys_execve(TrapFrame *tf) {
int sys_chdir(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_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) // 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.
*(current->cwd) = new_cwd; 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) // At this point, 'status' should be L9660_OK if the path was a valid directory.
{ if (status == L9660_OK) {
l9660_dir dir1; *current->cwd = target_dir;
l9660_status err = l9660_opendirat(&dir1, &new_cwd, (char*)tf->ebx); return 0;
if(err != L9660_ENOTDIR)
{
*(current->cwd) = dir1;
return 0;
}
} }
switch(status) switch(status)
{ {
case L9660_EIO: case L9660_EIO:
return -5;//-EIO
break;
case L9660_EBADFS: case L9660_EBADFS:
return -5;//EIO as well return -5; // -EIO
break;
case L9660_ENOENT: case L9660_ENOENT:
return -2; return -2; // -ENOENT
break;
case L9660_ENOTDIR: case L9660_ENOTDIR:
return -20;//ENOTDIR return -20; // -ENOTDIR
break;
case L9660_OK:
return 0;
break;
default: default:
return -5;//EIO return -1; // Generic error
break;
} }
//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" #include "../include/vfs.h"
+11
View File
@@ -149,4 +149,15 @@ char *strtok(char *str, const char *delim) {
} }
return token_start; 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;
}
} }