Fix wrong argument of write. Fix return type of getdents. Fix procfs_getdents. Finish implementing the base version of the ps command.
This commit is contained in:
@@ -377,7 +377,7 @@ static ssize_t ext2_write(vfs_file_t *file, const void *buffer, off_t offset, si
|
||||
static off_t ext2_lseek(vfs_file_t *file, off_t offset, int whence);
|
||||
static int ext2_fstat(vfs_file_t *file, stat_t *stat);
|
||||
static int ext2_ioctl(vfs_file_t *file, int request, void *data);
|
||||
static int ext2_getdents(vfs_file_t *file, dirent_t *dirp, off_t doff, size_t count);
|
||||
static ssize_t ext2_getdents(vfs_file_t *file, dirent_t *dirp, off_t doff, size_t count);
|
||||
|
||||
static int ext2_mkdir(const char *path, mode_t mode);
|
||||
static int ext2_rmdir(const char *path);
|
||||
@@ -2640,7 +2640,7 @@ static int ext2_ioctl(vfs_file_t *file, int request, void *data)
|
||||
/// @param doff The offset inside the buffer where the data should be written.
|
||||
/// @param count The maximum length of the buffer.
|
||||
/// @return The number of written bytes in the buffer.
|
||||
static int ext2_getdents(vfs_file_t *file, dirent_t *dirp, off_t doff, size_t count)
|
||||
static ssize_t ext2_getdents(vfs_file_t *file, dirent_t *dirp, off_t doff, size_t count)
|
||||
{
|
||||
pr_debug("ext2_getdents(%s, %p, %d, %d)\n", file->name, dirp, doff, count);
|
||||
// Get the filesystem.
|
||||
@@ -2655,7 +2655,8 @@ static int ext2_getdents(vfs_file_t *file, dirent_t *dirp, off_t doff, size_t co
|
||||
pr_err("Failed to read the inode (%d).\n", file->ino);
|
||||
return -ENOENT;
|
||||
}
|
||||
uint32_t current = 0, written = 0;
|
||||
uint32_t current = 0;
|
||||
ssize_t written = 0;
|
||||
// Allocate the cache.
|
||||
uint8_t *cache = kmem_cache_alloc(fs->ext2_buffer_cache, GFP_KERNEL);
|
||||
// Clean the cache.
|
||||
|
||||
+52
-44
@@ -90,7 +90,7 @@ static ssize_t procfs_write(vfs_file_t *file, const void *buffer, off_t offset,
|
||||
static off_t procfs_lseek(vfs_file_t *file, off_t offset, int whence);
|
||||
static int procfs_fstat(vfs_file_t *file, stat_t *stat);
|
||||
static int procfs_ioctl(vfs_file_t *file, int request, void *data);
|
||||
static int procfs_getdents(vfs_file_t *file, dirent_t *dirp, off_t doff, size_t count);
|
||||
static ssize_t procfs_getdents(vfs_file_t *file, dirent_t *dirp, off_t doff, size_t count);
|
||||
|
||||
// ============================================================================
|
||||
// Virtual FileSystem (VFS) Operaions
|
||||
@@ -691,63 +691,71 @@ static int procfs_ioctl(vfs_file_t *file, int request, void *data)
|
||||
/// @param doff The offset inside the buffer where the data should be written.
|
||||
/// @param count The maximum length of the buffer.
|
||||
/// @return The number of written bytes in the buffer.
|
||||
static inline int procfs_getdents(vfs_file_t *file, dirent_t *dirp, off_t doff, size_t count)
|
||||
static inline ssize_t procfs_getdents(vfs_file_t *file, dirent_t *dirp, off_t doff, size_t count)
|
||||
{
|
||||
if (!file || !dirp)
|
||||
return -1;
|
||||
// Check if the size of the buffer is big enough to hold the data about the
|
||||
// directory entry.
|
||||
if (count < sizeof(dirent_t))
|
||||
return -1;
|
||||
// If there are no file, stop right here.
|
||||
if (list_head_empty(&fs.files))
|
||||
return 0;
|
||||
// Find the directory entry.
|
||||
procfs_file_t *direntry = procfs_find_entry_inode(file->ino);
|
||||
if (direntry == NULL) {
|
||||
return -ENOENT;
|
||||
}
|
||||
// Check if it is a directory.
|
||||
if ((direntry->flags & DT_DIR) == 0)
|
||||
return -ENOTDIR;
|
||||
// Clear the buffer.
|
||||
memset(dirp, 0, count);
|
||||
// Initialize, the length of the directory name.
|
||||
int len = strlen(direntry->name);
|
||||
size_t written = 0;
|
||||
off_t current = 0;
|
||||
ssize_t written_size = 0;
|
||||
off_t iterated_size = 0;
|
||||
char *parent = NULL;
|
||||
procfs_file_t *entry;
|
||||
if (!list_head_empty(&fs.files)) {
|
||||
list_for_each_decl(it, &fs.files)
|
||||
{
|
||||
// Get the file structure.
|
||||
entry = procfs_get_file(it);
|
||||
// Check if it a valid procfs file.
|
||||
if (!entry)
|
||||
continue;
|
||||
|
||||
// If the entry is the directory itself, skip.
|
||||
if (strcmp(direntry->name, entry->name) == 0) {
|
||||
continue;
|
||||
}
|
||||
// Get the parent directory.
|
||||
parent = dirname(entry->name);
|
||||
// Check if the entry is inside the directory.
|
||||
if (strcmp(direntry->name, parent) != 0) {
|
||||
continue;
|
||||
}
|
||||
// Skip if already provided.
|
||||
if (current++ < doff) {
|
||||
continue;
|
||||
}
|
||||
if (*(entry->name + len) == '/')
|
||||
++len;
|
||||
// Write on current dirp.
|
||||
dirp->d_ino = entry->inode;
|
||||
dirp->d_type = entry->flags;
|
||||
strcpy(dirp->d_name, entry->name + len);
|
||||
dirp->d_off = sizeof(dirent_t);
|
||||
dirp->d_reclen = sizeof(dirent_t);
|
||||
// Increment the written counter.
|
||||
written += sizeof(dirent_t);
|
||||
// Move to next writing position.
|
||||
dirp += 1;
|
||||
|
||||
if (written >= count)
|
||||
break;
|
||||
// Iterate the filesystem files.
|
||||
list_for_each_decl(it, &fs.files)
|
||||
{
|
||||
// Get the file structure.
|
||||
procfs_file_t *entry = procfs_get_file(it);
|
||||
// Check if it a valid procfs file.
|
||||
if (!entry)
|
||||
continue;
|
||||
// If the entry is the directory itself, skip.
|
||||
if (!strcmp(direntry->name, entry->name))
|
||||
continue;
|
||||
// Get the parent directory.
|
||||
parent = dirname(entry->name);
|
||||
// Check if the parent of the entry is the directory we are iterating.
|
||||
if (strcmp(direntry->name, parent))
|
||||
continue;
|
||||
// Advance the size we just iterated.
|
||||
iterated_size += sizeof(dirent_t);
|
||||
// Check if the iterated size is still below the offset.
|
||||
if (iterated_size < doff) {
|
||||
continue;
|
||||
}
|
||||
// Check if the last character of the entry is a slash.
|
||||
if (*(entry->name + len) == '/')
|
||||
++len;
|
||||
// Write on current dirp.
|
||||
dirp->d_ino = entry->inode;
|
||||
dirp->d_type = entry->flags;
|
||||
strcpy(dirp->d_name, entry->name + len);
|
||||
dirp->d_off = sizeof(dirent_t);
|
||||
dirp->d_reclen = sizeof(dirent_t);
|
||||
// Increment the written counter.
|
||||
written_size += sizeof(dirent_t);
|
||||
// Move to next writing position.
|
||||
++dirp;
|
||||
if (written_size >= count)
|
||||
break;
|
||||
}
|
||||
return written;
|
||||
return written_size;
|
||||
}
|
||||
|
||||
/// @brief Mounts the block device as an EXT2 filesystem.
|
||||
|
||||
@@ -46,7 +46,7 @@ ssize_t sys_read(int fd, void *buf, size_t nbytes)
|
||||
return read;
|
||||
}
|
||||
|
||||
ssize_t sys_write(int fd, void *buf, size_t nbytes)
|
||||
ssize_t sys_write(int fd, const void *buf, size_t nbytes)
|
||||
{
|
||||
// Get the current task.
|
||||
task_struct *task = scheduler_get_current_process();
|
||||
|
||||
+16
-21
@@ -11,45 +11,40 @@
|
||||
#include "stdio.h"
|
||||
#include "fs/vfs.h"
|
||||
#include "string.h"
|
||||
#include "assert.h"
|
||||
|
||||
int sys_getdents(int fd, dirent_t *dirp, unsigned int count)
|
||||
ssize_t sys_getdents(int fd, dirent_t *dirp, unsigned int count)
|
||||
{
|
||||
if (dirp == NULL) {
|
||||
printf("getdents: cannot read directory :"
|
||||
"Directory pointer is not valid\n");
|
||||
return 0;
|
||||
}
|
||||
// Get the current task.
|
||||
task_struct *task = scheduler_get_current_process();
|
||||
|
||||
// Get the current process.
|
||||
task_struct *current_process = scheduler_get_current_process();
|
||||
// Check the current task.
|
||||
assert(current_process && "There is no current process!");
|
||||
// Check the current FD.
|
||||
if (fd < 0 || fd >= task->max_fd) {
|
||||
if ((fd < 0) || (fd >= current_process->max_fd)) {
|
||||
return -EMFILE;
|
||||
}
|
||||
|
||||
// Get the file descriptor.
|
||||
vfs_file_descriptor_t *vfd = &task->fd_list[fd];
|
||||
|
||||
// Check the permissions.
|
||||
// Get the process-specific file descriptor.
|
||||
vfs_file_descriptor_t *process_fd = ¤t_process->fd_list[fd];
|
||||
#if 0
|
||||
if (!(task->fd_list[fd].flags_mask & O_RDONLY)) {
|
||||
// Check the permissions.
|
||||
if (!(current_process->fd_list[fd].flags_mask & O_RDONLY)) {
|
||||
return -EROFS;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Get the file.
|
||||
vfs_file_t *file = vfd->file_struct;
|
||||
// Get the associated file.
|
||||
vfs_file_t *file = process_fd->file_struct;
|
||||
if (file == NULL) {
|
||||
return -ENOSYS;
|
||||
}
|
||||
// Clean the buffer.
|
||||
memset(dirp, 0, count);
|
||||
|
||||
// Perform the read.
|
||||
int actual_read = vfs_getdents(file, dirp, vfd->file_struct->f_pos, count);
|
||||
|
||||
// Update the offset.
|
||||
ssize_t actual_read = vfs_getdents(file, dirp, process_fd->file_struct->f_pos, count);
|
||||
// Update the offset, only if the value the function returns is positive.
|
||||
if (actual_read > 0)
|
||||
vfd->file_struct->f_pos += actual_read;
|
||||
process_fd->file_struct->f_pos += actual_read;
|
||||
return actual_read;
|
||||
}
|
||||
|
||||
+2
-2
@@ -172,7 +172,7 @@ ssize_t vfs_read(vfs_file_t *file, void *buf, size_t offset, size_t nbytes)
|
||||
return file->fs_operations->read_f(file, buf, offset, nbytes);
|
||||
}
|
||||
|
||||
ssize_t vfs_write(vfs_file_t *file, void *buf, size_t offset, size_t nbytes)
|
||||
ssize_t vfs_write(vfs_file_t *file, const void *buf, size_t offset, size_t nbytes)
|
||||
{
|
||||
if (file->fs_operations->write_f == NULL) {
|
||||
pr_err("No WRITE function found for the current filesystem.\n");
|
||||
@@ -190,7 +190,7 @@ off_t vfs_lseek(vfs_file_t *file, off_t offset, int whence)
|
||||
return file->fs_operations->lseek_f(file, offset, whence);
|
||||
}
|
||||
|
||||
int vfs_getdents(vfs_file_t *file, dirent_t *dirp, off_t off, size_t count)
|
||||
ssize_t vfs_getdents(vfs_file_t *file, dirent_t *dirp, off_t off, size_t count)
|
||||
{
|
||||
if (file->fs_operations->getdents_f == NULL) {
|
||||
pr_err("No GETDENTS function found for the current filesystem.\n");
|
||||
|
||||
Reference in New Issue
Block a user