syscalls: hopefully fix chdir syscall breaking sometimes
This commit is contained in:
@@ -11,5 +11,6 @@ size_t strlen(const char*);
|
||||
char *strcat(char *dest, const char *src);
|
||||
char *strcpy(char *dest, const char *src);
|
||||
char *strtok(char *str, const char *delim);
|
||||
char *strrchr(const char *s, int c);
|
||||
|
||||
#endif
|
||||
|
||||
+33
-37
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user