Reputation: 5
I have searched everywhere and the only reason I know of that I would be getting a bad file descriptor for fdUp[READ]
is if I had previously closed it. I don't believe I have done this and I cannot figure out why.
bool start_process(void) {
int fdDown[2];
int fdUp[2];
FILE* in;
FILE* out;
if(pipe(fdDown) && pipe(fdUp)) {
return false; //pipe failed
}
switch(fork()) {
case -1:
return false; //fork failed
case 0:
// child
close(fdDown[WRITE]);
dup2(fdDown[READ], STDIN_FILENO);
close(fdDown[READ]);
close(fdUp[READ]);
dup2(fdUp[WRITE], STDOUT_FILENO);
close(fdUp[WRITE]);
execlp("./process", "process1", (char *) 0);
return false; //exec failed
default:
//parent
close(fdDown[READ]);
out = fdopen(fdDown[WRITE], "w");
close(fdUp[WRITE]);
in = fdopen(fdUp[READ], "r");
if(in==NULL) printf("%s\n", strerror(errno)); //BAD FILE DESCRIPTOR
fprintf(out, "msg from parent\n");
fflush(out);
char buf[100];
fgets(buf, 100, in);
printf("%s", buf);
wait(NULL);
}
return true;
}
Upvotes: 0
Views: 234
Reputation: 121427
Your descriptors in fdUp
are indeed invalid because of the way you initialize them.
if(pipe(fdDown) && pipe(fdUp)) {
return false; //pipe failed
}
If pipe(fdDown)
succeeds (i.e., returns 0) then pipe(fdUp)
won't be executed at all (due to short-circuit evaluation).
You really want:
if(pipe(fdDown) || pipe(fdUp)) {
return false; //pipe failed
}
Another way with better diagnostics could be:
if(pipe(fdDown)) {
perror("pipe: fdDown");
return false;
}
if(pipe(fdUp)) {
perror("pipe: fdUp");
return false;
}
Upvotes: 1