Fork TP
This commit is contained in:
commit
88521d3635
8 changed files with 400 additions and 0 deletions
21
Makefile
Normal file
21
Makefile
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
CC=gcc
|
||||||
|
CFLAGS=-Wall -g -Isrc/include
|
||||||
|
|
||||||
|
%: obj/lib.o obj/%.o
|
||||||
|
$(CC) -o $@ $^
|
||||||
|
|
||||||
|
obj/%.o: src/%.c
|
||||||
|
$(CC) $(CFLAGS) $^ -o $@ -c
|
||||||
|
|
||||||
|
obj/lib.o: src/include/mylib.c directories
|
||||||
|
$(CC) $(CFLAGS) $< -o $@ -c
|
||||||
|
|
||||||
|
.PHONY: directories clean
|
||||||
|
|
||||||
|
directories:
|
||||||
|
if ! [ -d "obj" ]; then \
|
||||||
|
mkdir obj; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf obj
|
20
README.md
Normal file
20
README.md
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
# tp-shell
|
||||||
|
|
||||||
|
## Compilation
|
||||||
|
|
||||||
|
Il suffit d’utiliser le make avec un de ces paramètres pour compiler le shell correspondant :
|
||||||
|
|
||||||
|
* shell1 (shell basique où juste une commande simple fonctionne)
|
||||||
|
* shell2 (shell permettant d’entrer une commande avec des paramètres)
|
||||||
|
* shell3 (shell permettant d’entrer deux commandes qui communiqueront tel un pipe)
|
||||||
|
* shellOpt (shell permettant d’utiliser | au lieu de taper la commande en 2 fois)
|
||||||
|
|
||||||
|
À part le shell3, tous les autres utilisent une bibliothèque développée par nos soins, se trouvant dans `src/include` (ne sachant ce qu’est la convention).
|
||||||
|
|
||||||
|
## Bugs
|
||||||
|
|
||||||
|
Lors de nos tests, les shells 1 et 2 marchent bien sauf si l’utilisateur entre plusieurs espaces avant de faire entrer, sans taper aucune commande.
|
||||||
|
|
||||||
|
Le shell 3 fonctionne bien mais a le meme bug que les shell 1 et 2 lorsque l’utilisateur entre plusieurs espaces avant de faire entrer.
|
||||||
|
|
||||||
|
Le shellOpt marche bien avec des commandes ne contenant qu’un pipe, comme `ls | wc-l`. Si l’on rajoute un pipe, le programme le fera marcher avant de planter si on retape une commande. Le exit ne marche pas non plus après plusieurs pipes.
|
82
src/include/mylib.c
Normal file
82
src/include/mylib.c
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "mylib.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Permet de récupérer la commande de l’utilisateur
|
||||||
|
*
|
||||||
|
* @param user_input entrée de l’utilisateur, contiendrat la commande à exécuter
|
||||||
|
*/
|
||||||
|
void get_input(char *user_input)
|
||||||
|
{
|
||||||
|
char *buffer = (char *) malloc(MAX_LENGTH);
|
||||||
|
memset(user_input, 0, MAX_LENGTH);
|
||||||
|
printf("\n> ");
|
||||||
|
fgets(buffer, MAX_LENGTH, stdin);
|
||||||
|
while (buffer[0] == '\n')
|
||||||
|
{
|
||||||
|
printf("\n> ");
|
||||||
|
fgets(buffer, MAX_LENGTH, stdin);
|
||||||
|
}
|
||||||
|
strncpy(user_input, buffer, strlen(buffer)-1);
|
||||||
|
free(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief récupère l’entrée de l’utilisateur et la découpe
|
||||||
|
* selon le caractère passé en paramètre
|
||||||
|
*
|
||||||
|
* @param args Tableau de string qui sera modifié avec
|
||||||
|
* les arguments de la commande
|
||||||
|
* @param find Le caractère à utiliser pour découper la chaine
|
||||||
|
*/
|
||||||
|
void parse_char(char *args[], char find)
|
||||||
|
{
|
||||||
|
char *user_input = (char *) malloc(MAX_LENGTH);
|
||||||
|
get_input(user_input);
|
||||||
|
|
||||||
|
char *token = strtok(user_input, &find);
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
while (token != NULL && i < MAX_LENGTH)
|
||||||
|
{
|
||||||
|
strcpy(args[i], token);
|
||||||
|
i++;
|
||||||
|
token = strtok(NULL, &find);
|
||||||
|
}
|
||||||
|
|
||||||
|
// le dernier argument doit être NULL
|
||||||
|
// car il est vide et provoque une erreur si non NULL
|
||||||
|
free(args[i]);
|
||||||
|
args[i] = NULL;
|
||||||
|
|
||||||
|
free(token);
|
||||||
|
free(user_input);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @brief parse la chaine orig avec les espaces et la met dans le tableau dest
|
||||||
|
* */
|
||||||
|
void tok_space(char *orig, char* dest[])
|
||||||
|
{
|
||||||
|
char find = ' ';
|
||||||
|
|
||||||
|
char *token = strtok(orig, &find);
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
while (token != NULL && i < MAX_LENGTH)
|
||||||
|
{
|
||||||
|
strcpy(dest[i], token);
|
||||||
|
i++;
|
||||||
|
token = strtok(NULL, &find);
|
||||||
|
}
|
||||||
|
|
||||||
|
// le dernier argument doit être NULL
|
||||||
|
// car il est vide et provoque une erreur si non NULL
|
||||||
|
free(dest[i]);
|
||||||
|
dest[i] = NULL;
|
||||||
|
|
||||||
|
free(token);
|
||||||
|
}
|
5
src/include/mylib.h
Normal file
5
src/include/mylib.h
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
#define MAX_LENGTH 200
|
||||||
|
|
||||||
|
void get_input(char *user_input);
|
||||||
|
void parse_char(char *args[], char find);
|
||||||
|
void tok_space(char *args,char *commands[]);
|
30
src/shell1.c
Normal file
30
src/shell1.c
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
|
||||||
|
#include "mylib.h"
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
char *user_input = (char *) malloc(MAX_LENGTH);
|
||||||
|
int result, pid;
|
||||||
|
get_input(user_input);
|
||||||
|
while (strcmp(user_input, "exit"))
|
||||||
|
{
|
||||||
|
pid = fork();
|
||||||
|
|
||||||
|
if (!pid)
|
||||||
|
{
|
||||||
|
execlp(user_input, user_input, NULL);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
wait(&result);
|
||||||
|
|
||||||
|
get_input(user_input);
|
||||||
|
}
|
||||||
|
free(user_input);
|
||||||
|
return 0;
|
||||||
|
}
|
42
src/shell2.c
Normal file
42
src/shell2.c
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
|
||||||
|
#include "mylib.h"
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
int result, pid;
|
||||||
|
char *args[MAX_LENGTH];
|
||||||
|
for (int i = 0; i < MAX_LENGTH; i++)
|
||||||
|
args[i] = (char *) calloc(MAX_LENGTH, sizeof(char));
|
||||||
|
|
||||||
|
parse_char(args, ' ');
|
||||||
|
//get_args(args);
|
||||||
|
while (strcmp(args[0], "exit"))
|
||||||
|
{
|
||||||
|
pid = fork();
|
||||||
|
|
||||||
|
if (!pid)
|
||||||
|
{
|
||||||
|
execvp(args[0], args);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
wait(&result);
|
||||||
|
|
||||||
|
for (int i = 0; i < MAX_LENGTH; i++)
|
||||||
|
{
|
||||||
|
free(args[i]);
|
||||||
|
args[i] = (char *) calloc(MAX_LENGTH, sizeof(char));
|
||||||
|
}
|
||||||
|
//get_args(args);
|
||||||
|
parse_char(args, ' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < MAX_LENGTH; i++)
|
||||||
|
free(args[i]);
|
||||||
|
return 0;
|
||||||
|
}
|
89
src/shell3.c
Normal file
89
src/shell3.c
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
|
||||||
|
#define MAX_LENGTH 200
|
||||||
|
|
||||||
|
char** u_get_input(char* buffer, char* user_input, int i);
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
char *buffer = (char *) malloc(MAX_LENGTH);
|
||||||
|
char *user_input1 = (char *) malloc(MAX_LENGTH);
|
||||||
|
char *user_input2 = (char *) malloc(MAX_LENGTH);
|
||||||
|
int pid1, pid2;
|
||||||
|
int my_pipe[2];
|
||||||
|
int t = pipe(my_pipe);
|
||||||
|
if (t == -1)
|
||||||
|
{
|
||||||
|
printf("erreur à la création du pipe");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
char **args1 = u_get_input(buffer, user_input1, 1);
|
||||||
|
char **args2 = NULL;
|
||||||
|
while (strcmp(user_input1, "exit") != 0)
|
||||||
|
{
|
||||||
|
args2 = u_get_input(buffer, user_input2, 2);
|
||||||
|
pid1 = fork();
|
||||||
|
|
||||||
|
if (!pid1)
|
||||||
|
{
|
||||||
|
dup2(my_pipe[1], STDOUT_FILENO);
|
||||||
|
close(my_pipe[0]);
|
||||||
|
close(my_pipe[1]);
|
||||||
|
execvp(user_input1, args1);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pid2 = fork();
|
||||||
|
|
||||||
|
if (!pid2)
|
||||||
|
{
|
||||||
|
dup2(my_pipe[0], STDIN_FILENO);
|
||||||
|
close(my_pipe[1]);
|
||||||
|
close(my_pipe[0]);
|
||||||
|
execvp(user_input2, args2);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
close(my_pipe[0]);
|
||||||
|
close(my_pipe[1]);
|
||||||
|
waitpid(pid2, NULL, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(args1);
|
||||||
|
free(args2);
|
||||||
|
args1 = u_get_input(buffer, user_input1, 1);
|
||||||
|
pipe(my_pipe);
|
||||||
|
}
|
||||||
|
free(args1);
|
||||||
|
free(buffer);
|
||||||
|
free(user_input1);
|
||||||
|
free(user_input2);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char** u_get_input(char* buffer, char* user_input, int j)
|
||||||
|
{
|
||||||
|
printf("\ncommande%d> ", j);
|
||||||
|
memset(buffer, 0, MAX_LENGTH);
|
||||||
|
memset(user_input, 0, MAX_LENGTH);
|
||||||
|
fgets(buffer, MAX_LENGTH, stdin);
|
||||||
|
strncpy(user_input, buffer, strlen(buffer)-1);
|
||||||
|
|
||||||
|
char *token = strtok(user_input, " ");
|
||||||
|
char **args = (char **) malloc(MAX_LENGTH);
|
||||||
|
int i = 0;
|
||||||
|
while (token != NULL && i < MAX_LENGTH)
|
||||||
|
{
|
||||||
|
args[i] = token;
|
||||||
|
i++;
|
||||||
|
token = strtok(NULL, " ");
|
||||||
|
}
|
||||||
|
return args;
|
||||||
|
}
|
111
src/shellOpt.c
Normal file
111
src/shellOpt.c
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
|
||||||
|
#include "mylib.h"
|
||||||
|
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
int pid;
|
||||||
|
char *args[MAX_LENGTH];
|
||||||
|
char *command[MAX_LENGTH];
|
||||||
|
int my_pipe[2];
|
||||||
|
if (pipe(my_pipe) == -1)
|
||||||
|
{
|
||||||
|
printf("erreur pipe");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < MAX_LENGTH; i++)
|
||||||
|
{
|
||||||
|
args[i] = (char *) calloc(MAX_LENGTH, sizeof(char));
|
||||||
|
command[i] = (char *) calloc(MAX_LENGTH, sizeof(char));
|
||||||
|
}
|
||||||
|
|
||||||
|
parse_char(args, '|');
|
||||||
|
/*
|
||||||
|
int indx = 0;
|
||||||
|
while (args[indx] != NULL)
|
||||||
|
{
|
||||||
|
tok_space(args[indx], command);
|
||||||
|
int i = 0;
|
||||||
|
while (command[i] != NULL)
|
||||||
|
{
|
||||||
|
printf("- %s - ", command[i]);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < MAX_LENGTH; i++)
|
||||||
|
{
|
||||||
|
free(command[i]);
|
||||||
|
command[i] = (char *) calloc(MAX_LENGTH, sizeof(char));
|
||||||
|
}
|
||||||
|
if ( args[indx+1] == NULL )
|
||||||
|
printf("CASSSSSESESESESISRETNRISUT.NR\n");
|
||||||
|
indx++;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
int index = 0;
|
||||||
|
while (strcmp(args[0], "exit"))
|
||||||
|
{
|
||||||
|
if (args[1] != NULL)
|
||||||
|
{
|
||||||
|
while (args[index] != NULL)
|
||||||
|
{
|
||||||
|
pid = fork();
|
||||||
|
if (!pid)
|
||||||
|
{
|
||||||
|
tok_space(args[index], command);
|
||||||
|
if (args[index+1] == NULL)
|
||||||
|
dup2(my_pipe[0], STDIN_FILENO);
|
||||||
|
else if (index == 0)
|
||||||
|
dup2(my_pipe[1], STDOUT_FILENO);
|
||||||
|
/*else {
|
||||||
|
dup2(my_pipe[0], STDIN_FILENO);
|
||||||
|
dup2(my_pipe[1], STDOUT_FILENO);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
close(my_pipe[0]);
|
||||||
|
close(my_pipe[1]);
|
||||||
|
execvp(command[0], command);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (args[index + 1] == NULL)
|
||||||
|
{
|
||||||
|
close(my_pipe[1]);
|
||||||
|
close(my_pipe[0]);
|
||||||
|
//wait(&result);
|
||||||
|
waitpid(pid, NULL, 0);
|
||||||
|
}
|
||||||
|
//waitpid(-1, NULL, 0);
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < MAX_LENGTH; i++)
|
||||||
|
{
|
||||||
|
free(args[i]);
|
||||||
|
free(command[i]);
|
||||||
|
args[i] = (char *) calloc(MAX_LENGTH, sizeof(char));
|
||||||
|
command[i] = (char *) calloc(MAX_LENGTH, sizeof(char));
|
||||||
|
}
|
||||||
|
parse_char(args, '|');
|
||||||
|
pipe(my_pipe);
|
||||||
|
index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < MAX_LENGTH; i++)
|
||||||
|
{
|
||||||
|
free(command[i]);
|
||||||
|
free(args[i]);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue