Executes the first command and redirects it's output to the second.
False waitExecution causes the the first command to be executed at the time of the call and the second when the background handler allows it.
redIn refers to the first command and redOut to the second.
If the command parameters do not contain "/" the executable is searched in PATH.
Throws errno in case of failed pipelining,failed forking,failed redirection when waitExecution is true and failed background handling and initiation of the new process.
redIn,redOut should be NULL if no redirection is required,append should be true if output needs to be redirected to a file,appened at the end.
Check
LinuxShell for missing methods and complete source code.
void pipe(const char *command1, char *const args1[],const char *command2, char *const args2[],bool waitExecution,const char *redIn,const char* redOut,bool append){
int pipeDesc[2];
bool error=false;
if(pipe(pipeDesc)<0){
throw errno;
}
pid_t pid1,pid2;
int in=-1,out=-1;
if((pid1=fork())==0){ dup2(pipeDesc[1],1);
close(pipeDesc[0]);
close(pipeDesc[1]);
if(redIn!=NULL){
try{
in=startRedirectIn(redIn);
}catch(int ex){
exit(ex);
}
}
stopRedirect(in);
execvp(command1,args1);
exit(1);
}
if(pid1==-1){ throw errno;
}
if((pid2=fork())==0){ dup2(pipeDesc[0],0);
close(pipeDesc[0]);
close(pipeDesc[1]);
if(redOut!=NULL){
try{
in=startRedirectOut(redOut,append);
}catch(int ex){
exit(ex);
}
}
stopRedirect(out);
execvp(command2,args2);
exit(1);
}
if(pid2==-1){ throw errno;
}
close(pipeDesc[0]);
close(pipeDesc[1]);
if(waitExecution){
int status;
pid_t ws=wait(&status);
if(ws!=-1){ if(WIFEXITED(status)){
int exitStatus=WEXITSTATUS(status);
if(exitStatus!=0){
kill(pid2,SIGKILL);
throw exitStatus;
}
}
}else{ throw errno;
}
ws=wait(&status);
if(ws!=-1){ if(WIFEXITED(status)){
int exitStatus=WEXITSTATUS(status);
if(exitStatus!=0){
throw exitStatus;
}
}
}else{ throw errno;
}
}else{ int status;
pid_t ws=wait(&status);
bool pid1Finished=true;
if(ws!=-1){ if(WIFEXITED(status)){
int exitStatus=WEXITSTATUS(status);
if(exitStatus!=0){
kill(pid2,SIGKILL);
throw exitStatus;
}
}
}else{ throw errno;
}
if(kill(pid2,SIGSTOP)==0){
backgroundProcs.push_back(pid2);
}else{
throw errno;
}
}
}