feat: piping working
This commit is contained in:
parent
89ed491533
commit
61a5953a0f
5
.vscode/launch.json
vendored
5
.vscode/launch.json
vendored
|
@ -20,7 +20,10 @@
|
||||||
"description": "Enable pretty-printing for gdb",
|
"description": "Enable pretty-printing for gdb",
|
||||||
"text": "-enable-pretty-printing",
|
"text": "-enable-pretty-printing",
|
||||||
"ignoreFailures": true
|
"ignoreFailures": true
|
||||||
}
|
},
|
||||||
|
// {
|
||||||
|
// "text": "-gdb-set follow-fork-mode child"
|
||||||
|
// }
|
||||||
],
|
],
|
||||||
"preLaunchTask": "C/C++: gcc build active file",
|
"preLaunchTask": "C/C++: gcc build active file",
|
||||||
"miDebuggerPath": "/usr/bin/gdb"
|
"miDebuggerPath": "/usr/bin/gdb"
|
||||||
|
|
4
.vscode/settings.json
vendored
4
.vscode/settings.json
vendored
|
@ -1,9 +1,11 @@
|
||||||
{
|
{
|
||||||
"files.associations": {
|
"files.associations": {
|
||||||
|
"*.html": "django-html",
|
||||||
"signal.h": "c",
|
"signal.h": "c",
|
||||||
"readcmd.h": "c",
|
"readcmd.h": "c",
|
||||||
"stdlib.h": "c",
|
"stdlib.h": "c",
|
||||||
"wait.h": "c",
|
"wait.h": "c",
|
||||||
"*.bak": "c"
|
"*.bak": "c",
|
||||||
|
"*.tcc": "c"
|
||||||
}
|
}
|
||||||
}
|
}
|
115
minishell.c
115
minishell.c
|
@ -27,6 +27,9 @@ char initcd[256], currentcd[256];
|
||||||
|
|
||||||
int file_in, file_out;
|
int file_in, file_out;
|
||||||
|
|
||||||
|
int pipes[256][2];
|
||||||
|
int sous_fils[256];
|
||||||
|
|
||||||
void handler_sigchld(int sig_num)
|
void handler_sigchld(int sig_num)
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
|
@ -34,7 +37,7 @@ void handler_sigchld(int sig_num)
|
||||||
pid_fils = waitpid(-1, &wait_code, WNOHANG | WUNTRACED | WCONTINUED);
|
pid_fils = waitpid(-1, &wait_code, WNOHANG | WUNTRACED | WCONTINUED);
|
||||||
if ((pid_fils == -1) && (errno != ECHILD))
|
if ((pid_fils == -1) && (errno != ECHILD))
|
||||||
{ // wait fail ?
|
{ // wait fail ?
|
||||||
fprintf(stderr, "ERROR: waiting for child failed, (%d) %s\n", errno, strerror(errno));
|
fprintf(stderr, "ERROR: waiting for %d failed, (%d) %s\n", pid_fils, errno, strerror(errno));
|
||||||
exit(errno);
|
exit(errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,6 +130,7 @@ int main(int argc, char *argv[])
|
||||||
cmd = readcmd();
|
cmd = readcmd();
|
||||||
prompting = 0;
|
prompting = 0;
|
||||||
|
|
||||||
|
// TODO: créer fonction "builtin" ?
|
||||||
if (cmd == NULL)
|
if (cmd == NULL)
|
||||||
{ // EOF
|
{ // EOF
|
||||||
break;
|
break;
|
||||||
|
@ -222,34 +226,130 @@ int main(int argc, char *argv[])
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
pid_fils = fork();
|
// compter le nombre de commandes séparées par des pipes
|
||||||
if (pid_fils == -1)
|
int nb_pipe = -1;
|
||||||
|
char ***cursor = cmd->seq;
|
||||||
|
while (*cursor)
|
||||||
|
{
|
||||||
|
cursor++;
|
||||||
|
nb_pipe++;
|
||||||
|
}
|
||||||
|
if (nb_pipe < 0)
|
||||||
|
{ // counting failed ?
|
||||||
|
fprintf(stderr, "ERROR: counting pipes failed");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((pid_fils = fork()) == -1)
|
||||||
{ // fork fail ?
|
{ // fork fail ?
|
||||||
fprintf(stderr, "ERROR: forking failed, (%d) %s\n", errno, strerror(errno));
|
fprintf(stderr, "ERROR: forking failed, (%d) %s\n", errno, strerror(errno));
|
||||||
exit(errno);
|
exit(errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pid_fils == 0)
|
if (pid_fils == 0)
|
||||||
{ // instructions du fils
|
{ // instructions du fils
|
||||||
action.sa_handler = SIG_IGN;
|
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
|
sigaction(SIGINT, &action, NULL); // on ignore SIGINT
|
||||||
|
|
||||||
if (cmd->in)
|
if (cmd->in)
|
||||||
{
|
{ // "<"
|
||||||
file_in = open(cmd->in, O_RDONLY);
|
file_in = open(cmd->in, O_RDONLY);
|
||||||
dup2(file_in, 0);
|
dup2(file_in, 0);
|
||||||
}
|
}
|
||||||
if (cmd->out)
|
if (cmd->out)
|
||||||
{
|
{ // ">"
|
||||||
file_out = open(cmd->out, O_CREAT | O_TRUNC | O_WRONLY, 0640);
|
file_out = open(cmd->out, O_CREAT | O_TRUNC | O_WRONLY, 0640);
|
||||||
dup2(file_out, 1);
|
dup2(file_out, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (nb_pipe > 0)
|
||||||
|
{ // "|" présent(s) dans la commande
|
||||||
|
for (int i = 0; i <= nb_pipe; i++)
|
||||||
|
{ // on crée 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 fail
|
||||||
|
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 fail
|
||||||
|
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
|
||||||
|
pid_t id = waitpid(sous_fils[i], &wait_code, 0);
|
||||||
|
|
||||||
|
if (id == -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: child failed, (%d) %s\n", wait_code, strerror(wait_code));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exit(0); // on termine le fils
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // pas de piping
|
||||||
execvp(cmd->seq[0][0], cmd->seq[0]);
|
execvp(cmd->seq[0][0], cmd->seq[0]);
|
||||||
fprintf(stderr, "ERROR: execvp failed, (%d) %s\n", errno, strerror(errno));
|
fprintf(stderr, "ERROR: execvp failed, (%d) %s\n", errno, strerror(errno));
|
||||||
exit(errno); // si execvp échoue on exit avec une erreur
|
exit(errno); // si execvp échoue on exit avec une erreur
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{ // instructions du père
|
{ // instructions du père
|
||||||
if (cmd->backgrounded)
|
if (cmd->backgrounded)
|
||||||
|
@ -266,7 +366,6 @@ int main(int argc, char *argv[])
|
||||||
fprintf(stderr, "ERROR: waiting for %d failed, (%d) %s\n", wait_code, errno, strerror(errno));
|
fprintf(stderr, "ERROR: waiting for %d failed, (%d) %s\n", wait_code, errno, strerror(errno));
|
||||||
exit(errno);
|
exit(errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wait_code)
|
if (wait_code)
|
||||||
{ // execvp fail ?
|
{ // execvp fail ?
|
||||||
fprintf(stderr, "ERROR: child failed, (%d) %s\n", wait_code, strerror(wait_code));
|
fprintf(stderr, "ERROR: child failed, (%d) %s\n", wait_code, strerror(wait_code));
|
||||||
|
|
Loading…
Reference in a new issue