我的目标是编写一个程序,使用C中的匿名管道执行bash管道。
现在我用这个命令测试我的函数:ls -l | wc
[编辑],但目标是连接多个管道或只是在没有它们的情况下执行程序。
我使用的主程序调用了执行fork和exec的routines.h头文件中定义的函数:
MAIN.C
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "routines.h"
#define READ 0 // for file descriptor index
#define WRITE 1 // for file descriptor index
typedef enum eMode{ // typedef of exec modes
LEFT_PIPE=0, // cmd1|... start pipe
CENTER_PIPE=1, // cmd1|cmd2|... center pipes
RIGHT_PIPE=2, // ...|cmd2 end of the pipe
NORMAL_COMMAND=3// normal cmd
} Mode;
int main()
{
char * commandTest1[]={"ls","-l",NULL};
char * commandTest2[]={"wc",NULL};
int pipeFileDesc[2];
pipe(pipeFileDesc);
executeCommand(commandTest1,pipeFileDesc[READ],pipeFileDesc[WRITE],LEFT_PIPE);
executeCommand(commandTest2,pipeFileDesc[READ],pipeFileDesc[WRITE],RIGHT_PIPE);
return 0;
}
在Routines.c中执行命令
int executeCommand(char** args,int inputDataFD,int outputDataFD,int mode){ //inputDataFD is READ PIPE BUFFER
//outputDATA is WRITE PIPE BUFFER
int pid,retCode,status;
pid=fork(); // fork MONOLITIC: monolitic (father) remains unchanged the son will be transformed in exec of args
if(pid==-1){
perror("Fork Error, for command: ");
return 1; // TODO: in main read strerror(errno)
}else{
if(pid==0){ //son process
printf("Child process: pid %i, father pid %i , pid fork %i \n",getpid(),getppid(),pid);
////////////////////// SETTING OF STDOUT/IN REDIRECTS //////////////////////
if(mode==LEFT_PIPE){ // nothing to read for the process-> left side of the pipe -> PIPE has NO contet and another pipe is found
close(inputDataFD); //close the READ id/channel of the pipe Buffer: !!!! for a process the read side is input !!!!
dup2(outputDataFD,1); // redirects stdout on pipe write: fd 1 for every process is STDOUT, dup2 closes the file linked previously by stdout (closes stdout file)
// and assign fd=1 to the file linked by outputDataFD (pipeFileDesc[WRITE]), beacuse of that outputDataFD (pipeFileDesc[WRITE])
// is a duplicate and it can be unlinked with close()
close(outputDataFD);
}
if(mode==CENTER_PIPE){ //repiping: PIPE has contet and another pipe is found
dup2(inputDataFD,0); // redirects stdin on pipe READ: fd0 for every process is STDIN, dup2 closes the file linked previously by stdin (closes stdin file)
// and assign the file linked by inputDataFD (pipeFileDesc[READ]) to fd id=0 (where processes get data for input (exstdin)
// beacuse of that inputDataFD (pipeFileDesc[READ]) is a duplicate and it can be unlinked with close()
close(inputDataFD);
dup2(outputDataFD,1); // redirects stdout on pipe write: fd 1 for every process is STDOUT, dup2 closes the file linked previously by stdout (closes stdout file)
// and assign fd=1 to the file linked by outputDataFD (pipeFileDesc[WRITE]), beacuse of that outputDataFD (pipeFileDesc[WRITE])
// is a duplicate and it can be unlinked with close()
close(outputDataFD);
}
if(mode==RIGHT_PIPE){ //nothing to write for the process-> right side of pipe ->PIPE has contet and NO other pipe is found
close(outputDataFD); // close the WRITE id/channel of the pipe Buffer: !!! for a process the write side is output !!!!
dup2(inputDataFD,0); // redirects stdin on pipe READ: fd0 for every process is STDIN, dup2 closes the file linked previously by stdin (closes stdin file)
// and assign the file linked by inputDataFD (pipeFileDesc[READ]) to fd id=0 (where processes get data for input (exstdin)
// beacuse of that inputDataFD (pipeFileDesc[READ]) is a duplicate and it can be unlinked with close()
close(inputDataFD);
}
if(mode==NORMAL_COMMAND){ // non pipes-> no STDOUT/IN redirections -> PIPE has NO contet and NO other pipe is found
}
retCode=execvp(args[0],args); // exec command arg[0] with process name arg[0] and arg[1->i] parameters
// stdout of process is redirected onto outputDataFD that is pipeBuffer WRITE side
if(mode==RIGHT_PIPE) printf("error TWO %s",strerror(errno));
if(retCode == -1){
perror("Exec error, unable to execute:");
return 1; //smthing went wrong same TODO in main read output strerror(errno)
}
}else{ //father process
printf("Parent process: pid %i, pid fork %i \n",getpid(), pid );
waitpid(pid,&status,0); // The wait system-call puts the process to sleep and waits for a child-process to end.
// It then fills in the argument with the exit code of the child-process (if the argument is not NULL).
perror("\n");
printf("\nout of wait\n");
if(WIFEXITED(status)==1){//this macro translate the value int of status in TRUE if child ends normaly and FALSE otherwise
return WEXITSTATUS(status); //returns to the main the status of the call
}else{
printf("wait error\n");
}
}
}//end else pid==0
}//end executeCommand
所以我的问题是,当执行这个文件时,它一直运行到execvp()
的第二次调用的executeCommand()
,并且过程(孩子一个)冻结并且似乎处于睡眠状态模式。
删除等待语句有帮助,但输出错误......可能是等待问题吗?