As the title indicates I am trying to perform an exercise to emulate the behavior of the shell in the execution of a sentence with the form
comando1 argumento1 | comando2 argumento2
This program opens a pipe and creates a child by calling fork()
, in addition the parent executes comando1 argumento1
and redirects the standard output to the writing end of the pipe.
The child on the other hand executes comando1 argumento1
and in this case the standard input must be duplicated with the reading end of the pipe.
I am testing my program by executing ./shell echo holaa | wc -c
, my program returns a 47, when I should return 6, since they are the chars of the word "hello" plus the end of file character '\ 0', and it is also what the linux shell returns if I run the command on it.
All help is welcome and thanks in advance, I leave the code of my program below, greetings.
#include <sys/types.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/select.h>
#include <stdlib.h>
// Probar el programa con ./shell echo holaa | wc -c
int main(int argc, char *argv[]) {
if(argc < 6) {
printf("Uso: comando1 argumento1 | comando2 argumento2\n");
exit(EXIT_FAILURE);
}
int descf[2]; //descf[0] -> lectura, descf[1] -> escritura
int res1, res2;
char *cmd1[] = {argv[1], argv[2], NULL};
char *cmd2[] = {argv[4], argv[5], NULL};
// Creamos la tuberia sin nombre
pipe(descf);
// Si no ha habido errores (-1) fork() retorna dos veces, una con un pid = 0 (ejecución proceso hijo) y otra con un pid > 0 (ejecución proceso padre)
pid_t pid = fork();
if(pid == -1) {
perror("Error en el fork()");
} else if(pid > 0) { // Ejecución del padre:
close(descf[1]);
dup2(descf[0], 0); // Redirecciona salida estandar al extremo de escritura del pipe
res1 = execvp(cmd1[0], cmd1); //Ejecuta comando1 argumento 1
if(res1 == -1) perror("Fallo en execvp1()");
} else if(pid == 0) { // Ejecución del hijo
close(descf[0]);
dup2(descf[1], 1); // Duplica la entrada estandar con el extremo de lectura del pipe
res2 = execv(cmd2[0], cmd2); // Ejecuta comando2 argumento 2
if(res2 == -1) perror("Fallo en execvp2()");
}
return 0;
}