diff --git a/.vscode/settings.json b/.vscode/settings.json index eba2745..bc67dc0 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -6,6 +6,8 @@ "stdlib.h": "c", "wait.h": "c", "*.bak": "c", - "*.tcc": "c" + "*.tcc": "c", + "errno.h": "c", + "string.h": "c" } } \ No newline at end of file diff --git a/minishell b/minishell index a6d1e3b..a83f702 100755 Binary files a/minishell and b/minishell differ diff --git a/minishell.c b/minishell.c index 6d66e13..a79178e 100644 --- a/minishell.c +++ b/minishell.c @@ -11,15 +11,18 @@ #include #include "readcmd.h" #include "jobs.h" +#include "utils.h" extern int errno; struct cmdline *cmd; -int pid_fils, wait_code; - list jobs; +int pid_fils; +int wait_code; +int builtin_code; + int prompting = 0; jmp_buf goto_prompt; @@ -30,81 +33,6 @@ int file_in, file_out; int pipes[256][2]; int sous_fils[256]; -void handler_sigchld(int sig_num) -{ - do - { - pid_fils = waitpid(-1, &wait_code, WNOHANG | WUNTRACED | WCONTINUED); - if ((pid_fils == -1) && (errno != ECHILD)) - { // wait fail ? - fprintf(stderr, "ERROR: waiting for %d failed, (%d) %s\n", pid_fils, errno, strerror(errno)); - exit(errno); - } - - cell *job = trouver(&jobs, pid_fils); - if (job != NULL) - { - if (prompting) - { - printf("\n"); - } - - if (WIFSTOPPED(wait_code)) - { - printf("[%d] %d stopped: %s\n", job->id, job->pid, job->cmd); - } - else if (WIFCONTINUED(wait_code)) - { - printf("[%d] %d continued: %s\n", job->id, job->pid, job->cmd); - if (!strcmp(cmd->seq[0][0], "fg")) - { - supprimer(&jobs, job->pid); - } - } - else if (WIFEXITED(wait_code)) - { - printf("[%d] %d exited: %s\n", job->id, job->pid, job->cmd); - supprimer(&jobs, job->pid); - } - else if (wait_code == SIGKILL) - { - printf("[%d] %d killed: %s\n", job->id, job->pid, job->cmd); - supprimer(&jobs, job->pid); - } - } - } while (pid_fils > 0); - - if (prompting) - { - siglongjmp(goto_prompt, sig_num); - } -} - -void handler_sigint(int sig_num) -{ - printf("\n"); - if (!prompting) - { - kill(pid_fils, SIGKILL); - pause(); - } - siglongjmp(goto_prompt, sig_num); -} - -void handler_sigtstp(int sig_num) -{ - printf("\n"); - if (!prompting) - { - ajouter(&jobs, pid_fils, *(cmd->seq)); - kill(pid_fils, SIGSTOP); - pause(); - } - siglongjmp(goto_prompt, sig_num); -} - -// TODO handler dans un autre fichier - int main(int argc, char *argv[]) { initialiser(&jobs); @@ -132,101 +60,19 @@ int main(int argc, char *argv[]) cmd = readcmd(); prompting = 0; - // TODO: créer fonction "builtin" ? - // continue ou break en fonction de l'entier de retour - if (cmd == NULL) - { // EOF + builtin_code = builtin(); + if (builtin_code == 1) + { break; } - else if (cmd->err) - { // error from readcmd - fprintf(stderr, "ERROR: readcmd failed, %s\n", cmd->err); + else if (builtin_code == 2) + { continue; } - 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], "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; - } - else if (!strcmp(cmd->seq[0][0], "jobs")) - { // "jobs" - afficher(&jobs); - continue; - } - else if (!strcmp(cmd->seq[0][0], "bg")) - { // "bg" - cell *job; - if (cmd->seq[0][1] == NULL) - { // no id - fprintf(stderr, "ERROR: id missing\n"); - continue; - } - else - { // id specified - job = trouver_id(&jobs, atoi(cmd->seq[0][1])); - } - kill(job->pid, SIGCONT); - pause(); - continue; - } - else if (!strcmp(cmd->seq[0][0], "fg")) - { // "fg" - cell *job; - if (cmd->seq[0][1] == NULL) - { // no id - fprintf(stderr, "ERROR: id missing\n"); - continue; - } - else - { // id specified - job = trouver_id(&jobs, atoi(cmd->seq[0][1])); - pid_fils = job->pid; - } - kill(pid_fils, SIGCONT); - pause(); - waitpid(pid_fils, NULL, 0); - continue; - } - else if (!strcmp(cmd->seq[0][0], "stop")) - { // "stop" - cell *job; - if (cmd->seq[0][1] == NULL) - { // no id - fprintf(stderr, "ERROR: id missing\n"); - continue; - } - else - { // id specified - job = trouver_id(&jobs, atoi(cmd->seq[0][1])); - } - kill(job->pid, SIGSTOP); - pause(); - continue; - } - else if (!strcmp(cmd->seq[0][0], "pid")) - { // "pid" - printf("pid=%d\n", getpid()); - continue; + else if (builtin_code != 0) + { + fprintf(stderr, "ERROR: builtin command failed"); + exit(1); } int nb_pipe = -1; @@ -239,7 +85,7 @@ int main(int argc, char *argv[]) if (nb_pipe < 0) { // counting failed ? fprintf(stderr, "ERROR: counting pipes failed"); - exit(1); + exit(2); } if ((pid_fils = fork()) == -1) diff --git a/utils.c b/utils.c new file mode 100644 index 0000000..baeb338 --- /dev/null +++ b/utils.c @@ -0,0 +1,195 @@ +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "readcmd.h" +#include "jobs.h" + +extern int errno; +extern int pid_fils; +extern int wait_code; +extern int prompting; +extern list jobs; +extern struct cmdline *cmd; +extern jmp_buf goto_prompt; +extern char initcd[]; + +int builtin() +{ + if (cmd == NULL) + { // EOF + return 1; + } + else if (cmd->err) + { // error from readcmd + fprintf(stderr, "ERROR: readcmd failed, %s\n", cmd->err); + return 2; + } + else if (cmd->seq[0] == NULL) + { // empty + return 2; + } + else if (!strcmp(cmd->seq[0][0], "exit")) + { // "exit" + return 1; + } + 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)); + } + return 2; + } + else if (!strcmp(cmd->seq[0][0], "jobs")) + { // "jobs" + afficher(&jobs); + return 2; + } + else if (!strcmp(cmd->seq[0][0], "bg")) + { // "bg" + cell *job; + if (cmd->seq[0][1] == NULL) + { // no id + fprintf(stderr, "ERROR: id missing\n"); + return 2; + } + else + { // id specified + job = trouver_id(&jobs, atoi(cmd->seq[0][1])); + } + kill(job->pid, SIGCONT); + pause(); + return 2; + } + else if (!strcmp(cmd->seq[0][0], "fg")) + { // "fg" + cell *job; + if (cmd->seq[0][1] == NULL) + { // no id + fprintf(stderr, "ERROR: id missing\n"); + return 2; + } + else + { // id specified + job = trouver_id(&jobs, atoi(cmd->seq[0][1])); + pid_fils = job->pid; + } + kill(pid_fils, SIGCONT); + pause(); + waitpid(pid_fils, NULL, 0); + return 2; + } + else if (!strcmp(cmd->seq[0][0], "stop")) + { // "stop" + cell *job; + if (cmd->seq[0][1] == NULL) + { // no id + fprintf(stderr, "ERROR: id missing\n"); + return 2; + } + else + { // id specified + job = trouver_id(&jobs, atoi(cmd->seq[0][1])); + } + kill(job->pid, SIGSTOP); + pause(); + return 2; + } + else if (!strcmp(cmd->seq[0][0], "pid")) + { // "pid" + printf("pid=%d\n", getpid()); + return 2; + } + + return 0; +} + +void handler_sigchld(int sig_num) +{ + do + { + pid_fils = waitpid(-1, &wait_code, WNOHANG | WUNTRACED | WCONTINUED); + if ((pid_fils == -1) && (errno != ECHILD)) + { // wait fail ? + fprintf(stderr, "ERROR: waiting for %d failed, (%d) %s\n", pid_fils, errno, strerror(errno)); + exit(errno); + } + + cell *job = trouver(&jobs, pid_fils); + if (job != NULL) + { + if (prompting) + { + printf("\n"); + } + + if (WIFSTOPPED(wait_code)) + { + printf("[%d] %d stopped: %s\n", job->id, job->pid, job->cmd); + } + else if (WIFCONTINUED(wait_code)) + { + printf("[%d] %d continued: %s\n", job->id, job->pid, job->cmd); + if (!strcmp(cmd->seq[0][0], "fg")) + { + supprimer(&jobs, job->pid); + } + } + else if (WIFEXITED(wait_code)) + { + printf("[%d] %d exited: %s\n", job->id, job->pid, job->cmd); + supprimer(&jobs, job->pid); + } + else if (wait_code == SIGKILL) + { + printf("[%d] %d killed: %s\n", job->id, job->pid, job->cmd); + supprimer(&jobs, job->pid); + } + } + } while (pid_fils > 0); + + if (prompting) + { + siglongjmp(goto_prompt, sig_num); + } +} + +void handler_sigint(int sig_num) +{ + printf("\n"); + if (!prompting) + { + kill(pid_fils, SIGKILL); + pause(); + } + siglongjmp(goto_prompt, sig_num); +} + +void handler_sigtstp(int sig_num) +{ + printf("\n"); + if (!prompting) + { + ajouter(&jobs, pid_fils, *(cmd->seq)); + kill(pid_fils, SIGSTOP); + pause(); + } + siglongjmp(goto_prompt, sig_num); +} diff --git a/utils.h b/utils.h new file mode 100644 index 0000000..1426e3d --- /dev/null +++ b/utils.h @@ -0,0 +1,10 @@ +#ifndef __UTILS_H +#define __UTILS_H + +int builtin(); + +void handler_sigchld(int sig_num); +void handler_sigint(int sig_num); +void handler_sigtstp(int sig_num); + +#endif \ No newline at end of file