Browse Source

Fin commande en fond

Loquicom 6 years ago
parent
commit
65aa236221
6 changed files with 57 additions and 7 deletions
  1. 2 1
      command.c
  2. 2 1
      command.h
  3. 46 4
      mysh.c
  4. 1 1
      mysh.h
  5. 5 0
      parser.c
  6. 1 0
      parser.h

+ 2 - 1
command.c

@@ -28,9 +28,10 @@ void ini_pid_list(pid_list* pl) {
     pl->last = NULL;
 }
 
-pid_node* add_pid(pid_list* pl, pid_t pid) {
+pid_node* add_pid(pid_list* pl, pid_t pid, int job) {
     pid_node* pn = malloc(sizeof (pid_node));
     pn->pid = pid;
+    pn->job = job;
     pn->next = NULL;
     if (pl->first == NULL) {
         pn->prev = NULL;

+ 2 - 1
command.h

@@ -16,6 +16,7 @@
 typedef struct pid_node pid_node;
 struct pid_node{
     pid_t pid;
+    int job;
     pid_node* prev;
     pid_node* next;
 };
@@ -30,7 +31,7 @@ extern boolean exitsh;
 
 /* --- Fonctions --- */
 void ini_pid_list(pid_list*);
-pid_node* add_pid(pid_list*, pid_t);
+pid_node* add_pid(pid_list*, pid_t, int);
 pid_node* search_pid(pid_list*, pid_t);
 void remove_pid(pid_list*, pid_node*);
 void clean_pid(pid_list*);

+ 46 - 4
mysh.c

@@ -11,7 +11,9 @@
 #include <unistd.h>
 #include <fcntl.h>
 #include <sys/stat.h>
+#include <sys/types.h>
 #include <wait.h>
+#include <signal.h>
 #include "error.h"
 #include "str.h"
 #include "parser.h"
@@ -26,6 +28,7 @@ extern boolean exitsh;
 /* --- Global --- */
 pid_list pidlist;
 pid_node* active = NULL;
+int job = 1;
 
 /* --- Fonctions privées --- */
 void test_write() {
@@ -138,13 +141,43 @@ int main(int argc, char* argv[]) {
     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");
     ini_pid_list(&pidlist);
     //Preparation affichage
     sprintf(before, "\x1b[32m%s:\x1b[36m", getlogin());
+    //Traitement des signeaux
+    result = sigemptyset(&sigs_new);
+    if(result == ERR){	
+	addperror("Impossible de récuperer un ensemble de signaux vide");
+        error.print("Erreur pendant l'initialisation\n");
+        clean_pid(&pidlist);
+        error.exit_err();
+    }
+    //On bloque que sigchld
+    result = sigaddset(&sigs_new, SIGCHLD);
+    if(result == -1){
+	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){
+	addperror("Impossible de bloquer les signaux de l'ensemble");
+        error.print("Erreur pendant l'initialisation\n");
+        clean_pid(&pidlist);
+        error.exit_err();
+    }
     //Boucle infini de lecture
     while(!exitsh){
+        //On regarde si un fils en fond est mort
+	if(sigpending(&sigs_block) == ERR){
+            addperror("Impossible de recuperer les signaux en attentes");
+	} else if(sigismember(&sigs_block, SIGCHLD)){
+            job--;
+	}
         //Affichage repertoire
         show_current_dir(before, ">\x1b[0m ");      
         //Lecture ligne
@@ -174,7 +207,7 @@ int main(int argc, char* argv[]) {
             continue;
         }
         //Execute
-        result = run(ct);
+        result = run(ct, NULL);
         printf("Result : %d\n", result);
         //Vide le resultat du parse de la ligne de commande
         clean_command(&ct);
@@ -185,7 +218,7 @@ int main(int argc, char* argv[]) {
     return EXIT_SUCCESS;
 }
 
-int run(CommandTab ct){
+int run(CommandTab ct, int* status){
     pid_t pid;
     int result = 0;
     //Si en fond creation d'un fork pour executer les commandes
@@ -199,15 +232,20 @@ int run(CommandTab ct){
         }
         //Fils
         if(pid == 0){
+            int stat = 0;
             ct.bck = 0;
-            result = run(ct);
+            result = run(ct, &stat);
+            //Message de fin + retour
             if(result == SHELL_FAIL){
+                printf("\n%s (jobs=[%d], pid=%d) terminée avec status=-1\n", ct.line, job, getpid());
                 exit(EXIT_FAILURE);
             }
+            printf("\n%s (jobs=[%d], pid=%d) terminée avec status=%d\n", ct.line, job, getpid(), stat);
             exit(EXIT_SUCCESS);
         }
+        printf("[%d] %d\n", job, pid);
         //Ajout du fils dans la liste des pid
-        add_pid(&pidlist, pid);
+        add_pid(&pidlist, pid, job++);
         //Pour le pere c'est fini
         return SHELL_OK;
     }
@@ -277,6 +315,10 @@ int run(CommandTab ct){
         } else {
             result = exec_shell(c->name, c->argv);
         }
+        //Si on a une variable pour stocker le status de retoure
+        if(status != NULL){
+            *status = result;
+        }
         //Reset IO
         if(c->input != STDIN){
             infd = redirect_fd(STDIN, infd);

+ 1 - 1
mysh.h

@@ -21,7 +21,7 @@ void show_current_dir(const char*, const char*);
  * @param CommandTab La ligne de commande parser
  * @return 
  */
-int run(CommandTab);
+int run(CommandTab, int*);
 
 #endif /* MYSH_H */
 

+ 5 - 0
parser.c

@@ -525,6 +525,10 @@ int parse_line(CommandTab* ct, char* line){
         return SHELL_ERR;
     }
     //Initialisation structure
+    tmp = strlen(line);
+    ct->line = malloc(sizeof(char) * (tmp + 1));
+    memset(ct->line, 0, tmp + 1);
+    strncpy(ct->line, line, tmp);
     ct->cmd = malloc(sizeof(Command*) * compteur);
     ct->length = compteur;
     ct->bck = line[strlen(line) - 1] == '&';
@@ -634,4 +638,5 @@ void clean_command(CommandTab* ct){
     }
     //Met à 0 la taille du tableau
     ct->length = 0;
+    free(ct->line);
 }

+ 1 - 0
parser.h

@@ -24,6 +24,7 @@ typedef struct {
 } Command;
 
 typedef struct {
+    char* line; //La ligne de commande
     Command** cmd; //Tableau avec toutes les commandes
     int length; //Taille du tableau
     boolean bck; //Si l'ensemble de commande se fait en fond