Я не совсем уверен, почему waitpid() постоянно зависает. Я предполагаю, что вилки должны завершиться и вернуться к родительскому процессу после выполнения execvp(). Этого не происходит. Если я закомментирую функцию waitpid(), исходный вывод будет правильным, но программа начнет вести себя неожиданно.
edit
- execFirst() Обрабатывает выполнение первой команды из списка
- execMid() Обрабатывает выполнение любой команды в списке, которая не является первой или последней командой в списке
- execLast() Обрабатывает выполнение последней команды в списке
// Closes pipe
void closePipe(int *pPipe){
close(pPipe[0]);
close(pPipe[1]);
return;
}
// Opens the read end of pPipe and closes the write end
// @Private
void readFromPipe(int *pPipe){
dup2(pPipe[0],0);
close(pPipe[1]);
close(pPipe[0]);
return;
}
// Opens the write end of pPipe and closes the read end
// @Private
void writeToPipe(int *pPipe){
dup2(pPipe[1],1);
close(pPipe[0]);
close(pPipe[1]);
return;
}
// @Private
void execLast(sSettings *pSettings_, sCommand *pCommand, int iPipe[]){
readFromPipe(iPipe);
_execvp(pSettings_, pCommand);
}
// @Private
void execMid(sSettings *pSettings_, sCommand *pCommand, int iPipe1[], int iPipe2[]){
readFromPipe(iPipe1);
writeToPipe(iPipe2);
_execvp(pSettings_, pCommand);
}
// @Private
void execFirst(sSettings *pSettings_, sCommand *pCommand, int iPipe[]){
writeToPipe(iPipe);
_execvp(pSettings_, pCommand);
}
void execIndefDepthPipe(sSettings *pSettings_, sCommandList *pCommandList_){
int iPipe1[2];
int iPipe2[2];
int iStatus, iProcessId, iNumCommands = pCommandList_->iSize;
_pipe(pSettings_, iPipe1);
_pipe(pSettings_, iPipe2);
sCommand *pCommand;
do{
pCommand = popHeadNode(pCommandList_);
iProcessId = _fork(pSettings_);
if(iProcessId){ // If Parent
// continue; // Do nothing
waitpid(iProcessId, &iStatus, WUNTRACED); // It waits forever. I don't know why.
}
else { // Execute the commands as a child
if(pCommand != NULL) {
if(pCommandList_->iSize == (iNumCommands-1)) { // Exec First
//closePipe(iPipe2);
execFirst(pSettings_, pCommand, iPipe1);
}
else if(pCommandList_->iSize == 0) { // Exec Last
closePipe(iPipe1);
execLast(pSettings_, pCommand, iPipe2);
}
else { // Exec mid
execMid(pSettings_, pCommand, iPipe1, iPipe2);
}
}
_exit(0);
}
} while(pCommand != NULL);
return;
}