diff --git a/.testms b/.testms deleted file mode 100644 index 53ecffa..0000000 --- a/.testms +++ /dev/null @@ -1,114 +0,0 @@ -/home/laurent/Documents/Cours/ENSEEIHT/S6 - Systèmes d'Exploitation Centralisés/projet >>> bonjour, je suis un message vert de debug -/home/laurent/Documents/Cours/ENSEEIHT/S6 - Systèmes d'Exploitation Centralisés/projet >>> à zipper -jobs.c -jobs.h -latex -Makefile -minishell -minishell.c -readcmd.c -readcmd.h -README.md -sujet.pdf -test1 -test.sh -utils.c -utils.h -/home/laurent/Documents/Cours/ENSEEIHT/S6 - Systèmes d'Exploitation Centralisés/projet >>> total 276K -drwxr-xr-x 6 laurent laurent 4.0K May 23 18:53 . -drwxrwxrwx 9 laurent laurent 4.0K May 5 08:07 .. -drwxr-xr-x 2 laurent laurent 4.0K May 23 16:32 à zipper -drwxr-xr-x 8 laurent laurent 4.0K May 23 16:28 .git --rw-r--r-- 1 laurent laurent 2.6K May 23 18:12 jobs.c --rw-r--r-- 1 laurent laurent 403 May 23 16:22 jobs.h -drwxr-xr-x 4 laurent laurent 4.0K Apr 25 20:56 latex --rw-r--r-- 1 laurent laurent 205 May 10 15:49 Makefile --rwxr-xr-x 1 laurent laurent 27K May 23 18:53 minishell --rw-r--r-- 1 laurent laurent 7.2K May 23 18:51 minishell.c --rwxr-xr-x 1 laurent laurent 5.0K Apr 21 14:03 readcmd.c --rwxr-xr-x 1 laurent laurent 2.2K May 23 16:24 readcmd.h --rwxr-xr-x 1 laurent laurent 2.1K Apr 13 10:42 README.md --rw-r--r-- 1 laurent laurent 163K Apr 25 20:25 sujet.pdf --rw-r--r-- 1 laurent laurent 1.9K May 23 16:41 test1 --rw-r--r-- 1 laurent laurent 452 May 23 18:53 .testms --rw-r--r-- 1 laurent laurent 2.3K May 23 18:26 test.sh --rw-r--r-- 1 laurent laurent 4.6K May 23 18:09 utils.c --rw-r--r-- 1 laurent laurent 165 May 23 16:22 utils.h -drwxr-xr-x 2 laurent laurent 4.0K Apr 20 21:34 .vscode -/home/laurent/Documents/Cours/ENSEEIHT/S6 - Systèmes d'Exploitation Centralisés/projet >>> -rwxr-xr-x 1 laurent laurent 27K May 23 18:53 minishell --rw-r--r-- 1 laurent laurent 7.2K May 23 18:51 minishell.c -/home/laurent/Documents/Cours/ENSEEIHT/S6 - Systèmes d'Exploitation Centralisés/projet >>> 2 18 116 -/home/laurent/Documents/Cours/ENSEEIHT/S6 - Systèmes d'Exploitation Centralisés/projet >>> -rw-r--r-- 1 laurent laurent 1.9K May 23 16:41 test1 -drwxr-xr-x 6 laurent laurent 4.0K May 23 18:53 . -drwxrwxrwx 9 laurent laurent 4.0K May 5 08:07 .. --rwxr-xr-x 1 laurent laurent 5.0K Apr 21 14:03 readcmd.c --rw-r--r-- 1 laurent laurent 7.2K May 23 18:51 minishell.c --rw-r--r-- 1 laurent laurent 2.6K May 23 18:12 jobs.c --rw-r--r-- 1 laurent laurent 4.6K May 23 18:09 utils.c --rwxr-xr-x 1 laurent laurent 2.1K Apr 13 10:42 README.md -drwxr-xr-x 2 laurent laurent 4.0K Apr 20 21:34 .vscode --rw-r--r-- 1 laurent laurent 205 May 10 15:49 Makefile --rw-r--r-- 1 laurent laurent 163K Apr 25 20:25 sujet.pdf --rwxr-xr-x 1 laurent laurent 2.2K May 23 16:24 readcmd.h --rw-r--r-- 1 laurent laurent 403 May 23 16:22 jobs.h --rw-r--r-- 1 laurent laurent 165 May 23 16:22 utils.h --rw-r--r-- 1 laurent laurent 2.3K May 23 18:26 test.sh -total 276K --rwxr-xr-x 1 laurent laurent 27K May 23 18:53 minishell -drwxr-xr-x 2 laurent laurent 4.0K May 23 16:32 à zipper --rw-r--r-- 1 laurent laurent 2.0K May 23 18:53 .testms -drwxr-xr-x 8 laurent laurent 4.0K May 23 16:28 .git -drwxr-xr-x 4 laurent laurent 4.0K Apr 25 20:56 latex -/home/laurent/Documents/Cours/ENSEEIHT/S6 - Systèmes d'Exploitation Centralisés/projet >>> -/home/laurent/Documents/Cours/ENSEEIHT/S6 - Systèmes d'Exploitation Centralisés/projet >>> -/home/laurent/Documents/Cours/ENSEEIHT/S6 - Systèmes d'Exploitation Centralisés/projet >>> -/home/laurent/Documents/Cours/ENSEEIHT/S6 - Systèmes d'Exploitation Centralisés/projet >>> [1] 30197 -/home/laurent/Documents/Cours/ENSEEIHT/S6 - Systèmes d'Exploitation Centralisés/projet >>> [2] 30200 -/home/laurent/Documents/Cours/ENSEEIHT/S6 - Systèmes d'Exploitation Centralisés/projet >>> [3] 30203 -/home/laurent/Documents/Cours/ENSEEIHT/S6 - Systèmes d'Exploitation Centralisés/projet >>> [4] 30206 -/home/laurent/Documents/Cours/ENSEEIHT/S6 - Systèmes d'Exploitation Centralisés/projet >>> [5] 30209 -/home/laurent/Documents/Cours/ENSEEIHT/S6 - Systèmes d'Exploitation Centralisés/projet >>> [6] 30212 -/home/laurent/Documents/Cours/ENSEEIHT/S6 - Systèmes d'Exploitation Centralisés/projet >>> [7] 30215 -/home/laurent/Documents/Cours/ENSEEIHT/S6 - Systèmes d'Exploitation Centralisés/projet >>> [8] 30218 -/home/laurent/Documents/Cours/ENSEEIHT/S6 - Systèmes d'Exploitation Centralisés/projet >>> [9] 30221 -/home/laurent/Documents/Cours/ENSEEIHT/S6 - Systèmes d'Exploitation Centralisés/projet >>> [10] 30224 -/home/laurent/Documents/Cours/ENSEEIHT/S6 - Systèmes d'Exploitation Centralisés/projet >>> [11] 30227 -/home/laurent/Documents/Cours/ENSEEIHT/S6 - Systèmes d'Exploitation Centralisés/projet >>> [8] 30218 stopped: sleep 12 -/home/laurent/Documents/Cours/ENSEEIHT/S6 - Systèmes d'Exploitation Centralisés/projet >>> [1] 30197 running: sleep 5 - -[1] 30197 stopped: sleep 5 -/home/laurent/Documents/Cours/ENSEEIHT/S6 - Systèmes d'Exploitation Centralisés/projet >>> [1] 30197 continued: sleep 5 -/home/laurent/Documents/Cours/ENSEEIHT/S6 - Systèmes d'Exploitation Centralisés/projet >>> [1] 30197 : sleep 5 -[2] 30200 : sleep 6 -[3] 30203 : sleep 7 -[4] 30206 : sleep 8 -[5] 30209 : sleep 9 -[6] 30212 : sleep 10 -[7] 30215 : sleep 11 -[8] 30218 : sleep 12 -[9] 30221 : sleep 13 -[10] 30224 : sleep 14 -[11] 30227 : sleep 15 -/home/laurent/Documents/Cours/ENSEEIHT/S6 - Systèmes d'Exploitation Centralisés/projet >>> /home/laurent/Documents/Cours/ENSEEIHT/S6 - Systèmes d'Exploitation Centralisés/projet -/home/laurent/Documents/Cours/ENSEEIHT/S6 - Systèmes d'Exploitation Centralisés/projet >>> /home/laurent/Documents/Cours/ENSEEIHT/S6 - Systèmes d'Exploitation Centralisés >>> /home/laurent/Documents/Cours/ENSEEIHT/S6 - Systèmes d'Exploitation Centralisés -/home/laurent/Documents/Cours/ENSEEIHT/S6 - Systèmes d'Exploitation Centralisés >>> -[1] 30197 exited: sleep 5 -/home/laurent/Documents/Cours/ENSEEIHT/S6 - Systèmes d'Exploitation Centralisés >>> -[2] 30200 exited: sleep 6 -/home/laurent/Documents/Cours/ENSEEIHT/S6 - Systèmes d'Exploitation Centralisés >>> -[3] 30203 exited: sleep 7 -/home/laurent/Documents/Cours/ENSEEIHT/S6 - Systèmes d'Exploitation Centralisés >>> -[4] 30206 exited: sleep 8 -/home/laurent/Documents/Cours/ENSEEIHT/S6 - Systèmes d'Exploitation Centralisés >>> -[5] 30209 exited: sleep 9 -/home/laurent/Documents/Cours/ENSEEIHT/S6 - Systèmes d'Exploitation Centralisés >>> -[6] 30212 exited: sleep 10 -/home/laurent/Documents/Cours/ENSEEIHT/S6 - Systèmes d'Exploitation Centralisés >>> -[7] 30215 exited: sleep 11 -/home/laurent/Documents/Cours/ENSEEIHT/S6 - Systèmes d'Exploitation Centralisés >>> -[9] 30221 exited: sleep 13 -/home/laurent/Documents/Cours/ENSEEIHT/S6 - Systèmes d'Exploitation Centralisés >>> -[10] 30224 exited: sleep 14 -/home/laurent/Documents/Cours/ENSEEIHT/S6 - Systèmes d'Exploitation Centralisés >>> -[11] 30227 exited: sleep 15 -/home/laurent/Documents/Cours/ENSEEIHT/S6 - Systèmes d'Exploitation Centralisés >>> \ No newline at end of file diff --git a/Makefile b/Makefile index 1c56a03..e4cd28a 100644 --- a/Makefile +++ b/Makefile @@ -1,15 +1,34 @@ CC = gcc -LDFLAGS = -Wall +LDFLAGS = -Wall -g -all: minishell +all: minishell Q1 Q3 Q4 Q5 Q6 Q7 -minishell: jobs.c readcmd.c minishell.c +minishell: utils.c jobs.c readcmd.c minishell.c + $(CC) $(LDFLAGS) $^ -o $@ + +Q1: jobs.c readcmd.c Q1.c + $(CC) $(LDFLAGS) $^ -o $@ + +Q3: jobs.c readcmd.c Q3.c + $(CC) $(LDFLAGS) $^ -o $@ + +Q4: jobs.c readcmd.c Q4.c + $(CC) $(LDFLAGS) $^ -o $@ + +Q5: jobs.c readcmd.c Q5.c + $(CC) $(LDFLAGS) $^ -o $@ + +Q6: jobs.c readcmd.c Q6.c + $(CC) $(LDFLAGS) $^ -o $@ + +Q7: jobs.c readcmd.c Q7.c $(CC) $(LDFLAGS) $^ -o $@ clean: - rm minishell readcmd jobs + rm minishell readcmd jobs utils Q1 Q3 Q4 Q5 Q6 Q7 .PHONY: clean all readcmd.o: readcmd.h jobs.o: jobs.h +utils.o: utils.h diff --git a/latex/notes.fdb_latexmk b/latex/notes.fdb_latexmk index 6db7508..3d50007 100644 --- a/latex/notes.fdb_latexmk +++ b/latex/notes.fdb_latexmk @@ -1,8 +1,8 @@ # Fdb version 3 -["pdflatex"] 1619376891 "/home/laurent/Documents/Cours/ENSEEIHT/S6 - Systèmes d'Exploitation Centralisés/projet/latex/notes.tex" "/home/laurent/Documents/Cours/ENSEEIHT/S6 - Systèmes d'Exploitation Centralisés/projet/latex/notes.pdf" "notes" 1619376893 - "/dev/null" 1619348936 0 d41d8cd98f00b204e9800998ecf8427e "" - "/home/laurent/Documents/Cours/ENSEEIHT/S6 - Systèmes d'Exploitation Centralisés/projet/latex/notes.aux" 1619376893 845 467bc9a0de3c71bf18b9a0157f8def98 "" - "/home/laurent/Documents/Cours/ENSEEIHT/S6 - Systèmes d'Exploitation Centralisés/projet/latex/notes.tex" 1619376890 1910 342138058897a9344f648b92cf61941b "" +["pdflatex"] 1621881898 "/home/laurent/Documents/Cours/ENSEEIHT/S6 - Systèmes d'Exploitation Centralisés/projet/latex/notes.tex" "/home/laurent/Documents/Cours/ENSEEIHT/S6 - Systèmes d'Exploitation Centralisés/projet/latex/notes.pdf" "notes" 1621881900 + "/dev/null" 1621880663 0 d41d8cd98f00b204e9800998ecf8427e "" + "/home/laurent/Documents/Cours/ENSEEIHT/S6 - Systèmes d'Exploitation Centralisés/projet/latex/notes.aux" 1621881899 845 467bc9a0de3c71bf18b9a0157f8def98 "" + "/home/laurent/Documents/Cours/ENSEEIHT/S6 - Systèmes d'Exploitation Centralisés/projet/latex/notes.tex" 1621881897 2038 d0c24313d6481f7788145d1bee0004c8 "" "/usr/share/texmf-dist/fonts/enc/dvips/cm-super/cm-super-t1.enc" 1616952564 2971 def0b6c1f0b107b3b936def894055589 "" "/usr/share/texmf-dist/fonts/map/fontname/texfonts.map" 1616952564 3524 cb3e574dea2d1052e39280babc910dc8 "" "/usr/share/texmf-dist/fonts/tfm/jknappen/ec/ecbx2074.tfm" 1616952564 3584 7666d038713b9e38abb5c2e0f6972188 "" @@ -108,16 +108,16 @@ "/usr/share/texmf-dist/tex/latex/upquote/upquote.sty" 1607185936 1048 517e01cde97c1c0baf72e69d43aa5a2e "" "/usr/share/texmf-dist/tex/latex/url/url.sty" 1616952564 12796 8edb7d69a20b857904dd0ea757c14ec9 "" "/usr/share/texmf-dist/web2c/texmf.cnf" 1616952564 33301 a3134070eacafb10b1f371612ce2650d "" - "/var/lib/texmf/fonts/map/pdftex/updmap/pdftex.map" 1618924313 4885835 225b430335ea75120e4d14f95280dfb9 "" - "/var/lib/texmf/web2c/pdftex/pdflatex.fmt" 1618924260 2635857 8ed966d5a25715e6e8fe7a58ee087971 "" + "/var/lib/texmf/fonts/map/pdftex/updmap/pdftex.map" 1620463121 4885835 225b430335ea75120e4d14f95280dfb9 "" + "/var/lib/texmf/web2c/pdftex/pdflatex.fmt" 1620463077 2635857 ce71ba2e9c61a222d6d9dcfa2d0986e6 "" "inp_n7.jpg" 1618500153 64325 a4188587e23e19cb9a8d50da0c47b845 "" - "notes.aux" 1619376893 845 467bc9a0de3c71bf18b9a0157f8def98 "pdflatex" - "notes.out" 1619376893 0 d41d8cd98f00b204e9800998ecf8427e "pdflatex" - "notes.tex" 1619376890 1910 342138058897a9344f648b92cf61941b "" + "notes.aux" 1621881899 845 467bc9a0de3c71bf18b9a0157f8def98 "pdflatex" + "notes.out" 1621881899 0 d41d8cd98f00b204e9800998ecf8427e "pdflatex" + "notes.tex" 1621881897 2038 d0c24313d6481f7788145d1bee0004c8 "" (generated) + "notes.out" "/home/laurent/Documents/Cours/ENSEEIHT/S6 - Systèmes d'Exploitation Centralisés/projet/latex/notes.log" - "/home/laurent/Documents/Cours/ENSEEIHT/S6 - Systèmes d'Exploitation Centralisés/projet/latex/notes.pdf" "notes.pdf" "notes.log" - "notes.out" "notes.aux" + "/home/laurent/Documents/Cours/ENSEEIHT/S6 - Systèmes d'Exploitation Centralisés/projet/latex/notes.pdf" diff --git a/latex/notes.log b/latex/notes.log index 3fee291..5155b1e 100644 --- a/latex/notes.log +++ b/latex/notes.log @@ -1,4 +1,4 @@ -This is pdfTeX, Version 3.14159265-2.6-1.40.21 (TeX Live 2020/Arch Linux) (preloaded format=pdflatex 2021.4.20) 25 APR 2021 20:54 +This is pdfTeX, Version 3.14159265-2.6-1.40.21 (TeX Live 2020/Arch Linux) (preloaded format=pdflatex 2021.5.8) 24 MAY 2021 20:44 entering extended mode \write18 enabled. file:line:error style messages enabled. @@ -538,14 +538,14 @@ Package rerunfilecheck Info: File `notes.out' has not changed. ) Here is how much of TeX's memory you used: 12226 strings out of 479383 - 200736 string characters out of 5875830 + 200736 string characters out of 5875831 668182 words of memory out of 5000000 29109 multiletter control sequences out of 15000+600000 409409 words of font info for 43 fonts, out of 8000000 for 9000 1141 hyphenation exceptions out of 8191 80i,7n,85p,622b,424s stack positions out of 5000i,500n,10000p,200000b,80000s {/usr/share/texmf-dist/fonts/enc/dvips/cm-super/cm-super-t1.enc} -Output written on "/home/laurent/Documents/Cours/ENSEEIHT/S6 - Systèmes d'Exploitation Centralisés/projet/latex/notes.pdf" (2 pages, 124006 bytes). +Output written on "/home/laurent/Documents/Cours/ENSEEIHT/S6 - Systèmes d'Exploitation Centralisés/projet/latex/notes.pdf" (2 pages, 124369 bytes). PDF statistics: 35 PDF objects out of 1000 (max. 8388607) 25 compressed objects within 1 object stream diff --git a/latex/notes.pdf b/latex/notes.pdf index 98c7fdb..55d017d 100644 Binary files a/latex/notes.pdf and b/latex/notes.pdf differ diff --git a/latex/notes.synctex.gz b/latex/notes.synctex.gz index ad94cad..f4e2411 100644 Binary files a/latex/notes.synctex.gz and b/latex/notes.synctex.gz differ diff --git a/latex/notes.tex b/latex/notes.tex index 0a32654..bf5676a 100644 --- a/latex/notes.tex +++ b/latex/notes.tex @@ -57,4 +57,6 @@ Pour ce qui est de la question 6 et 7, la principale difficulté a été de choi Mon implémentation de la question 6 et 7 fonctionne dans la plupart des cas, puisqu'il y a encore quelques cas exceptionnels où mon code ne fournit pas le résultat espéré. Cela est dû à ma gestion des signaux parfois un peu hasardeuse (et surtout car l'on doit gérer l'exécution de programmes en parallèle). +Un petit fichier de test est disponible et permet de tester les fonctionnalités principales du minishell. Il se nomme test.sh + \end{document} diff --git a/minishell b/minishell deleted file mode 100755 index faadff2..0000000 Binary files a/minishell and /dev/null differ diff --git a/test.sh b/test.sh index fcdde66..5ab0663 100644 --- a/test.sh +++ b/test.sh @@ -1,10 +1,11 @@ green=`tput setaf 2` reset=`tput sgr0` -extralongpipe=`printf '| sort | uniq | rev %.0s' {1..20}` +extralongpipe=`printf '| sort | uniq | rev %.0s' {1..50}` rm .testms > /dev/null touch .testms +make clear tail -f .testms & tailpid=$! @@ -76,7 +77,7 @@ tmux send-keys -t testms Enter sleep 0.5 -echo "${green}^Z${reset}" +printf "${green}^Z${reset}" tmux send-keys -t testms C-z sleep 0.5 @@ -108,7 +109,24 @@ echo "${green}pwd${reset}" tmux send-keys -t testms -l "pwd" tmux send-keys -t testms Enter -sleep 12 +sleep 6 +echo "${green}jobs${reset}" +tmux send-keys -t testms -l "jobs" +tmux send-keys -t testms Enter + +sleep 7 + +echo "${green}jobs${reset}" +tmux send-keys -t testms -l "jobs" +tmux send-keys -t testms Enter + +sleep 0.5 + +echo "${green}^D${reset}" tmux send-keys -t testms C-d kill $tailpid + +printf "\n\n\n" +rm .testms > /dev/null +make clean diff --git a/à zipper/FAINSIN_Laurent.tar b/à zipper/FAINSIN_Laurent.tar new file mode 100644 index 0000000..2a6af1d Binary files /dev/null and b/à zipper/FAINSIN_Laurent.tar differ diff --git a/à zipper/jobs.c b/à zipper/jobs.c index d220802..41c3b74 100644 --- a/à zipper/jobs.c +++ b/à zipper/jobs.c @@ -110,7 +110,6 @@ void liberer(list *l_ptr) free(cursor2free); } - free(*l_ptr); *l_ptr = NULL; } @@ -144,4 +143,4 @@ cell *trouver_id(list *l_ptr, int id) } return NULL; // erreur -} \ No newline at end of file +} diff --git a/à zipper/jobs.h b/à zipper/jobs.h index 20259ba..8127ebf 100644 --- a/à zipper/jobs.h +++ b/à zipper/jobs.h @@ -22,4 +22,4 @@ void supprimer(cell **list, int pid); cell *trouver(list *l_ptr, int pid); cell *trouver_id(list *l_ptr, int id); -#endif \ No newline at end of file +#endif diff --git a/à zipper/minishell.c b/à zipper/minishell.c index 49c8400..15b6e88 100644 --- a/à zipper/minishell.c +++ b/à zipper/minishell.c @@ -6,104 +6,42 @@ #include #include #include +#include #include #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; char initcd[256], currentcd[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 child failed, (%d) %s\n", errno, strerror(errno)); - exit(errno); - } +int file_in, file_out; - cell *job = trouver(&jobs, pid_fils); - if (job != NULL) - { - if (prompting) - { - printf("\n"); - } +int pipes[256][2]; +int sous_fils[256]; - 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); -} +struct sigaction action; int main(int argc, char *argv[]) { + setvbuf(stdout, NULL, _IONBF, 0); // pratique pour test.sh, optionnel sinon (normalement) 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; @@ -124,111 +62,137 @@ int main(int argc, char *argv[]) cmd = readcmd(); prompting = 0; - if (cmd == NULL) - { // EOF + builtin_code = builtin(); + if (builtin_code == 1) + { break; } - else if (cmd->seq[0] == NULL) - { // empty + else if (builtin_code == 2) + { 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); } - pid_fils = fork(); - if (pid_fils == -1) - { // fork fail ? + int nb_pipe = -1; + char ***cursor = cmd->seq; + while (*cursor) + { // compter le nombre de commandes séparées par des pipes + cursor++; + nb_pipe++; + } + if (nb_pipe < 0) + { // counting failed ? + fprintf(stderr, "ERROR: counting pipes failed"); + exit(2); + } + + if ((pid_fils = fork()) == -1) + { // fork failed ? fprintf(stderr, "ERROR: forking failed, (%d) %s\n", errno, strerror(errno)); exit(errno); } - if (pid_fils == 0) { // instructions du fils action.sa_handler = SIG_IGN; - sigaction(SIGTSTP, &action, NULL); // on igonre SIGTSTP + sigaction(SIGTSTP, &action, NULL); // on ignore SIGTSTP 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 + if (cmd->in) + { // "<" + file_in = open(cmd->in, O_RDONLY); + dup2(file_in, STDIN_FILENO); + } + if (cmd->out) + { // ">" + file_out = open(cmd->out, O_CREAT | O_TRUNC | O_WRONLY, 0640); + dup2(file_out, STDOUT_FILENO); + } + + if (nb_pipe > 0) + { // "|" + for (int i = 0; i <= nb_pipe; i++) + { // on créé itérativement nb_pipe fils et pipes + if (pipe(pipes[i]) < 0) + { // pipe failed ? + fprintf(stderr, "ERROR: pipe error, (%d) %s\n", errno, strerror(errno)); + exit(errno); + } + + if ((sous_fils[i] = fork()) < 0) + { // fork failed ? + fprintf(stderr, "ERROR: fork error, (%d) %s\n", errno, strerror(errno)); + exit(errno); + } + else if (sous_fils[i] == 0) + { // instructions des sous-fils + + if (i == 0) + { // premier sous-fils + close(pipes[0][0]); + } + else if (dup2(pipes[i - 1][0], STDIN_FILENO) == -1) + { // dup2 failed ? + fprintf(stderr, "ERROR: dup2 error, (%d) %s\n", errno, strerror(errno)); + exit(errno); + } + + if (i == nb_pipe) + { // dernier sous-fils + close(pipes[i][1]); + } + else if (dup2(pipes[i][1], STDOUT_FILENO) == -1) + { // dup2 failed ? + fprintf(stderr, "ERROR: dup2 error, (%d) %s\n", errno, strerror(errno)); + exit(errno); + } + + for (int j = 0; j <= i; j++) + { // on ferme les pipes non nécéssaires + if (j <= i - 2) + { // on ferme tous les pipes que l'on utilise pas + close(pipes[j][0]); + close(pipes[j][1]); + } + else if (j == i - 1) + { // on ferme l'écriture du pipe précédent + close(pipes[j][1]); + } + else if (j == i) + { // on ferme la lecture de son propre pipe + close(pipes[j][0]); + } + } + + execvp(cmd->seq[i][0], cmd->seq[i]); + fprintf(stderr, "ERROR: execvp failed, (%d) %s\n", errno, strerror(errno)); + exit(errno); // si execvp échoue on exit avec une erreur + } + } + for (int i = 0; i <= nb_pipe; i++) + { // on ferme tous les pipes pour le fils + close(pipes[i][0]); + close(pipes[i][1]); + } + for (int i = 0; i <= nb_pipe; i++) + { // on attend chaque sous-fils + if (waitpid(sous_fils[i], &wait_code, 0) == -1) + if (wait_code) + { // execvp failed ? + fprintf(stderr, "ERROR: child n°%d failed, (%d) %s\n", i, wait_code, strerror(wait_code)); + } + } + exit(0); // on termine le fils + } + else + { // pas de pipes dans la commande + execvp(cmd->seq[0][0], cmd->seq[0]); + fprintf(stderr, "ERROR: execvp failed, (%d) %s\n", errno, strerror(errno)); + exit(errno); // si execvp échoue on exit avec une erreur + } } else { // instructions du père @@ -239,21 +203,19 @@ int main(int argc, char *argv[]) } else { // foreground - pid_t id = waitpid(pid_fils, &wait_code, 0); - - if (id == -1) - { // wait fail ? - fprintf(stderr, "ERROR: waiting for %d failed, (%d) %s\n", wait_code, errno, strerror(errno)); + if (waitpid(pid_fils, &wait_code, 0) == -1) + { // wait failed ? + fprintf(stderr, "ERROR: waiting for %d failed, (%d) %s\n", pid_fils, errno, strerror(errno)); exit(errno); } - if (wait_code) - { // execvp fail ? - fprintf(stderr, "ERROR: command failed, (%d) %s\n", wait_code, strerror(wait_code)); + { // execvp failed ? + fprintf(stderr, "ERROR: child failed, (%d) %s\n", wait_code, strerror(wait_code)); } } } } + liberer(&jobs); return EXIT_SUCCESS; -} \ No newline at end of file +} diff --git a/à zipper/notes.pdf b/à zipper/notes.pdf index 98c7fdb..55d017d 100644 Binary files a/à zipper/notes.pdf and b/à zipper/notes.pdf differ diff --git a/à zipper/readcmd.h b/à zipper/readcmd.h index abe5f81..38408d8 100755 --- a/à zipper/readcmd.h +++ b/à zipper/readcmd.h @@ -17,7 +17,7 @@ struct cmdline *readcmd(void); struct cmdline { char *err; /* Si non null : message d'erreur à afficher. - * Dans ce cas, les autres champs sont nuls. */ + * Dans ce cas, les autres champs sont nuls. */ char *in; /* Si non null : nom du fichier vers lequel l'entrée doit être redirigée. */ char *out; /* Si non null : nom du fichier vers lequel la sortie doit être redirigée. */ char *backgrounded; /* Si non null : commande en tâche de fond */ diff --git a/à zipper/test.sh b/à zipper/test.sh index 9359f1a..5ab0663 100644 --- a/à zipper/test.sh +++ b/à zipper/test.sh @@ -1,2 +1,132 @@ -sleep 4 -printf "\n\n --- bonjour --- \n\n" \ No newline at end of file +green=`tput setaf 2` +reset=`tput sgr0` + +extralongpipe=`printf '| sort | uniq | rev %.0s' {1..50}` + +rm .testms > /dev/null +touch .testms +make +clear +tail -f .testms & +tailpid=$! + +tmux kill-session -t testms > /dev/null 2>&1 +tmux new-session -d -s testms './minishell > .testms' + +sleep 0.5 + +echo "${green}echo bonjour, je suis un message vert de debug${reset}" +tmux send-keys -t testms -l "echo bonjour, je suis un message vert de debug" +tmux send-keys -t testms Enter + +sleep 0.5 + +echo "${green}ls${reset}" +tmux send-keys -t testms -l "ls" +tmux send-keys -t testms Enter + +sleep 0.5 + +echo "${green}ls -l${reset}" +tmux send-keys -t testms -l "ls -lah" +tmux send-keys -t testms Enter + +sleep 0.5 + +echo "${green}ls -lah | grep mini${reset}" +tmux send-keys -t testms -l "ls -lah | grep mini" +tmux send-keys -t testms Enter + +sleep 0.5 + +echo "${green}ls -lah | grep mini | wc${reset}" +tmux send-keys -t testms -l "ls -lah | grep mini | wc" +tmux send-keys -t testms Enter + +sleep 0.5 + +echo "${green}ls -lah | sort | rev | sort | ... ${reset}" +tmux send-keys -t testms -l "ls -lah $extralongpipe" +tmux send-keys -t testms Enter + +sleep 0.5 + +echo "${green}^C${reset}" +tmux send-keys -t testms C-c +echo "${green}^C${reset}" +tmux send-keys -t testms C-c +echo "${green}^C${reset}" +tmux send-keys -t testms C-c + +for i in {5..15} +do + echo "${green}sleep $i &${reset}" + tmux send-keys -t testms -l "sleep $i &" + tmux send-keys -t testms Enter +done + +sleep 0.5 + +echo "${green}stop 8${reset}" +tmux send-keys -t testms -l "stop 8" +tmux send-keys -t testms Enter + +echo "${green}fg 1${reset}" +tmux send-keys -t testms -l "fg 1" +tmux send-keys -t testms Enter + +sleep 0.5 + +printf "${green}^Z${reset}" +tmux send-keys -t testms C-z + +sleep 0.5 + +echo "${green}bg 1${reset}" +tmux send-keys -t testms -l "bg 1" +tmux send-keys -t testms Enter + +sleep 0.5 + +echo "${green}jobs${reset}" +tmux send-keys -t testms -l "jobs" +tmux send-keys -t testms Enter + +sleep 0.5 + +echo "${green}pwd${reset}" +tmux send-keys -t testms -l "pwd" +tmux send-keys -t testms Enter + +sleep 0.5 + +echo "${green}cd ..${reset}" +tmux send-keys -t testms -l "cd .." +tmux send-keys -t testms Enter +sleep 0.5 + +echo "${green}pwd${reset}" +tmux send-keys -t testms -l "pwd" +tmux send-keys -t testms Enter + +sleep 6 + +echo "${green}jobs${reset}" +tmux send-keys -t testms -l "jobs" +tmux send-keys -t testms Enter + +sleep 7 + +echo "${green}jobs${reset}" +tmux send-keys -t testms -l "jobs" +tmux send-keys -t testms Enter + +sleep 0.5 + +echo "${green}^D${reset}" +tmux send-keys -t testms C-d +kill $tailpid + +printf "\n\n\n" +rm .testms > /dev/null +make clean diff --git a/à zipper/utils.c b/à zipper/utils.c new file mode 100644 index 0000000..84a57af --- /dev/null +++ b/à zipper/utils.c @@ -0,0 +1,197 @@ +#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[]; +extern struct sigaction action; + +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); + printf("[%d] %d running: %s\n", job->id, job->pid, job->cmd); + 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 failed ? + 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/à zipper/utils.h b/à zipper/utils.h new file mode 100644 index 0000000..bb7c49f --- /dev/null +++ b/à zipper/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