diff --git a/jobs.c b/jobs.c index a78ccc7..f86a8e7 100644 --- a/jobs.c +++ b/jobs.c @@ -3,128 +3,113 @@ #include #include "jobs.h" -void ajouter(list *l_ptr, int pid, int id, char **seq) +void ajouter(list *l_ptr, int pid, int id, char **seq, int state) { - cell *new_cell = malloc(sizeof(*new_cell)); + cell *new_cell = malloc(sizeof(*new_cell)); - char *cmd; - cmd = malloc(sizeof(char) * 256); - cmd[0] = '\0'; + char *cmd; + cmd = malloc(sizeof(char) * 256); + cmd[0] = '\0'; - while (*seq) - { - strcat(cmd, *seq); - seq++; - strcat(cmd, " "); - } + while (*seq) + { + strcat(cmd, *seq); + seq++; + strcat(cmd, " "); + } - new_cell->pid = pid; - new_cell->id = id; - new_cell->cmd = cmd; + new_cell->pid = pid; + new_cell->id = id; + new_cell->cmd = cmd; + new_cell->state = state; - if (*l_ptr == NULL) - { - new_cell->next = NULL; - } - else - { - new_cell->next = *l_ptr; - } + if (*l_ptr == NULL) + { + new_cell->next = NULL; + } + else + { + new_cell->next = *l_ptr; + } - *l_ptr = new_cell; - - printf("[%d] %d %s\n", id, pid, cmd); + *l_ptr = new_cell; } void supprimer(list *l_ptr, int pid) { - cell *cursor = *l_ptr; + cell *cursor = *l_ptr; - if (cursor->pid == pid) - { - cell *cursor2free = cursor; - *l_ptr = cursor->next; - printf("[%d] (%d) done: %s\n", cursor->id, cursor->pid, cursor->cmd); - free(cursor2free); - } - else - { - while (cursor->next != NULL) + if (cursor->pid == pid) { - if (cursor->next->pid == pid) - { - break; - } - else - { - cursor = cursor->next; - } + cell *cursor2free = cursor; + *l_ptr = cursor->next; + free(cursor2free); + } + else + { + while (cursor->next != NULL) + { + if (cursor->next->pid == pid) + { + break; + } + else + { + cursor = cursor->next; + } + } + cell *cursor_next = cursor->next->next; + free(cursor->next); + cursor->next = cursor_next; } - cell *cursor_next = cursor->next->next; - printf("[%d] (%d) done: %s\n", cursor->id, cursor->pid, cursor->cmd); - free(cursor->next); - cursor->next = cursor_next; - } } void afficher(list *l_ptr) { - cell *cursor = *l_ptr; + cell *cursor = *l_ptr; - while (cursor != NULL) - { - printf("[%d] %d\n", cursor->id, cursor->pid); - cursor = cursor->next; - } + while (cursor != NULL) + { + printf("[%d] %d\n", cursor->id, cursor->pid); + cursor = cursor->next; + } } void initialiser(list *l_ptr) { - *l_ptr = NULL; + *l_ptr = NULL; } void liberer(list *l_ptr) { - free(*l_ptr); - *l_ptr = NULL; -} - -int est_vide(list l_ptr) -{ - return l_ptr == NULL; -} - -int contiens(list *l_ptr, int pid) -{ - cell *cursor = *l_ptr; - - while (cursor != NULL) - { - if (cursor->pid == pid) + cell* cursor2free; + cell* cursor = *l_ptr; + while (cursor != NULL) { - return 1; + cursor2free = cursor; + cursor = cursor->next; + free(cursor2free); } - cursor = cursor->next; - } - return 0; + free(*l_ptr); + *l_ptr = NULL; } cell *trouver(list *l_ptr, int pid) { - cell *cursor = *l_ptr; + cell *cursor = *l_ptr; - while (cursor != NULL) - { - if (cursor->pid == pid) + while (cursor != NULL) { - return cursor; + if (cursor->pid == pid) + { + return cursor; + } + cursor = cursor->next; } - cursor = cursor->next; - } - return NULL; // erreur + return NULL; // erreur } \ No newline at end of file diff --git a/jobs.h b/jobs.h index 2b54d0a..e843816 100644 --- a/jobs.h +++ b/jobs.h @@ -8,16 +8,16 @@ struct cell int pid; char *cmd; cell *next; + int state; }; typedef cell *list; -void ajouter(cell **list, int pid, int id, char **cmd); +void ajouter(cell **list, int pid, int id, char **cmd, int state); void supprimer(cell **list, int pid); void afficher(cell **list); void initialiser(list *list); void liberer(list *list); -int contiens(list *l_ptr, int pid); cell *trouver(list *l_ptr, int pid); #endif \ No newline at end of file diff --git a/minishell b/minishell index f94d9cf..367476a 100755 Binary files a/minishell and b/minishell differ diff --git a/minishell.c b/minishell.c index f9a49fd..8df7cf8 100644 --- a/minishell.c +++ b/minishell.c @@ -21,14 +21,22 @@ jmp_buf start; void handler_print(int signal_num, siginfo_t *info) { - if (contiens(&jobs, info->si_pid)) - { // pid dans la lsite des proccess en fond + cell* job = trouver(&jobs, info->si_pid); + if (job) + { // pid dans la lite des proccess en fond + if (job->state) + { + job->state = 0; + siglongjmp(start, signal_num); + } + if (prompting) - { // si il n'y a pas d'execution de procces actuellement + { // si il n'y a pas d'execution de proccess actuellement printf("\n"); } - supprimer(&jobs, info->si_pid); + printf("[%d] (%d) done: %s\n", job->id, job->pid, job->cmd); + supprimer(&jobs, job->pid); job_id--; if (prompting) @@ -38,34 +46,34 @@ void handler_print(int signal_num, siginfo_t *info) } } -void handler_restart(int signal_num, siginfo_t *info) +void handler_restart(int signal_num) { printf("\n"); siglongjmp(start, signal_num); } -void handler_stop(int signal_num, siginfo_t *info) +void handler_stop(int signal_num) { if (!prompting) { kill(pidFils, SIGTSTP); - ajouter(&jobs, pidFils, job_id++, *(cmd->seq)); + ajouter(&jobs, pidFils, job_id++, *(cmd->seq), 1); + printf("[%d] (%d) suspended: %s\n", job_id, pidFils, *(cmd->seq)); siglongjmp(start, signal_num); } else { - handler_restart(signal_num, info); + handler_restart(signal_num); } } int main(int argc, char *argv[]) { - extern int errno; initialiser(&jobs); - // gestion de SIGCHLD + // gestion des signaux struct sigaction action; sigemptyset(&action.sa_mask); action.sa_flags = SA_SIGINFO | SA_RESTART; @@ -76,7 +84,7 @@ int main(int argc, char *argv[]) action.sa_handler = handler_stop; sigaction(SIGTSTP, &action, NULL); - // variables de "pwd" + // variables pour afficher le path char initcd[256], currentcd[256]; getcwd(initcd, 256); @@ -157,7 +165,8 @@ int main(int argc, char *argv[]) { // instructions du père if (cmd->backgrounded) { // on sauvegarde le pid, si background - ajouter(&jobs, pidFils, job_id++, *(cmd->seq)); + ajouter(&jobs, pidFils, job_id++, *(cmd->seq), 0); + printf("[%d] %d\n", job_id, pidFils); } else { // on attend le fils, si foreground @@ -178,5 +187,6 @@ int main(int argc, char *argv[]) } } + liberer(&jobs); return EXIT_SUCCESS; } \ No newline at end of file diff --git a/minishell2 b/minishell2 new file mode 100755 index 0000000..c5e00cb Binary files /dev/null and b/minishell2 differ diff --git a/minishell2.c b/minishell2.c new file mode 100644 index 0000000..fdf7aa9 --- /dev/null +++ b/minishell2.c @@ -0,0 +1,122 @@ +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include +#include "readcmd.h" +#include "jobs.h" + +struct cmdline *cmd; +int pid_fils; +int job_id = 0; +list jobs; +int prompting = 0; +jmp_buf goto_prompt; + +void handler_sigchld(int signal_num, siginfo_t *info) +{ + cell *job = trouver(&jobs, info->si_pid); + if (job) + { + if (prompting) + { + printf("\n"); + } + + printf("[%d] (%d) done: %s\n", job->id, job->pid, job->cmd); + supprimer(&jobs, job->pid); + job_id--; + + if (prompting) + { + siglongjmp(goto_prompt, signal_num); + } + } +} + +int main(int argc, char *argv[]) +{ + initialiser(&jobs); + + extern int errno; + + // gestion des signaux + struct sigaction action; + sigemptyset(&action.sa_mask); + action.sa_flags = SA_SIGINFO | SA_RESTART; + action.sa_handler = handler_sigchld; + sigaction(SIGCHLD, &action, NULL); + + // loop principal + while (1) + { + sigsetjmp(goto_prompt, 1); + + prompting = 1; + printf(">>> "); + cmd = readcmd(); + prompting = 0; + + if (cmd == NULL) + { // EOF + break; + } + else if (cmd->seq[0] == NULL) + { // empty + continue; + } + else if (!strcmp(cmd->seq[0][0], "exit")) + { // "exit" + break; + } + + pid_fils = fork(); + if (pid_fils == -1) + { // fork fail ? + fprintf(stderr, "ERROR: forking failed, (%d) %s\n", errno, strerror(errno)); + exit(errno); + } + + if (pid_fils == 0) + { // instructions du fils + if (cmd->backgrounded) + { // background + action.sa_handler = SIG_IGN; + sigaction(SIGINT, &action, NULL); // on ignore SIGINT + } + execvp(cmd->seq[0][0], cmd->seq[0]); + exit(errno); // si execlp échoue on exit avec une erreur + } + else + { // instructions du père + if (cmd->backgrounded) + { // background + ajouter(&jobs, pid_fils, ++job_id, *(cmd->seq), 0); + printf("[%d] %d\n", job_id, pid_fils); + } + else + { // foreground + int wait_code; + pid_t id_fils = waitpid(pid_fils, &wait_code, 0); // on attend la fin de l'exec du fils + + if (id_fils == -1) + { // wait fail ? + fprintf(stderr, "ERROR: waiting for %d failed, (%d) %s\n", wait_code, errno, strerror(errno)); + exit(errno); + } + + if (wait_code) + { // execvp fail ? + fprintf(stderr, "ERROR: %d's execution failed, (%d) %s\n", pid_fils, wait_code, strerror(wait_code)); + } + } + } + } + + return EXIT_SUCCESS; +} \ No newline at end of file