Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

open() blocks when trying to open pipe for reading

Tags:

c++

linux

pipe

I have two processes, a server and a client, that should communicate via pipes (C++, Linux). The server opens the pipe with the O_RDONLY flag, and the client with O_WRONLY. However, the server blocks at the open function, while the client seems to run successfully (the open function returns success and so do the write functions).

I have read that if the O_NONBLOCK flag is set, the read function will continue, but I don't want it to continue if no client is connected - it is ok to block until a client is connected, but in my case it remains blocked even after the client finishes running...

Can you plese tell me what I'm doing wrong...?

Here is the code:

// Server side
int pipe;
int status, nr_read = 0;

status = mkfifo(FIFO_NAME, 0666);
if (status < 0)
{
    // If the file already exists, delete it
    unlink(FIFO_NAME);

    // Try again
    status = mkfifo(FIFO_NAME, 0666);

    if(status < 0)
    {
        printf("mkfifo error: %d\n", status);
        return status;
    }
}

pipe = open(FIFO_NAME, O_RDONLY);
printf("Never gets here...\n");
[...]
nr_read = read(pipe, my_char_array, CHAR_ARRAY_SIZE);
[...]
close(pipe);
unlink(FIFO_NAME);

It never gets to the "printf" line...

// Client side:
int pipe, nr_sent = 0;
int status = 0;

pipe = open(FIFO_NAME, O_WRONLY);
if (pipe < 0)
{
    printf("open fifo error: %d\n", status);
    return pipe;
}

[...]
nr_sent = write(pipe, my_char_array, CHAR_ARRAY_LENGTH);
[...]
close(pipe);

EDIT

I didn't mention the line #define FIFO_NAME "MYFIFO"

... and here was the problem: as Jody Hagins said, the path being a relative one and the processes being started from different folders, they were trying to open different files.

like image 670
Ioanna Avatar asked Sep 11 '12 13:09

Ioanna


1 Answers

The read-side will not complete a blocking open until the write-side has completed the pipe.

If you do not want this functionality, then open the read-side O_NONBLOCK, and use select to determine when the write-side has established a connection and process input accordingly.

EDIT

Oops. Just noticed that you said your server is not completing the open even after running the client. That's strange. I just cut/paste your code and after adding the missing header includes, and the missing variable/constants, ran the server/client and they operated as expected.

The server waited for the client, and when the client ran, the server completed the open and read the data.

Check your file to make sure you have an actual FIFO.

You should see something like this:

> ls -lat /tmp/FIFO
prw-r--r-- 1 user user 0 2012-09-11 10:22 /tmp/FIFO


> stat /tmp/FIFO
  File: `/tmp/FIFO'
  Size: 0               Blocks: 0          IO Block: 4096   fifo
Device: 6802h/26626d    Inode: 186603      Links: 1
Access: (0644/prw-r--r--)  Uid: (10042/ user)   Gid: (10042/ user)
Access: 2012-09-11 10:22:48.000000000 -0400
Modify: 2012-09-11 10:22:48.000000000 -0400
Change: 2012-09-11 10:22:48.000000000 -0400
like image 148
Jody Hagins Avatar answered Sep 24 '22 01:09

Jody Hagins