How to append into a named pipe without changing the value stored previously (linux)(named pipes)

332 Views Asked by At

I am creating 10 children to one parent. I want all the children to write into a pipe appending the pipe, so I can then read the collective data later in the parent. So first child writes into the pipe "9-6" then the second child writes "9-6" making the contents inside the pipe "9-6 9-6" but what I have discovered here is that Every child when open the pipes for writing inside it. It truncates the pipe. Is there a way I can just keep on adding content into the pipe and eventually in the end just read it.

#include  <fcntl.h>                              //
#include  <stdio.h>                              //
#include  <stdlib.h>                             //
#include  <string.h>                             //
#include  <sys/types.h>                          //
#include  <sys/wait.h>                           //
#include  <sys/stat.h>                           //
#include  <termios.h>                            //
#include  <unistd.h> 
#include <iostream> 

using namespace std;


int main()
{
    pid_t pids[10]; //10 children
    int i;
    int n = 10;
    

    int f1 = mkfifo("p", 0666);   //making named pipe                                   
    
    if (f1 < 0)
        std::cerr << "Pipe not created";

    char str[256] = "9-6";   //character array that every child writes in the pipe
    char read_char[256] = "";                                            
    /* Start children. */
    for (i = 0; i < 10; ++i) {
        if ((pids[i] = fork()) < 0) {
            perror("fork");
            abort();
        }
        else if (pids[i] == 0) {\

            int fifo_write = open("p", O_WRONLY); //open the pipe for writing
            if (fifo_write < 0)
            {
                std::cerr << "Pipe could not be created";
                return 0;
            }
            else
            {
               
                write(fifo_write, str, sizeof(str)); //write char str[] and close the pipe
                close(fifo_write);
                exit(0); 
            }
            
            
        }

    }

    
    

    /* Wait for children to exit. */
   
    int count(0); 
    int fifo_read = open("p", O_RDONLY);
    char str1[256] = ""; 
    if (fifo_read < 0)
    {
        std::cerr << "Pipe could not be created";
    }
    else
    {
            
        read(fifo_read, str1, sizeof(str));
        cout << str1 << endl;
        count++; 
        close(fifo_read);
    }
    cout << "the count is " << count << endl; 
    unlink("p");
}

I have also tried first reading the pipe and appending what is read from the pipe with "9-6" and then writing in the pipe again. The implementation of that looks like this

#include  <fcntl.h>                              //
#include  <stdio.h>                              //
#include  <stdlib.h>                             //
#include  <string.h>                             //
#include  <sys/types.h>                          //
#include  <sys/wait.h>                           //
#include  <sys/stat.h>                           //
#include  <termios.h>                            //
#include  <unistd.h> 
#include <iostream> 

using namespace std;





int main()
{
    pid_t pids[10];
    int i;
    int n = 10;
    

    int f1 = mkfifo("p", 0666);                                         //Making named pipe
    
    if (f1 < 0)
        std::cerr << "Pipe not created";

    char str[256] = "9-6";   
    char read_char[256] = "";                                            
    /* Start children. */
    for (i = 0; i < 10; ++i) {
        if ((pids[i] = fork()) < 0) {
            perror("fork");
            abort();
        }
        else if (pids[i] == 0) {
//here I open the pipe for read so that I can read what inside and concatenate it with 9-6 //so every time it is concatenated with 9-6 and written back in the pipe
            int fifo_read = open("p", O_RDONLY); 
            if (fifo_read < 0)
            {
                std::cerr << "Pipe could not be created";
                return 0;
            }
            else
            {
                read(fifo_read, read_char, sizeof(read_char)); 
                strcat(str, read_char); 
                close(fifo_read); 

            }
            int fifo_write = open("p", O_WRONLY);
            if (fifo_write < 0)
            {
                std::cerr << "Pipe could not be created";
                return 0;
            }
            else
            {
               
                write(fifo_write, str, sizeof(str));
                close(fifo_write);
                exit(0); 
            }
            
            
        }

    }

    
    

    /* Wait for children to exit. */
   
    int count(0); 
    int fifo_read = open("p", O_RDONLY);
    char str1[256] = ""; 
    if (fifo_read < 0)
    {
        std::cerr << "Pipe could not be created";
    }
    else
    {
            
        read(fifo_read, str1, sizeof(str));
        cout << str1 << endl;
        count++; 
        close(fifo_read);
    }
    cout << "the count is " << count << endl; 
    unlink("p");
}

But when I do this mkfifo fails and "pipe not created" is printed

0

There are 0 best solutions below