'Redirecting stdin in C
I am have written a function in C that emulates command line piping. Now i am trying to handle redirection using '<' and '>'. I have managed to implement redirecting stdout correctly, however I am having problems wit stdin.
The function takes 3 arguments, the list of commands, and an input and output location. These can be NULL if there is no '<' or '>' used.
I am not sure why the input is not working. When I run "wc < input_file" it just executes wc.
The code looks like this:
void pipe_function(char *** cmd, char * input, char * output)
{
int p[2];
pid_t pid;
int fd_in = 0;
int count = 0;
/* If there are no input or output destinations specified */
if ((input == NULL) && (output == NULL))
{
while (* cmd != NULL)
{
pipe(p);
if ((pid = fork()) == -1)
{
exit(EXIT_FAILURE);
}
else if (pid == 0)
{
dup2(fd_in, 0);
if (* (cmd + 1) != NULL)
{
dup2(p[1], 1);
}
close(p[0]);
execvp((* cmd)[0], * cmd);
exit(EXIT_FAILURE);
}
else
{
wait(NULL);
close(p[1]);
fd_in = p[0];
cmd++;
}
}
}
/* If there is no input destination specified but an output destination specified */
else if ((input == NULL) && (output != NULL))
{
while (* cmd != NULL)
{
pipe(p);
if ((pid = fork()) == -1)
{
exit(EXIT_FAILURE);
}
else if (pid == 0)
{
dup2(fd_in, 0);
if (* (cmd + 1) != NULL)
{
dup2(p[1], 1);
}
else
{
int file = open(output, O_WRONLY | O_CREAT, 0777);
dup2(file, 1);
close(file);
}
close(p[0]);
execvp((* cmd)[0], * cmd);
exit(EXIT_FAILURE);
}
else
{
wait(NULL);
close(p[1]);
fd_in = p[0];
cmd++;
}
}
}
/* If there is an input destination and no output destination */
/* THIS IS WHERE TROUBLE IS OCCOURING*/
else if ((input != NULL) && (output == NULL))
{
while (* cmd != NULL)
{
pipe(p);
if ((pid = fork()) == -1)
{
exit(EXIT_FAILURE);
}
else if (pid == 0)
{
if (count != 0)
{
dup2(fd_in, 0);
}
else
{
int file = open(input, O_RDONLY);
dup2(file, 0);
close(file);
}
if (* (cmd + 1) != NULL)
{
dup2(p[1], 1);
}
close(p[0]);
execvp((* cmd)[0], * cmd);
exit(EXIT_FAILURE);
}
else
{
wait(NULL);
close(p[1]);
fd_in = p[0];
cmd++;
}
count++;
}
}
/* If there is both an input and an output destination */
else
{
}
}
Any help would be greatly appreciated :)
Solution 1:[1]
It doesn't completely fix your program, but I think the main bug here is that you don't close
STDIN_FILENObefore callingdup2. Thusdup2fails, and you remain with STDIN at the 0 fd.
This is actually incorrect, dup2() closes newfd for you!
Generally, the code looks pretty good, but it's best practice to always check the return value of library functions - this would obviously have caught the bug here.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
