I'm trying to create two-way communication between parent and child processes using 2 pipes in C.the prog1 running in child1
I want to read 3+4+5 from prog1 after that send something to prog1 with write but I could not.
Where is the wrong?
/* prog1.c */
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
void
main(void){
int FD;
unsigned int buf;
char buf[15];
printf("7+5+11=?\n");
FD=read(0,buf,10);
if(FD<0){
perror("FAIL\n");
exit(EXIT_FAILURE);
}
printf("TAKED:%s\n",buf);
}
prog2.c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
void ERR_SYS(const char *msg);
int
main(void){
char buf[15];
int pipe1[2];
int pipe2[2];
pid_t childpid;
memset(buf,'\0',14);
if(pipe(pipe1) < 0 || pipe(pipe2) < 0)
ERR_SYS("fail_pipe");
if((childpid = fork()) < 0)
ERR_SYS("fail_fork");
if(childpid==0)
{
dup2(pipe2[1],1);
dup2(pipe1[0],0);
close(pipe1[1]);
close(pipe2[0]);
close(pipe2[1]);
close(pipe1[0]);
//close(1);
//close(0);
execle("./prog1",NULL,NULL,NULL);
}else{
close(pipe1[0]);
close(pipe2[1]);
read(pipe2[0],buf,4); /*I hope to read 3+4+5*/
printf("BuF::%s\n",buf);
write(pipe1[1],"off",3);/*send {off}*/
wait(NULL);
}
return 0;
}
void
ERR_SYS(const char *msg)
{
perror(msg);
exit(EXIT_FAILURE);
}
There are few problems with your program:
You are not checking returned values of read, write and execle in prog2.c
You are sending "7+5+11=?\n" string which is 10 characters long but only expecting 4 characters ( 3+4+5 is not even four characters ).
Also "off" you are sending is 3 characters long but without including null termination.
When you read from an fd you will in both cases not get null terminated string and then you are trying to printf it. It's a quick way to undefined behaviour. Put an '\0' after the end of buffer you read from any file descriptor!
Especially what read returns is very important as it tells you how many characters were read. You should never ignore returned value of read (in some cases it's the same with write function).
Next time also provide some output of your program as it will be easier to give some help.
I didn't follow all your logic in setting up the pipes, so I modified and hopefully clarified your original. I should note that for whatever reason I named fd_in and fd_out from the external program's (prog1) point of view (e.g. fd_out is where prog1 is writing to, fd_in is where prog1 is reading from).
Here's the contents of my prog3.c:
...
#define READ_END 0
#define WRITE_END 1
void ERR_SYS(const char *msg);
int main(void) {
char buff[15];
char *msg = "hello";
int fd_out[2];
int fd_in[2];
int nbytes;
pid_t childpid;
if(pipe(fd_out) < 0 || pipe(fd_in) < 0) {
ERR_SYS("fail_pipe");
}
if((childpid = fork()) < 0) {
ERR_SYS("fail_fork");
}
if(childpid==0) { //child
//connect the write end of fd_out to stdout
dup2(fd_out[WRITE_END], STDOUT_FILENO);
close(fd_out[WRITE_END]);
//connect the read end of fd_in to stdin
dup2(fd_in[READ_END], STDIN_FILENO);
close(fd_in[READ_END]);
//the exec'd prog1 will inherit the streams
execlp("./prog1", "prog1", NULL); //TODO: check return
} else { //parent
nbytes = write(fd_in[WRITE_END], msg, strlen(msg));
//TODO: handle any errors from write
nbytes = read(fd_out[READ_END],buff,sizeof(buff)-1);
//TODO: handle any errors from read
buff[nbytes] = '\0';
printf("contents of buff::%s",buff);
}
return 0;
}
void ERR_SYS(const char *msg) {
perror(msg);
exit(EXIT_FAILURE);
}
And here's the contents of my prog1.c
int main(void){
char buff[15];
int nbytes;
nbytes = read(STDIN_FILENO, buff, sizeof(buff)-1);
buff[nbytes] = '\0';
printf("%s world\n", buff);
return 0;
}
Related
Referring to following code example, I want the main thread to supply the number num that the child thread is expecting using scanf.
I tried this way to write the wordcount (9) to stdin which is to be read by child thread, but it is not working.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
void* child_thread_func(void* terminalflag)
{
int num=0;
printf("Trying to read num from stdin\n");
scanf("%d",&num);
/*expecting 9 to be printed here*/
printf("Entered number is %d\n", num);
}
int main () {
pthread_t tid;
if (pthread_create(&tid, NULL, &child_thread_func, NULL) != 0) {
printf("Failed to initialize thread\n");
exit(1);
}
sleep(2);
char buffer[50];
FILE *wfp = popen("wc -c", "w");
if (wfp != NULL) {
sprintf(buffer, "dummyword");
int save_stdin = dup(fileno(stdin));
dup2(fileno(wfp), fileno(stdin));
fwrite(buffer, sizeof(char), strlen(buffer), wfp);
dup2(save_stdin, fileno(stdin));
pclose(wfp);
}
pthread_join(tid, NULL);
}
Can someone suggest a correct way or any other alternative way to do this?
Thanks.
I don't think there is any good way for a process to write text to its own stdin; stdin is meant to be a way for the parent process (or the user, if the parent process is a Terminal window) to send data to your process, not for your process to send data to itself.
However, you could achieve a similar result by having your child thread use select() or similar to read input from both stdin and from the output end of a pipe; then your parent process can send data to the child process by writing to the input end of that same pipe.
Below is a modified version of your program demonstrating the technique. Note that the child thread will print out any text that you type into stdin; and also the main thread will send a line of text to the child thread once every 5 seconds, and the child thread will also print out that text. After the main thread has sent 5 messages to the child thread, the main thread will close its end of the pipe, causing the child thread to exit and then the process can exit cleanly as well.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/select.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
static int pipeReadFD = -1;
static int ReadTextFrom(const char * descriptionOfSender, int fd)
{
char buf[256];
const int numBytesRead = read(fd, buf, sizeof(buf)-1); // -1 so we always have room to place NUL terminator byte
if (numBytesRead > 0)
{
buf[numBytesRead] = '\0'; // make sure the string is NUL-terminated
printf("ReadTextFrom(): Read %i bytes from [%s]: [%s]\n", numBytesRead, descriptionOfSender, buf);
}
return numBytesRead;
}
void* init_on_sys_ready(void* terminalflag)
{
int num=0;
printf("Child thread: trying to read text from stdin\n");
while(1)
{
const int stdinFD = fileno(stdin);
const int maxFD = (pipeReadFD > stdinFD) ? pipeReadFD : stdinFD;
fd_set readFDSet;
FD_ZERO(&readFDSet);
FD_SET(stdinFD, &readFDSet);
FD_SET(pipeReadFD, &readFDSet);
const int selRet = select(maxFD+1, &readFDSet, NULL, NULL, NULL);
if (selRet >= 0)
{
if ((FD_ISSET(stdinFD, &readFDSet))&&(ReadTextFrom("stdin", stdinFD) <= 0)) break;
if ((FD_ISSET(pipeReadFD, &readFDSet))&&(ReadTextFrom("pipe", pipeReadFD) <= 0)) break;
}
else
{
perror("select");
break;
}
}
printf("Child thread exiting!\n");
return NULL;
}
int main(int argc, char ** argv)
{
int pipeFDs[2];
if (pipe(pipeFDs) < 0)
{
perror("pipe");
return -1;
}
pipeReadFD = pipeFDs[0];
int pipeWriteFD = pipeFDs[1];
pthread_t tid;
if (pthread_create(&tid, NULL, &init_on_sys_ready, NULL) != 0) {
printf("Failed to initialize CLI\n");
exit(1);
}
int count = 0;
for (int count=0; count < 5; count++)
{
char buf[512];
snprintf(buf, sizeof(buf), "Hello #%i from main thread", ++count);
const size_t slen = strlen(buf);
if (write(pipeWriteFD, buf, slen) == slen)
{
printf("main() sent [%s] to the child thread via the pipe.\n", buf);
}
else
{
perror("write");
break;
}
sleep(5);
}
close(pipeWriteFD); // this will cause the child thread to exit ASAP
pthread_join(tid, NULL);
return 0;
}
popen's man states:
[...] the command's standard output is the same as that of the process that called popen()
So you just need a way to redirect stdout to stdin.
Which is exactly what pipe is for. It links an output fd with an input fd.
As pipe creates new fds, we need to use dup2 to replace stdin and stdout, as you've already did in your example code. Threads share the same memory, so you don't have to worry about any child/parent differences in fds.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
void* child_thread_func(void* terminalflag)
{
int num=0;
printf("Trying to read num from stdin\n");
scanf("%d",&num);
/*expecting 9 to be printed here*/
printf("Entered number is %d\n", num);
}
int main () {
setbuf(stdin, NULL);
pthread_t tid;
if (pthread_create(&tid, NULL, &child_thread_func, NULL) != 0) {
printf("Failed to initialize thread\n");
exit(1);
}
int save_stdin = dup(STDIN_FILENO);
int save_stdout = dup(STDOUT_FILENO);
int tube[2];
pipe(tube);
dup2(tube[0], STDIN_FILENO);
dup2(tube[1], STDOUT_FILENO);
char buffer[50] = {0};
FILE *wfp = popen("wc -c", "w");
if (wfp != NULL) {
sprintf(buffer, "dummyword");
fwrite(buffer, sizeof(char), strlen(buffer), wfp);
pclose(wfp);
}
dup2(save_stdin, STDIN_FILENO);
dup2(save_stdout, STDOUT_FILENO);
pthread_join(tid, NULL);
}
I can't get this basic communication to work.
All I want to do, is send information via the child's stdout to the parents file descriptor.
I am getting a seg fault.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define READ 0
#define WRITE 1
int main(void){
int fdRead[2];
int pid, i, num;
FILE* output;
char mystring [100];
char c;
pid = fork();
if(pid){
FILE * read;
close(fdRead[WRITE]);
read = fdopen(fdRead[READ], "r");
fgets(mystring,100, read);
printf("parent %d",mystring );
} else {
/* child */
dup2(fdRead[WRITE], STDOUT_FILENO);
close(fdRead[READ]);
close(fdRead[WRITE]);
printf("child" );
}
exit(0);
}
Your code does nothing about pipe.
Code for communicating between parent and child processes using pipe looks as follows
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#define READ 0
#define WRITE 1
int main(void){
int pipefd[2];
pid_t pid;
int i, num;
if (pipe(pipefd)<0) { /* create pipe */
perror("pipe");
exit(-1);
}
char mystring [100];
char c;
pid = fork();
if(pid<0){
perror("fork");
exit(-1);
} else if (pid=1) { /* parent */
char *mystring = "message to child";
write(pipefd[WRITE],mystring,strlen(mystring);
sleep(1); /* wait for child read message */
char buf[128]; /* buffer to receive data from child */
read(pipefd[READ],buf, sizeof buf);
close(pipefd[READ]);
close(pipefd[WRITE]);
printf("Returned from child %s",buf );
return 0;
} else { /* child */
char *s="send from child: ";
char buf[128];
read(pipefd[READ],buf, sizeof buf);
write(pipefd[WRITE],s,strlen(s));
close(pipefd[READ]);
close(pipefd[WRITE]);
return 0;
}
}
I have a problem where I must implement a key logger into a shell we have made in class. I am having trouble getting the flow of the program within a while loop to continue looping after a child process is created and it has ran execlp().
Here is a simple program I have made to work on the part I am having trouble with.. My main program, pipe.c, includes the parent/child process with a while loop that "should" continue getting an input from the user with fgets(), create a child process, use dup2(), write to stdout, then the child process invoke the receive.c executable which will get the input from stdin and display it..
/* file: pipe.c */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main() {
int key_logger_on = 0;
int p[2];
pid_t pid;
char str[256];
char input[1024];
int status;
char * file = "test.txt";
printf("Input :: ");
while(fgets(input, sizeof(input), stdin)) {
if (pipe(p)==-1) {
perror("Pipe create error");
exit(1);
}
if ((pid=fork())==-1) {
perror("Fork create error");
exit(1);
}
if (pid==0) {
close(p[1]); // Close write
dup2(p[0],0);
close(p[0]);
execlp("receive",file,NULL);
}
else {
close(p[0]); // Close read
fflush(stdout);
dup2(p[1],1);
close(p[1]);
write(1, input, strlen(input)+1);
waitpid(pid, NULL, 0);
}
printf("Input :: ");
}
}
Here is the simple receive.c that gets the stdin of the input and displays it. The file is just a test of passing a parameter.
/* file: receive.c */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
char input[256];
fgets(input, sizeof(input), stdin);
printf("FILE: %s RECEIVE: %s", argv[0],input);
return 0;
}
Right now, all this does for me is when ran the first time, it gets the input, sends it to stdout, child calls receive, prints out the input, and then the whole parent program exits, the while loop is ignored, everything just ends. I'm very new to forks and pipes so this is very frustrating to deal with! Even made me post a question on here for the first time! Thank you very much in advance.
Did it today as repetition task for me . CHeck this code . I tested it with your receive too :
#define PREAD 0
#define PWRITE 1
/*
*
*/
int main(int argc, char** argv) {
int key_logger_on = 0;
int pIn[2];
int pOut[2];
pid_t pid;
char str[256];
char input[1024] = "";
int status;
char file[] = "test.txt";
char buf;
printf("Input :: ");
while (fgets(input,sizeof(input),stdin)) {
char nChar;
int nResult;
if (pipe(pIn) < 0) {
perror("allocating pipe for child input redirect");
return -1;
}
if (pipe(pOut) < 0) {
close(pIn[PREAD]);
close(pIn[PWRITE]);
perror("allocating pipe for child output redirect");
return -1;
}
pid = fork();
if ( pid==0) {
// child continues here
// redirect stdin
if (dup2(pIn[PREAD], 0) == -1) {
perror("stdin");
return -1;
}
// redirect stdout
if (dup2(pOut[PWRITE], 1) == -1) {
perror("stdout");
return -1;
}
// redirect stderr
if (dup2(pOut[PWRITE], 2) == -1) {
perror("stderr");
return -1;
}
// all these are for use by parent only
close(pIn[PREAD]);
close(pIn[PWRITE]);
close(pOut[PREAD]);
close(pOut[PWRITE]);
// run child process image
nResult = execl("receive",file,NULL);
exit(nResult);
} else if (pid > 0) {
// parent continues here
// close unused file descriptors, these are for child only
close(pIn[PREAD]);
close(pOut[PWRITE]);
write(pIn[PWRITE], input, strlen(input));
// char by char reading
while (read(pOut[PREAD], &nChar, 1) == 1) {
write(STDOUT_FILENO, &nChar, 1);
}
// close we done
close(pIn[PWRITE]);
close(pOut[PREAD]);
}
printf("Input :: ");
}
}
I have a simple setup for a fork and pipe that I have used before. But this time around I'm getting a SIGPIPE in my write call. Here's the code
int fd[2];
int pid;
if (pipe(fd) == -1) {
perror("pipe init error");
exit(1);
}
// signal(SIGPIPE, SIG_IGN);
if ((pid = fork()) < -1) {
perror("fork error"); exit(1);
}
// parent
else if (pid > 0) {
close(fd[0]);
write(fd[1], "WHAT", MAXWORD); //SIGPIPE here
close(fd[1]);
int status;
wait(&status);
}
// child
else {
close(fd[1]);
// void foo(char *dirname, int in, int out);
// foo takes a path, reads from fd 'in' and outputs to 'fd' out
foo("./some/path", fd[0], 1);
close(fd[0]);
}
Here's function foo:
void foo(char *dirname, int in, int out){
int string_length;
char word[MAXWORD];
// to get rid of \n
char* sep;
sep = malloc(sizeof(char));
// read from piped stdin until it's closed
while ((string_length = read(in, word, MAXWORD)) > 0){
// get rid of \n
sep = strchr(word, '\n');
*sep = '\0';
printf("THe word is: %s\n", word);
}
}
If you get SIGPIPE when you write on a pipe, it means there is no process that can read from the pipe: neither the current process (you've close the read end of the pipe — which is good; you'd be deadlocked instead of dead if you'd not closed it) nor the other (child) process.
Since you've not shown what the function foo() does, we can't tell you any more about what's wrong.
Now that foo() has been added, it is not clear what's up. There are issues, but most are not show stoppers.
Argument dirname is unused.
Argument out is unused.
You leak the memory allocated to sep in the loop.
You do not ensure that the string read from the pipe is null terminated. This could lead to crashes, which in turn would lead to writes failing.
I suspect item 4 is the immediately critical issue; the others are more matters of tidiness.
I note that in the main code, you have:
write(fd[1], "WHAT", MAXWORD); //SIGPIPE here
Unless MAXWORD is either 4 or 5, you are on a losing path; you should only write 4 or 5 characters.
Combined with the read()...the read will attempt to read MAXWORD bytes but might get fewer. However, there's no sign that the data written contains a newline, so the search for a newline in the input is not going to work reliably. However, that problem should manifest itself after the pipe was successfully written too, not before.
I note that the variable int fd_parent_write_word[2]; is unused and the code uses variable int fd[2] without declaring it.
It is a nuisance when what you get to analyze is not an SSCCE (Short, Self-Contained, Correct Example). It is so much easier when the test case has been reduced to a simple program that can be compiled and run with the submitter confident that the problem reproduces with it.
This SSCCE code compiles cleanly and runs OK:
#include <assert.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
enum { MAXWORD = 5 };
static void foo(int in);
static void he_who_pays_the_piper(int signum)
{
assert(signum == SIGPIPE);
const char msg[] = "Received signal SIGPIPE\n";
write(2, msg, sizeof(msg)-1);
exit(1);
}
int main(void)
{
int fd[2];
int pid;
if (pipe(fd) == -1) {
perror("pipe init error");
exit(1);
}
signal(SIGPIPE, he_who_pays_the_piper);
if ((pid = fork()) < -1) {
perror("fork error"); exit(1);
}
else if (pid > 0) {
close(fd[0]);
write(fd[1], "WHAT", MAXWORD); //SIGPIPE here
close(fd[1]);
int status;
pid = wait(&status);
printf("Got status 0x%04X from %d\n", status, pid);
}
else {
close(fd[1]);
foo(fd[0]);
close(fd[0]);
}
return 0;
}
static void foo(int in)
{
int string_length;
char word[MAXWORD];
while ((string_length = read(in, word, MAXWORD)) > 0)
printf("The word is: %.*s\n", string_length, word);
}
Example output:
The word is: WHAT
Got status 0x0000 from 49458
Note that this works because the '\0' at the end of the string WHAT is written to the pipe, and read from the pipe. Most usually, you do not write the strings including the trailing '\0'.
I have a program that takes two files as an argument. The first file is to be copied into the second. The program forks into 2 children, the first child reads file and throws it thru the pipe to the other, then the other child writes it out to a file. The two files are supposed to be identical in the end.
When I run diff to compare the two files I get the following error:
virtual#ubuntu:~/Documents/OSprojects$ ./parent test.txt test2.txt
virtual#ubuntu:~/Documents/OSprojects$ cat test.txt
123456789112233445566778899
virtual#ubuntu:~/Documents/OSprojects$ cat test2.txt
123456789112233445566778899
virtual#ubuntu:~/Documents/OSprojects$ diff test.txt test2.txt
Binary files test.txt and test2.txt differ
virtual#ubuntu:~/Documents/OSprojects$
As you can see they are both the same, but the diff prints out that they are different. Obviously its just something I don't understand about the diff cmd. Any help would be appreciated.
I believe for some reason the file I create is a binary file whereas the first file is not, but I am unaware as to why it is a binary file. I believe it might have to do with this line of code:
write(1, buf, BUF_SIZE); //write to buffer
memset(buf, '\0', BUF_SIZE);
In one of the children this is writing out to the buffer then I am clearing the buffer. Am I clearing out that buffer wrong?
Here is the result of cat -e:
virtual#ubuntu:~/Documents/OSprojects$ cat -e test2.txt
123456789112233445566778899$
^#^#^#^#virtual#ubuntu:~/Documents/OSprojects$
Here is the result of cmp:
virtual#ubuntu:~/Documents/OSprojects$ cmp test.txt test2.txt
cmp: EOF on test.txt
virtual#ubuntu:~/Documents/OSprojects$
I believe that is my problem, how can I clear out that buffer so it doesn't throw those at the end?
ALL OF MY CODE::
Parent:
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#define BUF_SIZE 16
void exitWithError(char* errorMsg, int exitWith); //generic error out function
void launch_writer(const char* pathname, char* const argv[], int pfd[]);
void launch_reader(const char* pathname, char* const argv[], int pfd[]);
int main(int argc, char* argv[]){
//making the pipe
int pfd[2];
if(pipe(pfd) == -1) //test pipe creation
exitWithError("PIPE FAILED", 1);
//forking
pid_t reader_child_pid;
pid_t writer_child_pid;
//args for each fork
char *args_1[] = {"reader", argv[1], (char *) 0};
char *args_2[] = {"writer", argv[2], (char *) 0};
if((writer_child_pid = fork()) == -1) {
exitWithError("WRITER FORK FAILED", 1);
}
else if (writer_child_pid == 0) { //first child comes here
launch_writer("./writer", args_2, pfd);
}
else if ((reader_child_pid = fork()) == -1) {
exitWithError("READER FORK FAILED", 1);
}
else if (reader_child_pid == 0) { //second child comes here
launch_reader("./reader", args_1, pfd);
}
//parent picks up here
//close off pipe from parents end
close(pfd[0]);
close(pfd[1]);
//wait for all processes to exit before ending
for(;;) {
if(wait(NULL) == -1){
if(errno == ECHILD)
exit(0);
else {
exitWithError("WAIT ERROR", 1);
}
}
}
}
void exitWithError(char* errorMsg, int exitWith) {
perror(errorMsg);
exit(exitWith);
}
void launch_writer(const char* pathname, char* const argv[], int pfd[]) {
dup2(pfd[0], 0);
close(pfd[1]);
close(pfd[0]);
execve(pathname, argv, NULL);
perror("execve failed");
}
void launch_reader(const char* pathname, char* const argv[], int pfd[]) {
dup2(pfd[1], 1);
close(pfd[1]);
close(pfd[0]);
execve(pathname, argv, NULL);
perror("execve failed");
}
Child 1:
#include <unistd.h>
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#define BUF_SIZE 16
int main(int argc, char* argv[]){
//Opens file to be read from
int inFile = open(argv[1], O_RDONLY);
//declaring variables
char buf[BUF_SIZE]; //temp hold whats read/written
int read_test; //check if EOF
for(;;) {
read_test = read(inFile, buf, BUF_SIZE); //read from file
if(read_test == 0) //eof
break;
write(1, buf, BUF_SIZE); //write to buffer
memset(buf, '\0', BUF_SIZE);
}
close(inFile);
exit(0);
}
Child 2:
#include <unistd.h>
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#define BUF_SIZE 16
int main(int argc, char* argv[]){
//Opens a file for reading/writing, if exists then truncates, otherwise makes new one
//with correct permissions
int wri_inFile = open(argv[1], O_WRONLY | O_CREAT | O_TRUNC , S_IRUSR | S_IWUSR);
if(wri_inFile == -1)
perror("ERROR OPENING FILE");
//declaring variables
char buf[BUF_SIZE]; //to store what is read in/written out
int read_test; //test if EOF
for(;;) {
read_test = read(0, buf, BUF_SIZE); //read from buffer
if(read_test == 0) //eof
break;
write(wri_inFile, buf, BUF_SIZE); //write to file
}
close(wri_inFile);
exit(0);
}
You don't check (and use) the read data length. Therefore, your data gets padded with garbage.
There should be actual data bytes read (read_test):
read_test = read(0, buf, BUF_SIZE); //read from buffer
if(read_test == 0) //eof
break;
write(wri_inFile, buf, BUF_SIZE); //write to file
-----------------------^^^^^^^^
The same applies to the other child. You should also check the error conditions.