159 lines
3.6 KiB
C
159 lines
3.6 KiB
C
/** @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
|
|
* @return La ligne écrite par l'utilisateur
|
|
*/
|
|
char *read_line() {
|
|
char c;
|
|
int i = 0;
|
|
int j = 1;
|
|
|
|
char *buffer = malloc(j * BUFSIZE * sizeof(char));
|
|
if (buffer == NULL) {
|
|
dprintf(STDERR_FILENO, "Line read buffer allocation error !");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
while (1) {
|
|
c = getchar();
|
|
|
|
if (i == BUFSIZE - 1) {
|
|
j++;
|
|
buffer = realloc(buffer, j * BUFSIZE);
|
|
}
|
|
|
|
if (c == EOF || c == '\n') {
|
|
buffer[i] = '\0';
|
|
return buffer;
|
|
} else {
|
|
buffer[i] = c;
|
|
}
|
|
i++;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief
|
|
* @param char *line la ligne à parser
|
|
* @return la liste des arguments de la commande
|
|
*/
|
|
command **split_line(char *line) {
|
|
char **args = malloc(BUFSIZE * sizeof(char *));
|
|
int i = 0;
|
|
if (args == NULL) {
|
|
dprintf(STDERR_FILENO, "Allocation error");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
char *token = strtok(line, " ");
|
|
|
|
while (token != NULL) {
|
|
args[i] = token;
|
|
i++;
|
|
token = strtok(NULL, " ");
|
|
}
|
|
args[i++] = NULL;
|
|
|
|
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;
|
|
}
|
|
|
|
/**
|
|
* @brief La boucle du shell, elle consiste en trois étapes :
|
|
* - Quand l'utilisateur appui sur entrer pour récupérer son entrée standard
|
|
* - Parser la ligne en fonction de ses espaces
|
|
* - Exécuter la commande demandée
|
|
* @see char* read_line()
|
|
* @see char** split_line(char *line)
|
|
* @see int execute_cmd(char **args)
|
|
*/
|
|
void shell_loop(disk *disk) {
|
|
char *user = get_env_value("USER");
|
|
|
|
if (user == NULL) {
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
char *hostname = get_env_value("HOST");
|
|
|
|
char *line;
|
|
command **args;
|
|
int status = 1;
|
|
|
|
do {
|
|
// ça aussi c'est pas bien, ça sera à changer une fois le sgf fonctionnel
|
|
dprintf(STDOUT_FILENO, "%s@%s %s> ", user, hostname, get_env_value("PWD"));
|
|
line = read_line();
|
|
args = split_line(line);
|
|
status = execute_cmd(disk, args);
|
|
|
|
free(line);
|
|
free(args);
|
|
} while (status);
|
|
}
|
|
|
|
void signal_handler(int sig) {
|
|
(void)sig;
|
|
char *user = get_env_value("USER");
|
|
if (user == NULL) {
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
char *hostname = get_env_value("HOST");
|
|
|
|
dprintf(STDOUT_FILENO, "\n");
|
|
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();
|
|
shell_loop(disk);
|
|
free(envs);
|
|
}
|