Reputation: 13
I have tried to do fork() and piping in main and it works perfectly fine but when I try to implement it in a function for some reason I don't get any output, this is my code:
void cmd(int **pipefd,int count,int type, int last);
int main(int argc, char *argv[]) {
int pipefd[3][2];
int i, total_cmds = 3,count = 0;
int in = 1;
for(i = 0; i < total_cmds;i++){
pipe(pipefd[count++]);
cmd(pipefd,count,i,0);
}
/*Last Command*/
cmd(pipefd,count,i,1);
exit(EXIT_SUCCESS);
}
void cmd(int **pipefd,int count,int type, int last){
int child_pid,i,i2;
if ((child_pid = fork()) == 0) {
if(count == 1){
dup2(pipefd[count-1][1],1); /*first command*/
}
else if(last!=1){
dup2(pipefd[count - 2][0],0); /*middle commands*/
dup2(pipefd[count - 1][1],1);
}
else if(last == 1){
dup2(pipefd[count - 1][0],0); /*last command*/
}
for(i = 0; i < count;i++){/*close pipes*/
for(i2 = 0; i2 < 2;i2++){
close(pipefd[i][i2]);
}}
if(type == 0){
execlp("ls","ls","-al",NULL);
}
else if(type == 1){
execlp("grep","grep",".bak",NULL);
}
else if(type==2){
execl("/usr/bin/wc","wc",NULL);
}
else if(type ==3){
execl("/usr/bin/wc","wc","-l",NULL);
}
perror("exec");
exit(EXIT_FAILURE);
}
else if (child_pid < 0) {
perror("fork");
exit(EXIT_FAILURE);
}
}
I checked the file descriptors and it is opening the right ones, not sure what the problem could be..
Edit: I Fixed the problem but I'm having child processes, which way would be the best to wait for the child , while(wait(NULL)!=-1); but that hangs
Upvotes: 1
Views: 1848
Reputation: 400156
The problem is that pipefd
is not an int**
, it's an int[3][2]
, so when you pass it to cmd
, you get garbage. Your compiler should be giving you a warning on each call to cmd()
, such as something like this:
warning: passing argument 1 of 'cmd' from incompatible pointer type
If not, turn up your warning level.
It's true that arrays decay into pointers to their first elements, so you can pass a 1-D array to a function expecting a pointer, but that's only true for the first dimension of arrays. In particular, a 2D array does not decay into a pointer to a pointer. It decays at the first level only, so pipefd
can decay into the type int (*)[2]
, which is read as "pointer to array 2 of int
"
So, the correct way to write cmd
is this:
void cmd(int (*pipefd)[2],int count,int type, int last)
Upvotes: 3