I'm building a simple command line interpreter in C, and I've encountered an issue with handling file descriptors when using pipes. The interpreter is supposed to support piped commands, but I'm running into problems with closing file descriptors correctly. Here’s a snippet of the main loop that executes commands:
for (i = 0; i < params.cnt_prog; i++) {
len = proc_len(lst);
char* buf[len + 1];
lst2buf(&lst, buf);
buf[len] = NULL;
if (i < params.cnt_prog - 1) {
pipe(i % 2 == 0 ? fd1 : fd2);
}
pid = fork();
if (pid == 0) {
/* Set child input */
if (i > 0) {
if (i % 2 == 1) {
dup2(fd1[0], 0);
close(fd1[0]);
close(fd1[1]);
} else {
dup2(fd2[0], 0);
close(fd2[0]);
close(fd2[1]);
}
} else {
close(fd1[0]);
if (!redirect_in(¶ms)) {
exit(1);
}
}
/* Set output */
if (i < params.cnt_prog - 1) {
if (i % 2 == 1) {
dup2(fd2[1], 1);
close(fd2[1]);
close(fd2[0]);
} else {
dup2(fd1[1], 1);
close(fd1[1]);
close(fd1[0]);
}
} else {
close(fd1[1]);
close(fd2[1]);
if (!redirect_out(¶ms))
exit(1);
}
execvp(buf[0], buf);
perror(buf[0]);
exit(1);
}
if (i > 0) {
if (i % 2 == 1) {
close(fd1[0]);
close(fd1[1]);
} else {
close(fd2[0]);
close(fd2[1]);
}
}
}
- params.cnt_prog is the number of commands in the pipeline (e.g., ls | grep ".c" has 2 commands), executed from command line (ls | grep ".c" will produce 2)
- I’m confident that the logic converting the list to an array (lst2buf) is correct, so the problem likely lies with how I'm managing the pipe file descriptors in the parent and child processes.
Output examples:
> ls | grep .c
grep: (standard input): Bad file descriptor
> cat main.c | wc
wc: 'standard input': Bad file descriptor
0 0 0
wc: -: Bad file descriptor
fd1andfd2? There should just be one pipe -- you use the same pipe as the stdout oflsand the stdin ofgrep.cmd1 | cmd2 | cmd3then you should have an array of pipes, since the pipeline can be arbitrarily long.main()function and at least one#include. Please edit your code so it's a minimal reproducible example of your problem (including any necessary inputs, but preferably not needing any), then we can try to reproduce and solve it. You should also read How to Ask.