I have two processes, father and child, that need to execute two commands, synchronizing with pipes. A text file containing these commands on two different lines is given in input to the program. So it would be something like this:
ps aux
wc -l
I found other questions about more or less the same problem but I haven't figured out what could be wrong here.
void write_to_pipe(int pipeIn[], char *commands_file){
FILE *command_stream ;
char *line = NULL ; //contains the first command
char *command, *options[200] ;
int i = 0 ;
close(STDOUT_FILENO);
if(dup(pipeIn[1])== -1){
perror("Duplication failed");
exit(1);
}
close(pipeIn[0]);
close(pipeIn[1]);
command_stream = fopen(commands_file,"r");
if (getline(&line, 0, command_stream)!= -1){
fclose(command_stream);
command = strtok(line," ");//tokenize string with a separator
options[i++] = command ;
while((options[i] = strtok(line," "))!= NULL){
i++ ;
}
execvp(command, options);
perror("execvp failed");
exit(1);
}
}
This function uses dup to redirect stdout to the pipe. Then, it opens the file in input and calls execvp using the first token of the line as the command and the rest as arguments. The read function is very similar
void read_from_pipe(int pipeIn[], char *commands_file){
FILE *command_stream ;
char *line = NULL ; //contains the second command
char *command, *options[200] ;
int i = 0 ;
close(STDIN_FILENO);
if(dup(pipeIn[0])== -1){
perror("Duplication failed");
exit(1);
}
close(pipeIn[1]);
close(pipeIn[0]);
command_stream = fopen(commands_file,"r");
getline(&line, 0, command_stream);
if (getline(&line, 0, command_stream)!= -1){
fclose(command_stream);
command = strtok(line," ");//tokenize string with a separator
options[i++] = command;
while((options[i] = strtok(line," "))!= NULL){
i++ ;
}
execvp(command, options);
perror("execvp failed");
exit(1);
}
}
The only difference being that getline is called once more to skip the first line, because the reader has to execute the second command. And then there's the main:
int main(int argc, char *argv[]){
//if no file is given the program does nothing
if (argv[1]){
pid_t pid ;
int mypipe[2] ;
if (pipe(mypipe)){
//pipe creation has failed
perror("Pipe creation failed");
exit(1);
}
pid = fork();
switch(pid){
case 0:
read_from_pipe(mypipe,argv[1]);
break;
case -1:
perror("Fork failed");
break;
default:
write_to_pipe(mypipe,argv[1]);
break;
}
}
return 0 ;
}
The program compiles and it runs but it outputs nothing.
[Edit] Adjusted execvp to have the command in the arguments array and checked for errors with dup. Still gives no output.