add: pipe and cmd parsing refacto

This commit is contained in:
Guamss 2026-05-10 13:38:59 +02:00
parent 17b9a67217
commit 61889f25be
6 changed files with 258 additions and 153 deletions

View File

@ -2,7 +2,7 @@
#define BUFSIZE 1024
#define MAX_BLOCS 30
#define MAX_BYTES_PER_BLOC 512
#define MAX_INODE 20
#define MAX_INODE 30
#define MAX_INODE_NAME 28 // 27 caractères + '\0' + numero de l'inode ref
#define TYPE_NULL 0

View File

@ -50,7 +50,7 @@ int find_offset_in_parent_bloc(bloc *parent_bloc) {
}
int is_dir_empty(disk *d, int bloc_index) {
for (int i = 0; i < MAX_BYTES_PER_BLOC; i+= MAX_INODE_NAME + sizeof(int)) {
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) {
@ -103,7 +103,7 @@ int allocate_node(disk *disk, inode *parent, char *name, char type) {
}
int remove_inode(disk *disk, inode *parent, inode *inode_to_remove,
int inode_to_remove_idx) {
int inode_to_remove_idx) {
if (parent == inode_to_remove) {
dprintf(STDERR_FILENO, "rm: can't delete root\n");
@ -140,127 +140,137 @@ int remove_inode(disk *disk, inode *parent, inode *inode_to_remove,
}
int do_rmdir(disk *disk, char *filepath) {
char *parent_path = NULL;
char *dirname = NULL;
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;
}
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, "/");
int parent_index = 0;
char *token = strtok(parent_path, "/");
while (token != NULL) {
parent_index = find_dir_inode_by_name(token, parent_index, disk);
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");
if (parent_index == -1) {
dprintf(STDERR_FILENO, "rmdir: path '%s' does not exist\n", token);
free(parent_path);
free(dirname);
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");
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;
}
persist_on_disk(disk);
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;
}
return (res == 1) ? 0 : -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;
char *parent_path = NULL;
char *dirname = NULL;
if (get_dirname_and_parent_path_by_absolute_path(filepath, &parent_path, &dirname) == -1) {
dprintf(STDERR_FILENO, "rm: erreur de chemin\n");
return -1;
if (get_dirname_and_parent_path_by_absolute_path(filepath, &parent_path,
&dirname) == -1) {
dprintf(STDERR_FILENO, "rm: erreur de chemin\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, "rm: path '%s' does not exist\n", token);
free(parent_path);
free(dirname);
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, "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' is not a directory\n", token);
free(parent_path); free(dirname);
return -1;
}
token = strtok(NULL, "/");
if (disk->inodes[parent_index].filetype != TYPE_DIRECTORY) {
dprintf(STDERR_FILENO, "rm: '%s' is not a directory\n", token);
free(parent_path);
free(dirname);
return -1;
}
int file_index = find_dir_inode_by_name(dirname, parent_index, disk);
token = strtok(NULL, "/");
}
if (file_index == -1) {
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: can't delete '%s': not a file\n", dirname);
free(parent_path); free(dirname);
return -1;
}
int res = remove_inode(disk, &disk->inodes[parent_index], &disk->inodes[file_index], file_index);
if (res == 1) {
} else {
dprintf(STDERR_FILENO, "rm: can't delete because of a fatal error\n");
}
int file_index = find_dir_inode_by_name(dirname, parent_index, disk);
if (file_index == -1) {
dprintf(STDERR_FILENO, "rm: can't delete '%s': no such file\n", dirname);
free(parent_path);
free(dirname);
return -1;
}
persist_on_disk(disk);
if (disk->inodes[file_index].filetype != TYPE_FILE &&
disk->inodes[file_index].filetype != TYPE_SYMBOLIC_LINK) {
dprintf(STDERR_FILENO, "rm: can't delete '%s': not a file\n", dirname);
free(parent_path);
free(dirname);
return -1;
}
return (res == 1) ? 0 : -1;
int res = remove_inode(disk, &disk->inodes[parent_index],
&disk->inodes[file_index], file_index);
if (res == 1) {
} else {
dprintf(STDERR_FILENO, "rm: can't delete because of a fatal error\n");
}
free(parent_path);
free(dirname);
return (res == 1) ? 0 : -1;
}
int create_file(disk *disk, inode *parent, char *filename) {
@ -399,12 +409,13 @@ int get_number_of_inode_left(disk *d) {
int do_df(disk *d) {
int free_blocs = get_number_of_free_blocs(d);
printf(" Free blocs : %i\n", free_blocs);
printf(" Inode left : %i\n", get_number_of_inode_left(d));
// N'est pas la taille réelle à proprement parlé mais plutot l'espace
// possiblement occupable par le reste d'inode sur le disque
printf(" Space left : %.2fKb\n",
(float)(free_blocs * MAX_BYTES_PER_BLOC) / 1000);
int inodes_left = get_number_of_inode_left(d);
float space_left = (float)(free_blocs * MAX_BYTES_PER_BLOC) / 1000;
dprintf(STDOUT_FILENO,
" Free blocs : %i\n Inode left : %i\n Space left : %.2fKb\n",
free_blocs, inodes_left, space_left);
return 0;
}
@ -511,15 +522,14 @@ char *read_in_file(disk *d, int file_index) {
return out;
}
int do_cat(disk *disk, char* path_to_file) {
(void)disk;
(void)path_to_file;
int do_cat(disk *disk, char *path_to_file) {
if (path_to_file == NULL) {
char buffer[4096];
ssize_t bytes_read;
while (fgets(buffer, 4096, stdin)) {
fprintf(stdout, "%s", buffer);
while ((bytes_read = read(STDIN_FILENO, buffer, sizeof(buffer))) > 0) {
write(STDOUT_FILENO, buffer, bytes_read);
}
}
@ -542,7 +552,7 @@ int do_cat(disk *disk, char* path_to_file) {
return -1;
}
printf("%s\n", read_in_file(disk, inode_index));
dprintf(STDOUT_FILENO, "%s\n", read_in_file(disk, inode_index));
return 1;
}
@ -582,8 +592,10 @@ disk create_disk() {
memcpy(&d.blocs[0].datas[MAX_INODE_NAME], &root_inode, sizeof(int));
// création de '..' dans '/'
strncpy(&d.blocs[0].datas[MAX_INODE_NAME + sizeof(int)], "..", MAX_INODE_NAME);
memcpy(&d.blocs[0].datas[2*(MAX_INODE_NAME) + sizeof(int)], &root_inode, sizeof(int));
strncpy(&d.blocs[0].datas[MAX_INODE_NAME + sizeof(int)], "..",
MAX_INODE_NAME);
memcpy(&d.blocs[0].datas[2 * (MAX_INODE_NAME) + sizeof(int)], &root_inode,
sizeof(int));
int test_file_inode = create_file(&d, &d.inodes[0], "test");
write_in_file(&d, test_file_inode, "coucou petit\ntest!!");

View File

@ -1,7 +1,13 @@
/** @file */
#include "exec.h"
#include "disk.h"
#include "struct.h"
#include <stdio.h>
#include <string.h>
#include <unistd.h>
const char *cmd_list[] = {"ls", "touch", "df", "rm", "rmdir",
"cat", "echo", "cd", 0};
int do_cd(disk *d, char *path) {
char full_path[1024] = {0};
@ -33,7 +39,7 @@ int do_cd(disk *d, char *path) {
int do_echo(char **args) {
if (args[0] == NULL) {
printf("\n");
dprintf(STDOUT_FILENO, "\n");
return 1;
}
@ -77,11 +83,11 @@ int do_echo(char **args) {
}
result[pos] = '\0';
printf("%s\n", result);
dprintf(STDOUT_FILENO, "%s\n", result);
return 1;
}
int child_process_job(disk *d, char **args) {
int exec_cmd_job(disk *d, char **args) {
if (strcmp("ls", args[0]) == 0) {
do_ls(d, args[1]);
} else if (strcmp("mkdir", args[0]) == 0) {
@ -94,42 +100,74 @@ int child_process_job(disk *d, char **args) {
do_df(d);
} else if (strcmp("rm", args[0]) == 0) {
do_rm(d, args[1]);
persist_on_disk(d);
} else if (strcmp("rmdir", args[0]) == 0) {
do_rmdir(d, args[1]);
} else if(strcmp("cat", args[0]) == 0) {
persist_on_disk(d);
} else if (strcmp("cat", args[0]) == 0) {
do_cat(d, args[1]);
} else {
dprintf(STDERR_FILENO, "%s: no such command\n", args[0]);
dprintf(STDERR_FILENO, "%s: command does not exist\n", args[0]);
return 0;
}
return 1;
}
int execute_cmd(disk *d, char **args) {
int spawn_proc(disk *d, int in, int out, command *cmd) {
int pid;
// cas ou l'utilisateur fait CTRD+D
if (args[0] == NULL) {
printf("\n");
if ((pid = fork()) == 0) {
signal(SIGINT, SIG_DFL);
if (out != STDOUT_FILENO) {
dup2(out, STDOUT_FILENO);
close(out);
}
if (in != STDIN_FILENO) {
dup2(in, STDIN_FILENO);
close(in);
}
return exec_cmd_job(d, cmd->argv);
}
return pid;
}
int execute_cmd(disk *d, command **args) {
// cas ou l'utilisateur fait CTRD+D
if (args == NULL) {
dprintf(STDOUT_FILENO, "\n");
exit(EXIT_SUCCESS);
}
if (strcmp(args[0], "cd") == 0) {
return do_cd(d, args[1]);
} else if (strcmp(args[0], "echo") == 0) {
return do_echo(&args[1]);
int args_len = 0;
for (args_len = 0; args[args_len] != NULL; args_len++)
;
int i;
int in, p[2];
in = 0;
for (i = 0; i < args_len - 2; i++) {
pipe(p);
spawn_proc(d, in, p[1], args[i]);
close(p[1]);
in = p[0];
}
int pid = fork();
spawn_proc(d, in, STDOUT_FILENO, args[i]);
if (pid == 1) {
return -1;
if (in != 0) {
close(in);
}
if (pid == 0) {
signal(SIGINT, SIG_DFL);
return child_process_job(d, args);
} else {
int status;
waitpid(pid, &status, WUNTRACED);
}
return 1;
int status;
while (waitpid(-1, &status, WUNTRACED) > 0)
;
return status;
}

View File

@ -13,5 +13,4 @@
#include <sys/wait.h>
#include <ctype.h>
int is_builtin_cmd(char *executable);
int execute_cmd(disk *d, char **args);
int execute_cmd(disk *d, command **args);

View File

@ -1,19 +1,24 @@
/** @file */
#include "parsing.h"
#include "disk.h"
#include "exec.h"
#include "struct.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
/**
* @brief Attend que l'utilisateur appuie sur entrée pour récupérer la ligne écrite
* puis la renvoi
* @brief Attend que l'utilisateur appuie sur entrée pour récupérer la ligne
* écrite puis la renvoi
* @return La ligne écrite par l'utilisateur
*/
char *read_line() {
char c;
int i = 0;
// buffer overflow attention
char *buffer = malloc(BUFSIZE * sizeof(char));
int j = 1;
char *buffer = malloc(j * BUFSIZE * sizeof(char));
if (buffer == NULL) {
dprintf(STDERR_FILENO, "Line read buffer allocation error !");
exit(EXIT_FAILURE);
@ -22,6 +27,11 @@ char *read_line() {
while (1) {
c = getchar();
if (i == BUFSIZE - 1) {
j++;
buffer = realloc(buffer, j * BUFSIZE);
}
if (c == EOF || c == '\n') {
buffer[i] = '\0';
return buffer;
@ -29,17 +39,15 @@ char *read_line() {
buffer[i] = c;
}
i++;
// TODO: realoc quand le buffer est dépassé
}
}
/**
* @brief Sépare une ligne par des espaces (pour la ligne "ls -l" ça va renvoyer {"ls",
* "-l"})
* @brief
* @param char *line la ligne à parser
* @return la liste des arguments de la commande
*/
char **split_line(char *line) {
command **split_line(char *line) {
char **args = malloc(BUFSIZE * sizeof(char *));
int i = 0;
if (args == NULL) {
@ -56,7 +64,43 @@ char **split_line(char *line) {
}
args[i++] = NULL;
return args;
if (args[0] == NULL) {
return NULL;
}
command **cmd_lines = malloc(sizeof(command *));
if (cmd_lines == NULL) {
dprintf(STDERR_FILENO, "Command struct allocation error !");
exit(EXIT_FAILURE);
}
cmd_lines[0] = malloc(sizeof(command));
cmd_lines[0]->argv = malloc(sizeof(char *));
i = 0;
int idx_cmd = 0;
int nbr_args_in_actual_cmd = 0;
while (args[i] != NULL) {
if (strcmp(args[i], "|") == 0) {
cmd_lines[idx_cmd]->argv[nbr_args_in_actual_cmd + 1] = NULL;
idx_cmd++;
cmd_lines[idx_cmd] = malloc(sizeof(command));
cmd_lines[idx_cmd]->argv = malloc(sizeof(char *));
nbr_args_in_actual_cmd = 0;
} else {
cmd_lines[idx_cmd]->argv =
realloc(cmd_lines[idx_cmd]->argv,
(nbr_args_in_actual_cmd + 1) * sizeof(char *));
cmd_lines[idx_cmd]->argv[nbr_args_in_actual_cmd] = strdup(args[i]);
nbr_args_in_actual_cmd++;
}
i++;
}
cmd_lines[idx_cmd + 1] = malloc(sizeof(command));
cmd_lines[idx_cmd + 1] = NULL;
return cmd_lines;
}
/**
@ -78,7 +122,7 @@ void shell_loop(disk *disk) {
char *hostname = get_env_value("HOST");
char *line;
char **args;
command **args;
int status = 1;
do {
@ -105,10 +149,10 @@ void signal_handler(int sig) {
dprintf(STDOUT_FILENO, "%s@%s %s> ", user, hostname, get_env_value("PWD"));
}
void open_seyshell(disk* disk) {
signal(SIGINT, signal_handler); // le processus père ne s'arrête pas quand il y a un SIGINT = sigma boy
env* envs = init_envs();
void open_seyshell(disk *disk) {
signal(SIGINT, signal_handler); // le processus père ne s'arrête pas quand il
// y a un SIGINT = sigma boy
env *envs = init_envs();
shell_loop(disk);
free(envs);
}

View File

@ -37,4 +37,16 @@ typedef struct disk {
} disk;
// pour 10 inode qui a 30 blocs de chacun 1024 octets, on a 30720 octets, soit
// 30,7 Ko sur le disque
// 30,7 Ko sur le disque
typedef struct command {
char **argv;
} command;
/*
ce structure de cette façon :
commands[0].argv[0]: ls
commands[0].argv[1]: -l
commands[1].argv[0]: head
commands[2].argv[0]: tail
commands[2].argv[1]: -4
*/