Browse Source

Ajout création et suppression ipc

Loquicom 6 years ago
parent
commit
fc243f7e3e
9 changed files with 490 additions and 9 deletions
  1. 2 1
      .gitignore
  2. 1 0
      constante.h
  3. 77 0
      ipc.c
  4. 34 0
      ipc.h
  5. 10 2
      makefile
  6. 17 5
      mysh.c
  7. 1 1
      shm.c
  8. 263 0
      subdiv.c
  9. 85 0
      subdiv.h

+ 2 - 1
.gitignore

@@ -53,4 +53,5 @@ dkms.conf
 /.directory
 /nbproject
 /mysh
-/mysh.log
+/mysh.log
+*.log

+ 1 - 0
constante.h

@@ -10,6 +10,7 @@
 
 /* --- General --- */
 #define BUFFER_SIZE 512
+#define MEM_SIZE 8192
 #define SHELL_ERR -1
 #define SHELL_FAIL 0
 #define SHELL_OK 1

+ 77 - 0
ipc.c

@@ -0,0 +1,77 @@
+/* 
+ * File:   ipc.c
+ * Author: Arthur Brandao
+ *
+ * Created on 21 décembre 2018
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include "ipc.h"
+
+/* --- Extern --- */
+ipc_mysh ipc;
+extern int errno;
+
+/* --- Fonctions publiques --- */
+boolean setup_ipc(char** envp){
+    //boolean setup = true;
+    //SHM pour variable environnement
+    if(!create_shm(&ipc.memoire, SHMCODEMEM, MEM_SIZE)){
+        return false;
+    }
+    //SHM pour gestionnaire variable env
+    if(!create_shm(&ipc.gestionnaire, SHMCODEGEST, sizeof(subdiv))){
+        return false;
+    }
+    //Si creation alors on remplie les segments
+    printf("Errno %d\n", errno != EEXIST);
+    if(errno != EEXIST){
+        subdiv* sd = (subdiv*) ipc.gestionnaire.adr;
+        char* mem = (char*) ipc.memoire.adr;
+        ini_subdiv(sd);
+        int i = 0;
+	while(envp[i] != NULL){
+            add_fdata_subdiv(sd, mem, envp[i]);
+            i++;
+	}
+    }
+    //SHM pour variable globale
+    if(!create_shm(&ipc.global, SHMCODEGLOB, sizeof(int))){
+        return false;
+    }
+    //Semaphore
+    int ini[] = {1, 1, 1};
+    if(!create_sem(&ipc.sem, SEMCODE, 3, ini)){
+        return false;
+    }
+    return true;
+}
+
+boolean end_ipc(){
+    //Detache les shm
+    if(!unset_shm(&ipc.memoire)){
+        return false;
+    }
+    if(!unset_shm(&ipc.gestionnaire)){
+        return false;
+    }
+    if(!unset_shm(&ipc.global)){
+        return false;
+    }
+    //Tente de supprimer shm
+    if(delete_shm(&ipc.global)){
+        //Si on est le dernier processus en vie on supprime tous
+        if(!delete_shm(&ipc.memoire)){
+            return false;
+        }
+        if(!delete_shm(&ipc.gestionnaire)){
+            return false;
+        }
+        if(!delete_sem(&ipc.sem)){
+            return false;
+        }
+    }
+    return true;
+}

+ 34 - 0
ipc.h

@@ -0,0 +1,34 @@
+/* 
+ * File:   ipc.h
+ * Author: Arthur Brandao
+ *
+ * Created on 21 décembre 2018
+ */
+
+#ifndef IPC_H
+#define IPC_H
+
+/* --- Include --- */
+#include "constante.h"
+#include "sem.h"
+#include "shm.h"
+#include "subdiv.h"
+
+/* --- Structure --- */
+typedef struct{
+    shared_mem memoire;
+    shared_mem gestionnaire;
+    shared_mem global;
+    semaphore sem;
+}ipc_mysh;
+
+/* --- Extern --- */
+extern ipc_mysh ipc;
+
+/* --- Fonctions --- */
+boolean setup_ipc(char**);
+
+boolean end_ipc();
+
+#endif /* IPC_H */
+

+ 10 - 2
makefile

@@ -3,7 +3,7 @@
 #
 
 EXEC = mysh
-OBJETS = error.o str.o parser.o wildcard.o command.o execute.o sem.o shm.o
+OBJETS = error.o str.o parser.o wildcard.o command.o execute.o sem.o shm.o subdiv.o ipc.o
 NOM_PROJET = mini-shell
 
 #
@@ -67,6 +67,7 @@ clean:
 	@rm -f *~ *#
 	@rm -f $(EXEC)
 	@rm -f dependances
+	@rm -f *.log
 	@echo "Termine."
 
 depend:
@@ -79,6 +80,11 @@ depend:
 	@cat dependances > makefile
 	@rm dependances
 	@echo "Termine."
+	
+rm-log:
+	@echo "Suppression log..."
+	@rm -f *.log
+	@echo "Termine."
 
 #
 # CREATION ARCHIVE
@@ -101,5 +107,7 @@ command.o: command.c error.h str.h parser.h constante.h mysh.h execute.h \
 execute.o: execute.c error.h execute.h constante.h
 sem.o: sem.c error.h sem.h constante.h
 shm.o: shm.c error.h shm.h constante.h
+subdiv.o: subdiv.c subdiv.h
+ipc.o: ipc.c ipc.h constante.h sem.h shm.h subdiv.h
 mysh.o: mysh.c error.h str.h parser.h constante.h command.h execute.h \
- mysh.h
+ ipc.h sem.h shm.h subdiv.h mysh.h

+ 17 - 5
mysh.c

@@ -19,6 +19,7 @@
 #include "parser.h"
 #include "command.h"
 #include "execute.h"
+#include "ipc.h"
 #include "mysh.h"
 
 /* --- Extern --- */
@@ -140,15 +141,21 @@ int get_tmp_file(){
 }
 
 /* --- Main --- */
-int main(int argc, char* argv[]) {
+int main(int argc, char* argv[], char* envp[]) {
     //Declaration variables
     CommandTab ct;
     int result;
     char line[BUFFER_SIZE], before[BUFFER_SIZE];
     sigset_t sigs_new, sigs_old, sigs_block;
     //Initialisation structures
-    error_finit("mysh.log");
+    error_init();
     ini_pid_list(&pidlist);
+    //Lancement ipc
+    if(!setup_ipc(envp)){
+        error.print("Erreur pendant l'initialisation\n");
+        clean_pid(&pidlist);
+        error.exit_err();
+    }
     //Preparation affichage
     sprintf(before, "\x1b[32m%s:\x1b[36m", getlogin());
     //Traitement des signeaux
@@ -161,14 +168,14 @@ int main(int argc, char* argv[]) {
     }
     //On bloque que sigchld
     result = sigaddset(&sigs_new, SIGCHLD);
-    if(result == -1){
+    if(result == ERR){
 	addperror("Impossible d'ajouter SIGCHLD à l'ensemble de signaux");
         error.print("Erreur pendant l'initialisation\n");
         clean_pid(&pidlist);
         error.exit_err();
     }
     result = sigprocmask(SIG_BLOCK, &sigs_new, &sigs_old);
-    if(result == -1){
+    if(result == -ERR){
 	addperror("Impossible de bloquer les signaux de l'ensemble");
         error.print("Erreur pendant l'initialisation\n");
         clean_pid(&pidlist);
@@ -218,6 +225,7 @@ int main(int argc, char* argv[]) {
         clean_command(&ct);
     }
     //Nettoyage
+    end_ipc();
     clean_pid(&pidlist);
     error.end();
     return EXIT_SUCCESS;
@@ -394,10 +402,13 @@ void handler(int sig){
     }
     //Sinon demande comfirmation pour finir le programme
     while(reponse != 'o' && reponse != 'O' && reponse != 'n' && reponse != 'N'){
+        //Recup la valeur
         printf("Voulez vous vraiment quitter ? [O/N] ");
-        if(scanf("%c", &reponse) == 0){
+        if((reponse = getchar()) == EOF){
             reponse = ' ';
         }
+        //Vide l'entrée standard
+        while(getchar() != '\n');
     }
     //Si oui
     if(reponse == 'n' || reponse == 'N'){
@@ -412,6 +423,7 @@ void handler(int sig){
         pn = pn->next;
     }
     //Termine l'execution
+    end_ipc();
     clean_pid(&pidlist);
     error.exit();
 }

+ 1 - 1
shm.c

@@ -111,7 +111,7 @@ boolean unset_shm(shared_mem* shm){
 boolean delete_shm(shared_mem* shm) {
     /* Regarde si on peut supprimer */
     if(!can_delete_shm(shm)){
-        adderror("Des processus utilise encore le segment");
+        adderror("Des processus utilisent encore le segment");
         return false;
     }
     /* Supprime */

+ 263 - 0
subdiv.c

@@ -0,0 +1,263 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "subdiv.h" 
+
+/* --- Fonctions privées traitement valeurs --- */
+
+boolean is_key(node* n, char* mem, char* key) {
+    int i, length = strlen(key);
+    //Verif que la clef correspond à celle en param
+    for (i = 0; i < length; i++) {
+        if (mem[i + n->start] != key[i]) {
+            return false;
+        }
+    }
+    //Verif que le caractere suivant est bien un =
+    if (mem[i + n->start] != '=') {
+        return false;
+    }
+    return true;
+}
+
+node* find_key(subdiv* sd, char* mem, char* key) {
+    int length = strlen(key) + 2; //Clef + = + taille min mot
+    node* n = NULL;
+    //Cherche la clef
+    for (int i = 0; i < MEM_SIZE / 2; i++) {
+        if (sd->use[i] && sd->mem[i].type == MEMSET && sd->mem[i].length >= length) {
+            //Regarde si la clef correspond
+            if (is_key(&sd->mem[i], mem, key)) {
+                n = &sd->mem[i];
+                break;
+            }
+        }
+    }
+    return n;
+}
+
+char* parse_val(node* n, char* mem) {
+    int pos = 0;
+    //Cherche la postion du =
+    while (mem[pos + n->start] != '=') {
+        pos++;
+    }
+    pos++;
+    //Creation chaine
+    char* str = mem + n->start + pos;
+    char* val = malloc(sizeof (char) * (n->length - pos + 1));
+    memset(val, 0, n->length - pos + 1);
+    strncpy(val, str, n->length - pos);
+    //Retour
+    return val;
+}
+
+/* --- Fonctions privées nodes --- */
+
+boolean div_node(subdiv* sd, node* n) {
+    node* newn = NULL;
+    int i;
+    //Verif que la node à diviser est bien libre
+    if (n->type != MEMEMPTY) {
+        return false;
+    }
+    //Cherche une node libre
+    for (i = 0; i < MEM_SIZE; i++) {
+        if (sd->use[i] == 0) {
+            newn = &sd->mem[i];
+            break;
+        }
+    }
+    //Plus de place
+    if (newn == NULL) {
+        return false;
+    }
+    //Setup node
+    newn->index = i;
+    newn->start = n->start + (n->length / 2);
+    newn->end = n->end;
+    newn->length = n->length / 2;
+    newn->type = MEMEMPTY;
+    newn->prev = n;
+    newn->next = n->next;
+    //Modifie node suivant la nouvelle
+    if (n->next != NULL) {
+        n->next->prev = newn;
+    }
+    //Modifie node origine
+    n->end = n->start + (n->length / 2);
+    n->length /= 2;
+    n->next = newn;
+    //Indique que la node est utilisé
+    sd->use[i] = true;
+    return true;
+}
+
+boolean fusion_node(subdiv* sd, node* n) {
+    //Verif que la node et la node suivante sont vide
+    if (!(n->type == MEMEMPTY && n->next != NULL && n->next->type == MEMEMPTY)) {
+        return false;
+    }
+    node* n2 = n->next;
+    //Verif qu'elles ont la meme taille
+    if (n->length != n2->length) {
+        return false;
+    }
+    //Met à jour la node
+    n->end = n2->end;
+    n->length *= 2;
+    n->next = n2->next;
+    if (n2->next != NULL) {
+        n2->next->prev = n;
+    }
+    //Indique que l'autre node n'est plus utilisée
+    sd->use[n2->index] = false;
+    return true;
+}
+
+/* --- Fonctions publiques --- */
+
+void ini_subdiv(subdiv* sd) {
+    sd->mem[0] = (node){0, 0, MEM_SIZE, MEM_SIZE, MEMEMPTY, NULL, NULL};
+    sd->use[0] = true;
+    for (int i = 1; i < MEM_SIZE / 2; i++) {
+        sd->use[i] = false;
+    }
+}
+
+boolean add_data_subdiv(subdiv* sd, char* mem, char* key, char* data) {
+    //Recup taille data
+    int length = strlen(data) + strlen(key) + 1;
+    //Cherche un espace ou mettre la données
+    node* n = &sd->mem[0];
+    while (n != NULL) {
+        if (n->type == MEMEMPTY && n->length >= length) {
+            break;
+        }
+        n = n->next;
+    }
+    //Si plus de place
+    if (n == NULL) {
+        return false;
+    }
+    //Si on peut diviser par deux la place libre et stocker dedans
+    if ((n->length / 2) >= length) {
+        //On divise la zone en 2
+        if (!div_node(sd, n)) {
+            return false;
+        }
+        return add_data_subdiv(sd, mem, key, data);
+    }
+    //Genere chaine à mettre en mémoire
+    char* str = malloc(sizeof (char) * (length + 1));
+    memset(str, 0, length + 1);
+    snprintf(str, length + 1, "%s=%s", key, data);
+    //On maj la node
+    n->type = MEMSET;
+    n->length = length;
+    //On met dans la mémoire
+    for (int i = 0; i < length; i++) {
+        mem[i + n->start] = str[i];
+    }
+    //Nettoyage
+    free(str);
+    return true;
+}
+
+boolean add_fdata_subdiv(subdiv* sd, char* mem, char* data) {
+    //Recup taille data
+    int length = strlen(data);
+    //Cherche un espace ou mettre la données
+    node* n = &sd->mem[0];
+    while (n != NULL) {
+        if (n->type == MEMEMPTY && n->length >= length) {
+            break;
+        }
+        n = n->next;
+    }
+    //Si plus de place
+    if (n == NULL) {
+        return false;
+    }
+    //Si on peut diviser par deux la place libre et stocker dedans
+    if ((n->length / 2) >= length) {
+        //On divise la zone en 2
+        if (!div_node(sd, n)) {
+            return false;
+        }
+        return add_fdata_subdiv(sd, mem, data);
+    }
+    //On maj la node
+    n->type = MEMSET;
+    n->length = length;
+    //On met dans la mémoire
+    for (int i = 0; i < length; i++) {
+        mem[i + n->start] = data[i];
+    }
+    return true;
+}
+
+char* get_data_subdiv(subdiv* sd, char* mem, char* key) {
+    node* n = find_key(sd, mem, key);
+    //Si pas trouvé la clef
+    if (n == NULL) {
+        return NULL;
+    }
+    //Recup valeur
+    return parse_val(n, mem);
+}
+
+boolean remove_data_subdiv(subdiv* sd, char* mem, char* key) {
+    node* n = find_key(sd, mem, key);
+    //Si pas trouvé la clef
+    if (n == NULL) {
+        return false;
+    }
+    //Marque la node comme vide
+    n->length = n->end - n->start;
+    n->type = MEMEMPTY;
+    //Tente la fusion des noeuds (Algo imparfait)
+    n = &sd->mem[0];
+    while (n != NULL) {
+        //On fusionne avec celui d'après si celui d'avant à une taille différente
+        if (n->prev == NULL) {
+            if (fusion_node(sd, n)) {
+                n = &sd->mem[0];
+            } else {
+                n = n->next;
+            }
+        } else if (n->prev->length != n->length) {
+            if (fusion_node(sd, n)) {
+                n = &sd->mem[0];
+            } else {
+                n = n->next;
+            }
+        } else {
+            n = n->next;
+        }
+    }
+    return true;
+}
+
+void show_subdiv(subdiv* sd) {
+    node* n = &sd->mem[0];
+    while (n != NULL) {
+        printf("Deb : %d, Fin : %d, Length : %d, Real length : %d, Use : %d\n", n->start, n->end, n->length, n->end - n->start, (int) n->type);
+        n = n->next;
+    }
+}
+
+void show_data_subdiv(subdiv* sd, char* mem){
+    node* n = &sd->mem[0];
+    while (n != NULL) {
+        if(n->type == MEMSET){
+            char* str = malloc(sizeof(char) * (n->length + 1));
+            char* deb = mem + n->start;
+            memset(str, 0, n->length + 1);
+            strncpy(str, deb, n->length);
+            printf("%s\n", str);
+            free(str);
+        }
+        n = n->next;
+    }
+}

+ 85 - 0
subdiv.h

@@ -0,0 +1,85 @@
+#ifndef subdiv_h
+#define subdiv_h
+
+/* --- Include --- */
+#include "constante.h"
+
+/* --- Constante --- */
+#define MEMEMPTY 0
+#define MEMSET 1
+
+/* --- Structures --- */
+typedef struct node node;
+struct node{
+	int index; //Index dans le tableau mem de subdiv
+	int start; //Pos debut (incluse)
+	int end; //Pos fin (non incluse)
+	int length; //Taille réellement utilisée
+	unsigned char type;
+	node* prev;
+	node* next;
+};
+
+typedef struct{
+	node mem[MEM_SIZE / 2];
+	boolean use[MEM_SIZE / 2];
+}subdiv;
+
+/* --- Fonctions --- */
+/**
+ * Initialise la structure de gestion
+ * @param subdiv* Le gestionnaire de mémoire par subdivision
+ */
+void ini_subdiv(subdiv*);
+
+/**
+ * Ajoute une donnée dans la mémoire
+ * @param subdiv* Le gestionnaire de mémoire par subdivision
+ * @param char* La mémoire
+ * @param char* La clef
+ * @param char* La valeur
+ * @return Réussite
+ */
+boolean add_data_subdiv(subdiv*, char*, char*, char*);
+
+/**
+ * Ajoute une donnée déjà formatée sour la forme clef=valeur en mémoire
+ * @param subdiv* Le gestionnaire de mémoire par subdivision
+ * @param char* La mémoire
+ * @param char* La donnée
+ * @return Réussite
+ */
+boolean add_fdata_subdiv(subdiv*, char*, char*); //add formated data
+
+/**
+ * Récupère une donnée dans la mémoire
+ * @param subdiv* Le gestionnaire de mémoire par subdivision
+ * @param char* La mémoire
+ * @param char* La clef
+ * @return Réussite
+ */
+char* get_data_subdiv(subdiv*, char*, char*);
+
+/**
+ * Supprime une donnée de la mémoire
+ * @param subdiv* Le gestionnaire de mémoire par subdivision
+ * @param char* La mémoire
+ * @param char* La clef
+ * @return Réussite
+ */
+boolean remove_data_subdiv(subdiv*, char*, char*);
+
+/**
+ * Affiche la répartition de la mémoire
+ * @param subdiv* Le gestionnaire de mémoire par subdivision
+ */
+void show_subdiv(subdiv*);
+
+/**
+ * Affiche toutes les données de la mémoire
+ * @param subdiv* Le gestionnaire de mémoire par subdivision
+ * @param char* La mémoire
+ */
+void show_data_subdiv(subdiv*, char*);
+
+#endif