diff --git a/minishell b/minishell index 367476a..4ef753f 100755 Binary files a/minishell and b/minishell differ diff --git a/minishell.c b/minishell.c index 8df7cf8..5efdfe7 100644 --- a/minishell.c +++ b/minishell.c @@ -11,182 +11,187 @@ #include "readcmd.h" #include "jobs.h" -int prompting = 0; -int job_id = 1; -list jobs; -pid_t pidFils; +extern int errno; + struct cmdline *cmd; -jmp_buf start; +int pid_fils; -void handler_print(int signal_num, siginfo_t *info) +int job_id = 0; +list jobs; + +int prompting = 0; +jmp_buf goto_prompt; + +char initcd[256], currentcd[256]; + + + +void handler_sigchld(int sig_num, siginfo_t *info) { - cell* job = trouver(&jobs, info->si_pid); + 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 proccess actuellement + { printf("\n"); } - printf("[%d] (%d) done: %s\n", job->id, job->pid, job->cmd); + printf("[%d] %d done: %s\n", job->id, job->pid, job->cmd); supprimer(&jobs, job->pid); job_id--; if (prompting) - { // on réaffiche un prompt si besoin - siglongjmp(start, signal_num); + { + siglongjmp(goto_prompt, sig_num); } } } -void handler_restart(int signal_num) + + +void handler_sigint(int sig_num) { printf("\n"); - siglongjmp(start, signal_num); + siglongjmp(goto_prompt, sig_num); } -void handler_stop(int signal_num) + + +void handler_sigtstp(int sig_num) { if (!prompting) { - kill(pidFils, SIGTSTP); - ajouter(&jobs, pidFils, job_id++, *(cmd->seq), 1); - printf("[%d] (%d) suspended: %s\n", job_id, pidFils, *(cmd->seq)); - siglongjmp(start, signal_num); + kill(pid_fils, SIGTSTP); + ajouter(&jobs, pid_fils, ++job_id, *(cmd->seq), 1); + printf("[%d] %d suspended\n", job_id, pid_fils); + siglongjmp(goto_prompt, sig_num); } else { - handler_restart(signal_num); + handler_sigint(sig_num); } } + + +void handler_sigcont(int sig_num) +{ + +} + + int main(int argc, char *argv[]) { - extern int errno; - initialiser(&jobs); + getcwd(initcd, sizeof(initcd)); // gestion des signaux struct sigaction action; sigemptyset(&action.sa_mask); action.sa_flags = SA_SIGINFO | SA_RESTART; - action.sa_handler = handler_print; + action.sa_handler = handler_sigchld; sigaction(SIGCHLD, &action, NULL); - action.sa_handler = handler_restart; + action.sa_handler = handler_sigint; sigaction(SIGINT, &action, NULL); - action.sa_handler = handler_stop; + action.sa_handler = handler_sigtstp; sigaction(SIGTSTP, &action, NULL); - // variables pour afficher le path - char initcd[256], currentcd[256]; - getcwd(initcd, 256); - // loop principal while (1) { - if (sigsetjmp(start, 1) == 2) - { // si on provient du jump - continue; - } - - getcwd(currentcd, 256); - printf("%s >>> ", currentcd); + sigsetjmp(goto_prompt, 1); prompting = 1; + getcwd(currentcd, sizeof(currentcd)); + printf("%s >>> ", currentcd); cmd = readcmd(); prompting = 0; if (cmd == NULL) - { // on quitte le shell, EOF + { // EOF break; } else if (cmd->seq[0] == NULL) - { // ligne vide, on skip - continue; - } - else if (!strcmp(cmd->seq[0][0], "bg")) - { - kill(pidFils, SIGCONT); + { // empty continue; } else if (!strcmp(cmd->seq[0][0], "exit")) - { + { // "exit" break; } + else if (!strcmp(cmd->seq[0][0], "jobs")) + { // "jobs" + afficher(&jobs); + continue; + } else if (!strcmp(cmd->seq[0][0], "cd")) - { // cd + { // "cd" int ret = 0; if (cmd->seq[0][1] == NULL) - { // vide, sans path + { // no path ret = chdir(initcd); } else - { // avec un path + { // with path ret = chdir(cmd->seq[0][1]); } if (ret) - { // si le path n'existe pas + { // wrong path fprintf(stderr, "ERROR: cd failed, (%d) %s\n", errno, strerror(errno)); } continue; } - else if (!strcmp(cmd->seq[0][0], "jobs")) - { // on affiche tous les process de fond - afficher(&jobs); - continue; - } - pidFils = fork(); - - if (pidFils == -1) - { // si le fork échoue + pid_fils = fork(); + if (pid_fils == -1) + { // fork fail ? fprintf(stderr, "ERROR: forking failed, (%d) %s\n", errno, strerror(errno)); exit(errno); } - if (pidFils == 0) + if (pid_fils == 0) { // instructions du fils + action.sa_handler = SIG_DFL; + sigaction(SIGTSTP, &action, NULL); // on default SIGTSTP + sigaction(SIGCONT, &action, NULL); // on default SIGCONT + if (cmd->backgrounded) - { + { // background action.sa_handler = SIG_IGN; sigaction(SIGINT, &action, NULL); // on ignore SIGINT + sigaction(SIGTSTP, &action, NULL); // on ignore SIGTSTP + } + 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) - { // on sauvegarde le pid, si background - ajouter(&jobs, pidFils, job_id++, *(cmd->seq), 0); - printf("[%d] %d\n", job_id, pidFils); + { // background + ajouter(&jobs, pid_fils, ++job_id, *(cmd->seq), 0); + printf("[%d] %d\n", job_id, pid_fils); } else - { // on attend le fils, si foreground - int codeTerm; - pid_t idFils = waitpid(pidFils, &codeTerm, 0); // on attend la fin de l'exec du fils + { // foreground + int wait_code; + pid_t id_fils = waitpid(pid_fils, &wait_code, 0); // on attend la fin de l'exec du fils - if (idFils == -1) - { // si le wait fail - fprintf(stderr, "ERROR: waiting for %d failed, (%d) %s\n", codeTerm, errno, strerror(errno)); + if (id_fils == -1) + { // wait fail ? + fprintf(stderr, "ERROR: waiting for %d failed, (%d) %s\n", wait_code, errno, strerror(errno)); exit(errno); } - if (codeTerm) - { // si l'exec a échoué - fprintf(stderr, "ERROR: %d's execution failed, (%d) %s\n", pidFils, codeTerm, strerror(codeTerm)); + if (wait_code) + { // execvp fail ? + fprintf(stderr, "ERROR: %d's execution failed, (%d) %s\n", pid_fils, wait_code, strerror(wait_code)); } } } } - liberer(&jobs); return EXIT_SUCCESS; } \ No newline at end of file diff --git a/minishell.c.bak b/minishell.c.bak new file mode 100644 index 0000000..8df7cf8 --- /dev/null +++ b/minishell.c.bak @@ -0,0 +1,192 @@ +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include +#include "readcmd.h" +#include "jobs.h" + +int prompting = 0; +int job_id = 1; +list jobs; +pid_t pidFils; +struct cmdline *cmd; + +jmp_buf start; + +void handler_print(int signal_num, siginfo_t *info) +{ + 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 proccess actuellement + printf("\n"); + } + + printf("[%d] (%d) done: %s\n", job->id, job->pid, job->cmd); + supprimer(&jobs, job->pid); + job_id--; + + if (prompting) + { // on réaffiche un prompt si besoin + siglongjmp(start, signal_num); + } + } +} + +void handler_restart(int signal_num) +{ + printf("\n"); + siglongjmp(start, signal_num); +} + +void handler_stop(int signal_num) +{ + if (!prompting) + { + kill(pidFils, SIGTSTP); + 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); + } +} + +int main(int argc, char *argv[]) +{ + extern int errno; + + initialiser(&jobs); + + // gestion des signaux + struct sigaction action; + sigemptyset(&action.sa_mask); + action.sa_flags = SA_SIGINFO | SA_RESTART; + action.sa_handler = handler_print; + sigaction(SIGCHLD, &action, NULL); + action.sa_handler = handler_restart; + sigaction(SIGINT, &action, NULL); + action.sa_handler = handler_stop; + sigaction(SIGTSTP, &action, NULL); + + // variables pour afficher le path + char initcd[256], currentcd[256]; + getcwd(initcd, 256); + + // loop principal + while (1) + { + if (sigsetjmp(start, 1) == 2) + { // si on provient du jump + continue; + } + + getcwd(currentcd, 256); + printf("%s >>> ", currentcd); + + prompting = 1; + cmd = readcmd(); + prompting = 0; + + if (cmd == NULL) + { // on quitte le shell, EOF + break; + } + else if (cmd->seq[0] == NULL) + { // ligne vide, on skip + continue; + } + else if (!strcmp(cmd->seq[0][0], "bg")) + { + kill(pidFils, SIGCONT); + continue; + } + else if (!strcmp(cmd->seq[0][0], "exit")) + { + break; + } + else if (!strcmp(cmd->seq[0][0], "cd")) + { // cd + int ret = 0; + if (cmd->seq[0][1] == NULL) + { // vide, sans path + ret = chdir(initcd); + } + else + { // avec un path + ret = chdir(cmd->seq[0][1]); + } + if (ret) + { // si le path n'existe pas + fprintf(stderr, "ERROR: cd failed, (%d) %s\n", errno, strerror(errno)); + } + continue; + } + else if (!strcmp(cmd->seq[0][0], "jobs")) + { // on affiche tous les process de fond + afficher(&jobs); + continue; + } + + pidFils = fork(); + + if (pidFils == -1) + { // si le fork échoue + fprintf(stderr, "ERROR: forking failed, (%d) %s\n", errno, strerror(errno)); + exit(errno); + } + + if (pidFils == 0) + { // instructions du fils + if (cmd->backgrounded) + { + 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) + { // on sauvegarde le pid, si background + ajouter(&jobs, pidFils, job_id++, *(cmd->seq), 0); + printf("[%d] %d\n", job_id, pidFils); + } + else + { // on attend le fils, si foreground + int codeTerm; + pid_t idFils = waitpid(pidFils, &codeTerm, 0); // on attend la fin de l'exec du fils + + if (idFils == -1) + { // si le wait fail + fprintf(stderr, "ERROR: waiting for %d failed, (%d) %s\n", codeTerm, errno, strerror(errno)); + exit(errno); + } + + if (codeTerm) + { // si l'exec a échoué + fprintf(stderr, "ERROR: %d's execution failed, (%d) %s\n", pidFils, codeTerm, strerror(codeTerm)); + } + } + } + } + + liberer(&jobs); + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/minishell2 b/minishell2 deleted file mode 100755 index ddf8075..0000000 Binary files a/minishell2 and /dev/null differ diff --git a/minishell2.c b/minishell2.c deleted file mode 100644 index ca2a181..0000000 --- a/minishell2.c +++ /dev/null @@ -1,155 +0,0 @@ -#define _GNU_SOURCE - -#include -#include -#include -#include -#include -#include -#include -#include -#include "readcmd.h" -#include "jobs.h" - -extern int errno; - -struct cmdline *cmd; - -int pid_fils; - -int job_id = 0; -list jobs; - -int prompting = 0; -jmp_buf goto_prompt; - -char initcd[256], currentcd[256]; - - - -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); - getcwd(initcd, sizeof(initcd)); - - // 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; - getcwd(currentcd, sizeof(currentcd)); - printf("%s >>> ", currentcd); - 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; - } - else if (!strcmp(cmd->seq[0][0], "jobs")) - { // "jobs" - afficher(&jobs); - continue; - } - else if (!strcmp(cmd->seq[0][0], "cd")) - { // "cd" - int ret = 0; - if (cmd->seq[0][1] == NULL) - { // no path - ret = chdir(initcd); - } - else - { // with path - ret = chdir(cmd->seq[0][1]); - } - if (ret) - { // wrong path - fprintf(stderr, "ERROR: cd failed, (%d) %s\n", errno, strerror(errno)); - } - continue; - } - - 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