Code:
void executerCommande( char *commande[], int descripteur, char* option )
{
int tubeEntree[2];
int tubeSortie[2];
int erreur;
erreur = pipe( tubeEntree );
if ( erreur == -1 )
{
printf( "Erreur lors de la création du tube %s\n", strerror( errno ) );
exit( 1 );
}
erreur = pipe( tubeSortie );
if ( erreur == -1 )
{
printf( "Erreur lors de la création du tube %s\n", strerror( errno ) );
exit( 1 );
}
pid_t pid = fork();
if ( pid == -1 ) // erreur
{
perror( "fork a échoué" );
exit( 1 );
}
else if ( pid == 0 ) // child
{
erreur = close( tubeEntree[1] ); // closing writing end of tube from parent to child
if ( erreur == -1 )
{
printf( "Erreur lors du close %s\n", strerror( errno ) );
exit( 1 );
}
erreur = close( tubeSortie[0] ); // closing reading end of tube from child to parent
if ( erreur == -1 )
{
printf( "Erreur lors du close %s\n", strerror( errno ) );
exit( 1 );
}
erreur = dup2 ( tubeSortie[1], STDOUT_FILENO );
if ( erreur == -1 ) // redirecting stdout to writing end of tube from child to parent
{
printf( "Erreur lors du dup2 stdout: %s\n", strerror( errno ) );
exit( 1 );
}
erreur = close( tubeSortie[1] ); // fermeture du doublon
if ( erreur == -1 )
{
printf( "Erreur lors du close %s\n", strerror( errno ) );
exit( 1 );
}
erreur = dup2( tubeEntree[0], STDIN_FILENO );
if ( erreur == -1 ) // redirecting stdin to reading end of tube from parent to child
{
printf( "Erreur lors du dup stdin: %s\n", strerror( errno ) );
exit( 1 );
}
erreur = close( tubeEntree[0] ); // fermeture du doublon
if ( erreur == -1 )
{
printf( "Erreur lors du close %s\n", strerror( errno ) );
exit( 1 );
}
execvp( commande[0], commande );
}
else // parent
{
int evenement;
int commandeTerminee = 0;
int length;
char tampon [256];
struct pollfd entrees[2];
entrees[0].fd = 0; // check stdin
entrees[0].events = POLLIN | POLLPRI; // surveiller pour des données normales ou prioritaires
entrees[0].revents = 0;
entrees[1].fd = tubeSortie[0]; // check reading end of tube from child to parent
entrees[1].events = POLLIN | POLLPRI; // surveiller pour des données normales ou prioritaires
entrees[1].revents = 0;
erreur = close( tubeEntree[0] ); // closing reading end of tube from parent to child
if ( erreur == -1 )
{
printf( "Erreur lors du close %s\n", strerror( errno ) );
exit( 1 );
}
erreur = close( tubeSortie[1] ); // closing writing end of tube from child to parent
if ( erreur == -1 )
{
printf( "Erreur lors du close %s\n", strerror( errno ) );
exit( 1 );
}
while ( commandeTerminee == 0 )
{
entrees[0].revents = 0;
entrees[1].revents = 0;
evenement = poll( entrees, 2, 0 );
if ( evenement == -1 )
{
printf( "Erreur lors du poll %s\n", strerror( errno ) );
exit( 1 );
}
if ( ( entrees[0].revents & POLLIN ) || ( entrees[0].revents & POLLPRI ) )
{
memset(tampon, '\0', 256);
length = read( entrees[0].fd, tampon, 256 );
if ( ( strcmp( option, "-i" ) == 0 ) || ( strcmp( option, "-io" ) == 0 ) )
{
erreur = write ( descripteur, tampon, strlen( tampon ) );
if ( erreur == -1 )
{
printf( "Erreur lors de l'écriture sur le fichier %s\n", strerror( errno ) );
exit( 1 );
}
}
erreur = write ( tubeEntree[1], tampon, length );
if ( erreur == -1 )
{
printf( "Erreur lors de l'écriture dans le tube d'entrée %s\n", strerror( errno ) );
exit( 1 );
}
}
if ( entrees[0].revents & POLLHUP )
{
commandeTerminee = 1;
}
if ( ( entrees[1].revents & POLLIN ) || ( entrees[1].revents & POLLPRI ) )
{
do {
memset(tampon, '\0', 256);
length = read( entrees[1].fd, tampon, 256 );
if ( erreur == -1 )
{
printf( "Erreur lors de la lecture du tube de sortie %s\n", strerror ( errno ) );
exit( 1 );
}
if ( ( strcmp( option, "-o" ) == 0 ) || ( strcmp( option, "-io" ) == 0 ) )
{
erreur = write( descripteur, tampon, strlen( tampon ) );
if ( erreur == -1 )
{
printf( "Erreur lors de l'écriture sur le fichier %s\n", strerror ( errno ) );
exit( 1 );
}
}
printf( "%s", tampon );
} while (erreur != 0);
}
if ( entrees[1].revents & POLLHUP )
{
commandeTerminee = 1;
}
}
pid = wait( NULL );
}
}