/*
* PJ Waskiewicz
* 2/08/2000
* pipe.c
* Function to handle pipes in pnsh
*/
#include "pnsh.h"
void pipeme(char **args, int numoftokens) {
int p[2];
int fd;
int numofpipes = 0;
int i, j, process_num = 0;
int out_bool, redirect_pos;
int pipepos[MAX_PIPES];
out_bool = 0;
for(i = 0, j = 0; i < numoftokens; i++) {
if(strcmp(args[i], "|") == 0) {
pipepos[j] = i;
j++;
numofpipes++;
}
/* Check if we are redirecting output */
else if(strcmp(args[i], ">") == 0) {
out_bool = 1;
redirect_pos = i;
/* Sanity check */
if(args[redirect_pos + 1] == NULL) {
fprintf(stderr, "Malformed redirect\n");
exit(1);
}
else
/* Get ready for the redirect */
args[redirect_pos] = NULL;
}
}
/* Start forking */
if(fork() == 0) {
pipe(p);
dup2(p[0], 0);
close(p[0]);
for(i = 1; i < numofpipes + 1; i++) {
if(fork() == 0) {
dup2(p[0], 0);
close(p[0]);
close(p[1]);
pipe(p);
process_num = i;
}
else {
dup2(p[1], 1);
close(p[1]);
close(p[0]);
break;
}
}
if(process_num == numofpipes) {
/* I'm last */
/* Find the pipe, in order to set up for exec.
* We also need to check for output redirection
*/
for(j = pipepos[numofpipes - 1]; j < numoftokens; j++) {
if(strcmp(args[j], "|") == 0) {
args[j] = NULL;
if(out_bool == 1) {
/* Time to open the file */
if((fd = open(args[redirect_pos + 1], O_RDWR |
O_CREAT | O_TRUNC, 0666)) < 0)
fprintf(stderr, "%s: open() in child\n", strerror(errno));
/* Purge the file */
if((fd = dup2(fd, 1)) < 0)
fprintf(stderr, "%s: dup2() in child\n", strerror(errno));
}
if(execvp(args[pipepos[numofpipes - 1] + 1], args +
pipepos[numofpipes - 1] + 1) < 0) {
fprintf(stderr, "%s: %s\n", args[pipepos[numofpipes - 1] + 1],
strerror(errno));
exit(1);
}
}
}
}
else if(process_num > 0) {
/* I'm everyone else */
for(j = pipepos[process_num]; j < numoftokens; j++) {
if(strcmp(args[j], "|") == 0) {
args[j] = NULL;
if(execvp(args[pipepos[process_num - 1] + 1],
args + pipepos[process_num - 1] + 1) < 0) {
fprintf(stderr, "%s: %s\n", args[pipepos[process_num - 1] + 1],
strerror(errno));
exit(1);
}
}
}
}
else {
dup2(p[1], 1);
close(p[0]);
close(p[1]);
/* I'm first */
for(j = 0; j < numoftokens; j++) {
if(strcmp(args[j], "|") == 0) {
args[j] = NULL;
if(execvp(args[0], args) < 0) {
fprintf(stderr, "%s: %s\n", args[0], strerror(errno));
exit(1);
}
}
}
}
}
else
/* Wait for children to die */
for(i = 0; i < numofpipes + 1; i++)
wait(NULL);
}