This commit is contained in:
Laureηt 2021-05-25 17:58:28 +02:00
parent c9a0342380
commit 8c4a5a760e
18 changed files with 537 additions and 314 deletions

114
.testms
View file

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

View file

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

View file

@ -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"

View file

@ -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}</usr/share/texmf-dist/fonts/type1/public/cm-super/sfbx2074.pfb></usr/share/texmf-dist/fonts/type1/public/cm-super/sfrm1200.pfb></usr/share/texmf-dist/fonts/type1/public/cm-super/sfrm1440.pfb></usr/share/texmf-dist/fonts/type1/public/cm-super/sfrm2074.pfb>
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

Binary file not shown.

Binary file not shown.

View file

@ -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}

BIN
minishell

Binary file not shown.

24
test.sh
View file

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

Binary file not shown.

View file

@ -110,7 +110,6 @@ void liberer(list *l_ptr)
free(cursor2free);
}
free(*l_ptr);
*l_ptr = NULL;
}

View file

@ -6,104 +6,42 @@
#include <sys/wait.h>
#include <string.h>
#include <signal.h>
#include <fcntl.h>
#include <errno.h>
#include <setjmp.h>
#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;
}

Binary file not shown.

View file

@ -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 */

View file

@ -1,2 +1,132 @@
sleep 4
printf "\n\n --- bonjour --- \n\n"
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

197
à zipper/utils.c Normal file
View file

@ -0,0 +1,197 @@
#define _GNU_SOURCE
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <string.h>
#include <signal.h>
#include <fcntl.h>
#include <errno.h>
#include <setjmp.h>
#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);
}

10
à zipper/utils.h Normal file
View file

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