Im trying to learn how to pipe and use fork in c. Im trying to pipe data from on
ID: 3726863 • Letter: I
Question
Im trying to learn how to pipe and use fork in c. Im trying to pipe data from one program to another.
im piping 2 strings to another program.
What I did was if had 2 pipe variables.
int fd1[2];
int fd2[2];
in the child, I did
close(fd1[1]);
close(fd2[1]);
dup2(fd_user[0], STDIN_FILENO);
dup2(fd_pass[0], STDIN_FILENO);
close(fd1[0]);
close(fd2[0]);
execl("./name", "./name", NULL);
in parent I had
close(fd1[0]);
close(fd2[0]);
write(fd1[1], buf1, sizeof(buf1));
write(fd2[1], buf2, sizeof(buf2));
close(fd1[1]);
close(fd2{1]);
The problem is that in my other program, when I try to read from stdin_fileno, my error handler says that nothing was read from stdin_fileno.
Explanation / Answer
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
/* max receiving buffer size; Note: no check or enforcement is made on this value*/
#define BUF_SIZE 256
int main()
{
int pfd1[2];
int pfd2[2];
ssize_t numRead = -1;
/* Note: working under the assumption that the messages
are of equal length*/
const char* messageOne = "Hello from child ONE. ";
const char* messageTwo = "Hello from child TWO. ";
const unsigned int commLen = strlen(messageOne) + 1;
char buf[BUF_SIZE];
if (pipe(pfd1) == -1)
{
printf("Error opening pipe 1! ");
exit(1);
}
if (pipe(pfd2) == -1)
{
printf("Error opening pipe 2! ");
exit(1);
}
printf("Piped opened with success. Forking ... ");
// child 1
switch (fork())
{
case -1:
printf("Error forking child 1! ");
exit(1);
case 0:
printf(" Child 1 executing... ");
/* close reading end of first pipe */
if (close(pfd1[0]) == -1)
{
printf("Error closing reading end of pipe 1. ");
_exit(1);
}
/* close writing end of second pipe */
if (close(pfd2[1]) == -1)
{
printf("Error closing writing end of pipe 2. ");
_exit(1);
}
/* write to pipe 1 */
if (write(pfd1[1], messageOne, commLen) != commLen)
{
printf("Error writing to pipe 1. ");
_exit(1);
}
if (close(pfd1[1]) == -1)
{
printf("Error closing writing end of pipe 1. ");
_exit(1);
}
/* reding from pipe 2 */
numRead = read(pfd2[0], buf, commLen);
if (numRead == -1)
{
printf("Error reading from pipe 2. ");
_exit(1);
}
if (close(pfd2[0]) == -1)
{
printf("Error closing reding end of pipe 2. ");
_exit(1);
}
printf("Message received child ONE: %s", buf);
printf("Exiting child 1... ");
_exit(0);
default:
break;
}
// child 2
switch (fork())
{
case -1:
printf("Error forking child 2! ");
exit(1);
case 0:
printf(" Child 2 executing... ");
/* close reading end of second pipe */
if (close(pfd2[0]) == -1)
{
printf("Error closing reading end of pipe 2. ");
_exit(1);
}
/* close writing end of first pipe */
if (close(pfd1[1]) == -1)
{
printf("Error closing writing end of pipe 1. ");
_exit(1);
}
/* read from the first pipe */
if (read(pfd1[0], buf, commLen) == -1)
{
printf("Error reading from pipe 1. ");
_exit(EXIT_FAILURE);
}
if (close(pfd1[0]) == -1)
{
printf("Error closing reading end of pipe 1. ");
_exit(EXIT_FAILURE);
}
/* write to the second pipe */
if (write(pfd2[1], messageTwo, commLen) != commLen)
{
printf("Error writing to the pipe.");
_exit(EXIT_FAILURE);
}
if (close(pfd2[1]) == -1)
{
printf("Error closing writing end of pipe 2.");
_exit(EXIT_FAILURE);
}
printf("Message received child TWO: %s", buf);
printf("Exiting child 2... ");
_exit(EXIT_SUCCESS);
default:
break;
}
printf("Parent closing pipes. ");
if (close(pfd1[0]) == -1)
{
printf("Error closing reading end of the pipe. ");
exit(EXIT_FAILURE);
}
if (close(pfd2[1]) == -1)
{
printf("Error closing writing end of the pipe. ");
exit(EXIT_FAILURE);
}
if (close(pfd2[0]) == -1)
{
printf("Error closing reading end of the pipe. ");
exit(EXIT_FAILURE);
}
if (close(pfd1[1]) == -1)
{
printf("Error closing writing end of the pipe. ");
exit(EXIT_FAILURE);
}
printf("Parent waiting for children completion... ");
if (wait(NULL) == -1)
{
printf("Error waiting. ");
exit(EXIT_FAILURE);
}
if (wait(NULL) == -1)
{
printf("Error waiting. ");
exit(EXIT_FAILURE);
}
printf("Parent finishing. ");
exit(EXIT_SUCCESS);
}