/*
* jpipe.h: file contenente le routine per gestire una
* pipeline di processi.
*
* Autore: Antonio Ospite 408/244
* Data: Giugno 2001
*/
#include "jpipe.h"
/*
* prototipo della funzione che si occupa di eseguire un comando della
* pipeline
*/
static void launch_pipe_process (char *, pid_t, int);
/*
* definizione della funzione execpipe()
*/
int
execpipe (char *inputstring)
{
pid_t pid;
int i, j, c, len, status;
int pfd[MAXCMD][2];
char *word, *tmpstr, *cmdv[MAXCMD];
c = strlen(inputstring);
tmpstr = malloc(c+1);
strncpy (tmpstr, inputstring, c);
tmpstr[c]=0;
c = 0;
for (word = strtok (tmpstr, SEPARATOR); word;
word = strtok (NULL, SEPARATOR))
{
len = strlen (word);
if ((cmdv[c] = malloc (len)) == NULL)
perror ("malloc");
strcpy (cmdv[c], word);
c++;
}
for (i = 0; i < c - 1; i++) /*
* creo c-1 pipe, se ho c comandi
*/
pipe (pfd[i]);
for (i = 0; i < c; i++)
{ /*
* creo un figlio per ogni processo
*/
if ((pid = fork ()) < 0)
{
perror ("errore di fork");
exit (1);
}
if (pid == 0)
{
if (i != 0)
{
close (STDIN_FILENO);
dup (pfd[i - 1][READ]);
}
if (i != c - 1)
{
close (STDOUT_FILENO);
dup (pfd[i][WRITE]);
}
for (j = 0; j < c - 1; j++)
{
close (pfd[j][READ]);
close (pfd[j][WRITE]);
}
launch_pipe_process (cmdv[i], getppid (), 1);
}
}
/*
* chiusura dei descrittori di pipe
*/
for (j = 0; j < c - 1; j++)
{
close (pfd[j][READ]);
close (pfd[j][WRITE]);
}
/*
* attesa dei processi figli
*/
for (i = 0; i < c; i++)
{
if (waitpid (-1, &status, WUNTRACED) < 0)
{
perror ("errore di wait");
}
if (WIFSIGNALED (status))
printf ("Processo terminato per un segnale (%s)\n",
sys_siglist[WTERMSIG (status)]);
if (WIFSTOPPED (status))
{
printf ("L'esecuzione della pipeline e' stata stoppata\n");
return 0;
}
}
return 0;
}
static void
launch_pipe_process (char *command, pid_t pgid, int foreground)
{
pid_t pid = getpid ();
/*
* Creazione di un nuovo gruppo di processi ed eventuale
* assegnazione del terminale di controllo al nuovo gruppo di processi
*/
pid = getpid ();
if (pgid == 0)
pgid = pid;
setpgid (pid, pgid);
if (foreground == 1)
tcsetpgrp (STDIN_FILENO, pgid);
/*
* Si ripristina l'handling dei segnali
*/
signal (SIGINT, SIG_DFL);
signal (SIGQUIT, SIG_DFL);
signal (SIGTSTP, SIG_DFL);
signal (SIGTTIN, SIG_DFL);
signal (SIGTTOU, SIG_DFL);
signal (SIGCHLD, SIG_DFL);
/*
* Esecuzione del nuovo processo
*/
execlp ("sh", "sh", "-c", command, (char *) 0);
/*
* Il codice che segue viene eseguito solo nel caso in cui
* la chiamata alla exec() fallisca
*/
perror ("Errore di exec");
exit (1);
}
syntax highlighted by Code2HTML, v. 0.9.1