From 5b67775c825e9238bc648f4ee57a460a3599db5b Mon Sep 17 00:00:00 2001 From: Guamss Date: Thu, 7 May 2026 17:43:51 +0200 Subject: [PATCH] add: rmdir --- src/const.h | 2 +- src/disk.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++----- src/disk.h | 1 + src/exec.c | 4 ++- 4 files changed, 96 insertions(+), 11 deletions(-) diff --git a/src/const.h b/src/const.h index 0a5b522..1fcac87 100644 --- a/src/const.h +++ b/src/const.h @@ -12,4 +12,4 @@ #define COLOR_BLUE "\x1b[34m" #define COLOR_GREEN "\x1b[32m" -#define ESCAPE_COLOR "\x1b[0m" \ No newline at end of file +#define ESCAPE_COLOR "\x1b[0m" diff --git a/src/disk.c b/src/disk.c index b65f619..02bb0af 100644 --- a/src/disk.c +++ b/src/disk.c @@ -49,6 +49,26 @@ int find_offset_in_parent_bloc(bloc *parent_bloc) { return -1; } +int is_dir_empty(disk *d, int bloc_index) { + for (int i = 0; i < MAX_BYTES_PER_BLOC; i+= MAX_INODE_NAME + sizeof(int)) { + char name[MAX_INODE_NAME]; + strncpy(name, &d->blocs[bloc_index].datas[i], MAX_INODE_NAME); + if (strcmp(name, "..") != 0 && strcmp(name, ".") != 0 && name[0] != 0) { + return 0; + } + } + return 1; +} + +int is_file_empty(disk *d, int bloc_index) { + for (int i = 0; i < MAX_BYTES_PER_BLOC; i++) { + if (d->blocs[bloc_index].datas[i] != 0) { + return 0; + } + } + return 1; +} + int allocate_node(disk *disk, inode *parent, char *name, char type) { int inode_index = 0; while (inode_index < MAX_INODE && @@ -82,7 +102,7 @@ int allocate_node(disk *disk, inode *parent, char *name, char type) { return inode_index; } -int remove_file(disk *disk, inode *parent, inode *inode_to_remove, +int remove_inode(disk *disk, inode *parent, inode *inode_to_remove, int inode_to_remove_idx) { if (parent == inode_to_remove) { @@ -96,7 +116,7 @@ int remove_file(disk *disk, inode *parent, inode *inode_to_remove, int found = 0; - // on efface la référence du fichier dans son parent + // on efface la référence de l'inode dans son parent for (int i = 0; i < MAX_BYTES_PER_BLOC && !found; i += MAX_INODE_NAME + sizeof(int)) { if (*(int *)&disk->blocs[parent_bloc_idx].datas[i + MAX_INODE_NAME] == @@ -107,7 +127,7 @@ int remove_file(disk *disk, inode *parent, inode *inode_to_remove, } } - // on efface tout le contenu du fichier + // on efface tout le contenu de l'inode int bloc_inode_idx = inode_to_remove->blocs[0]; memset(&disk->blocs[bloc_inode_idx].datas[0], 0, MAX_BYTES_PER_BLOC); @@ -119,6 +139,68 @@ int remove_file(disk *disk, inode *parent, inode *inode_to_remove, return 1; } +int do_rmdir(disk *disk, char *filepath) { + char *parent_path = NULL; + char *dirname = NULL; + + if (get_dirname_and_parent_path_by_absolute_path(filepath, &parent_path, &dirname) == -1) { + dprintf(STDERR_FILENO, "rmdir: path error\n"); + return -1; + } + + int parent_index = 0; + char *token = strtok(parent_path, "/"); + + while (token != NULL) { + parent_index = find_dir_inode_by_name(token, parent_index, disk); + + if (parent_index == -1) { + dprintf(STDERR_FILENO, "rmdir: path '%s' does not exist\n", token); + free(parent_path); free(dirname); + return -1; + } + + if (disk->inodes[parent_index].filetype != TYPE_DIRECTORY) { + dprintf(STDERR_FILENO, "rmdir: '%s' is not a directory\n", token); + free(parent_path); free(dirname); + return -1; + } + + token = strtok(NULL, "/"); + } + + int file_index = find_dir_inode_by_name(dirname, parent_index, disk); + + if (file_index == -1) { + dprintf(STDERR_FILENO, "rmdir: can't delete '%s': no such directory\n", dirname); + free(parent_path); free(dirname); + return -1; + } + + if (disk->inodes[file_index].filetype != TYPE_DIRECTORY) { + dprintf(STDERR_FILENO, "rmdir: can't delete '%s': not a directory\n", dirname); + free(parent_path); free(dirname); + return -1; + } + + if (!(is_dir_empty(disk, disk->inodes[file_index].blocs[0]) == 1)) { + dprintf(STDERR_FILENO, "rmdir: directory not empty\n"); + return -1; + } + + int res = remove_inode(disk, &disk->inodes[parent_index], &disk->inodes[file_index], file_index); + + if (res == 1) { + } else { + dprintf(STDERR_FILENO, "rmdir: can't delete because of a fatal error\n"); + } + + free(parent_path); + free(dirname); + + return (res == 1) ? 0 : -1; +} + int do_rm(disk *disk, char *filepath) { char *parent_path = NULL; char *dirname = NULL; @@ -135,13 +217,13 @@ int do_rm(disk *disk, char *filepath) { parent_index = find_dir_inode_by_name(token, parent_index, disk); if (parent_index == -1) { - dprintf(STDERR_FILENO, "rm: le chemin '%s' n'existe pas\n", token); + dprintf(STDERR_FILENO, "rm: path '%s' does not exist\n", token); free(parent_path); free(dirname); return -1; } if (disk->inodes[parent_index].filetype != TYPE_DIRECTORY) { - dprintf(STDERR_FILENO, "rm: '%s' n'est pas un dossier\n", token); + dprintf(STDERR_FILENO, "rm: '%s' is not a directory\n", token); free(parent_path); free(dirname); return -1; } @@ -152,23 +234,23 @@ int do_rm(disk *disk, char *filepath) { int file_index = find_dir_inode_by_name(dirname, parent_index, disk); if (file_index == -1) { - dprintf(STDERR_FILENO, "rm: impossible de supprimer '%s': Aucun fichier de ce nom\n", dirname); + dprintf(STDERR_FILENO, "rm: can't delete '%s': no such file\n", dirname); free(parent_path); free(dirname); return -1; } if (disk->inodes[file_index].filetype != TYPE_FILE && disk->inodes[file_index].filetype != TYPE_SYMBOLIC_LINK) { - dprintf(STDERR_FILENO, "rm: impossible de supprimer '%s': est un dossier\n", dirname); + dprintf(STDERR_FILENO, "rm: can't delete '%s': not a file\n", dirname); free(parent_path); free(dirname); return -1; } - int res = remove_file(disk, &disk->inodes[parent_index], &disk->inodes[file_index], file_index); + int res = remove_inode(disk, &disk->inodes[parent_index], &disk->inodes[file_index], file_index); if (res == 1) { } else { - dprintf(STDERR_FILENO, "rm: erreur fatale lors de la suppression en mémoire\n"); + dprintf(STDERR_FILENO, "rm: can't delete because of a fatal error\n"); } free(parent_path); diff --git a/src/disk.h b/src/disk.h index bd183b9..0ca9807 100644 --- a/src/disk.h +++ b/src/disk.h @@ -19,5 +19,6 @@ int do_touch(disk *d, char *filepath); int do_mkdir(disk* d, char *dirpath); int do_df(disk *d); int do_rm(disk *disk, char *filepath); +int do_rmdir(disk *disk, char *filepath); int find_dir_inode_by_name(char *name, int dir_index, disk *d); void persist_on_disk(disk* d); \ No newline at end of file diff --git a/src/exec.c b/src/exec.c index 4c9f370..fd926c1 100644 --- a/src/exec.c +++ b/src/exec.c @@ -100,7 +100,9 @@ int child_process_job(disk *d, char **args) { do_df(d); } else if (strcmp("rm", args[0]) == 0) { do_rm(d, args[1]); - }else { + } else if (strcmp("rmdir", args[0]) == 0) { + do_rmdir(d, args[1]); + } else { dprintf(STDERR_FILENO, "%s: no such command\n", args[0]); } return 1;