/*********************************************************************
* executeCmdLine parses a command line into its individual pipeline
* elements. It creates a pipe to connect each intermediate member of
* the pipeline to its successor and forks children to exec the
* individual pipeline elements. The executeCmdLine function should
* never return. It handles all errors by calling exit(1).
*********************************************************************/
#include "ush.h"
void executeCmdLine(char *incmd)
{
char **chargv;
pid_t child_pid;
char *cmd;
char *nextcmd;
int frontfd[2];
int backfd[2];
frontfd[0] = -1;
frontfd[1] = -1;
backfd[0] = -1;
backfd[1] = -1;
child_pid = 0;
if ((nextcmd = incmd) == NULL)
exit(1);
for (;;)
{
cmd = nextcmd;
if (cmd == NULL) break;
/* if last in pipeline, do not fork another */
if ((nextcmd = strchr(nextcmd, PIPE_SYMBOL)) == NULL)
{
backfd[1] = -1;
child_pid = 0;
}
else
{
/* fork a child to execute next pipeline command */
*nextcmd = NULL_SYMBOL;
nextcmd++;
if (pipe(backfd)== -1)
{
perror("Could not create back pipe");
exit(1);
}
else
if ((child_pid = fork()) == -1)
{
perror("Could not fork next child");
exit(1);
}
}
if (child_pid == 0)
{
/* the child execs the command */
if (connectPipeLine(cmd, frontfd, backfd) == -1)
{
perror("Could not connect to pipeline");
exit(1);
}
else
if (makeargv(cmd, BLANK_STRING, &chargv) > 0)
{
if (execvp(chargv[0], chargv) == -1)
perror("Invalid command");
}
exit(1);
}
/* the parent closes front pipe and makes back pipe, front */
close(frontfd[0]);
close(frontfd[1]);
frontfd[0] = backfd[0];
frontfd[1] = backfd[1];
}
close(backfd[0]);
close(backfd[1]);
exit(1);
}