|
@@ -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);
|