Question

I have two functions writer() and reader(). I am writing message into the pipe from writer() function and reading it from the reader() function. The problem I am facing is that message is being written in the pipe, but it's not getting read. Maybe there is problem in opening pipe for reading. The code is:

#include<iostream>
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>

using namespace std;

//edit
int fifo = mkfifo("/tmp/mypipe", S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);

void writer()
{
    char message[] = "this is a message";
    int fd;
    fd = open("pipe" , O_WRONLY);
    write(fd , message , sizeof(message));
    cout<<"message wrote: "<<message<<"\n";     // gives output 
}                                               // message wrote: this is a message

void reader()
{
    char buffer[100];
    int fd;
    fd = open("pipe" , O_RDONLY);
    read(fd , buffer , 100);
    cout<<"message is: "<<buffer<<"\n";     // gives output
}                                           // message is:

int main()
{
    writer();
    reader();
    return 0;
}

I've debugged it, and I think the problem is, fifo is not being created correctly. I don't know how to resolve this. Need more help.

enter image description here

Thank you for any help.

Was it helpful?

Solution

My guess is that you have not created the pipe in a correct way. Take a look at the mkfifo man page. For the umask value take a look at the umask man page.

something like mkfifo("/tmp/pipe", 0666), before you open /tmp/pipe in the reader/writer.

Also take a look at the fifo man page:

The kernel maintains exactly one pipe object for each FIFO special file that is opened by at least one process. The FIFO must be opened on both ends (reading and writing) before data can be passed. Normally, opening the FIFO blocks until the other end is opened also.

So your problem now is, that the open(..., O_WRONLY) blocks until the reader opens the file.

To try it out, let just the reader run and then use echo "test" > /tmp/pipe.

Update:

Or use threads, i just tried it out.

int main() {
    mkfifo(fifo_name.c_str(), 0666);
    std::thread w(writer);     
    std::thread r(reader); 
    w.join();
    r.join();
    unlink(fifo_name.c_str());
    return 0;
}

you also have to #include <thread>, add this compiler flag: -std=c++0x and add the following library to the linker: -lpthread.

OTHER TIPS

Be sure to check returns from function calls, since they can tell you what the problem is.

Include errno.h:

#include <errno.h>
#include <string.h>

And check errno when you get an error return from your write or read open attempt:

fd = open("pipe" , O_WRONLY);
if (fd < 0)
{   
    cout << "writer open failed: " << errno << "(" << strerror(errno) << ")\n";
    /* exit */
}   

As another answer states, you're not using mkfifo(), so you're making a typical file (which would also work but may fail if you don't provide O_CREAT and a mode argument).

It is about how named pipe work in posix. You can only write in it, if there is already somebody, who is reading from it. If there is none, your write() operation will be blocked until somebody don't read.

The simplest solution were, if

  1. You used nonblocking I/O
  2. You implemented the reader and the writer in different processes (threads) and called the reader before the writer.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top