We help IT Professionals succeed at work.

We've partnered with Certified Experts, Carl Webster and Richard Faulkner, to bring you a podcast all about Citrix Workspace, moving to the cloud, and analytics & intelligence. Episode 2 coming soon!Listen Now

x

FIFO O_RDWR

waslap
waslap asked
on
Medium Priority
966 Views
Last Modified: 2013-12-26
When I open a FIFO with O_RDWR and I write to it and then do a select on it to read, select immediately returns saying there is something. When I read, I get what I've just written. This continues untill the process on the other side reads from the FIFO. Thus, the writer reads his own writing numerous times. It isn't removed from the FIFO however until the other side reads it. Is there some way around this.
Comment
Watch Question

dhm

Commented:
This sounds like an OS bug.  I just wrote a quickie read/write program under Solaris-2.5.1 and it behaves as expected: once you read the message out of the FIFO, it's gone -- nobody else gets it (including the process that *wrote* it there in the first place.)

What OS are you using?

Author

Commented:
I'm using Lunix. Might be that I'm doing something really stupid causing this.
Could you show the rilevant code?
-julio
dhm

Commented:
I tried the program below on one of my Linux boxes, but got nothing unusal.  Are you doing something different?  Or maybe just using a different version of the OS?

dhm@warthog[77]$ uname -a
Linux warthog.foobar.com 2.0.26 #9 Sun Apr 20 21:38:24 PDT 1997 i586

#include <sys/types.h>
#include <sys/time.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>

#define ASSERT(cond)    do if (!(cond)) { \
                            int e = errno; \
                            printf( "Assertion failed: " #cond " errno %d\n", \
                                    e ); \
                            exit( e ); \
                        } while (0)

int
main( int argc, char **argv )
{
    int      fd;
    ssize_t  wrote;
         
    fd = open( "/tmp/fifo", O_RDWR );
    ASSERT( fd != -1 );

    wrote = write( fd, "Hello, world\n", 13 );
    ASSERT( wrote == 13 );

    for ( ; ; ) {
        int              n;
        fd_set           readable;
        struct timeval   one_second;

        FD_ZERO( &readable );
        FD_SET( fd, &readable );
        one_second.tv_sec = 1;
        one_second.tv_usec = 0;
       
        n = select( fd + 1, &readable, 0, 0, &one_second );

        ASSERT( n != -1 );

        if (n == 1) {
            char     buf[8];
            ssize_t  red;
           
            red = read( fd, buf, sizeof(buf) );
            ASSERT( red != -1 );
           
            printf( "A: read %d: [%.*s]\n", red, red, buf );
        } else {
            puts( "A: nothing readable" );
        }
    }

    exit( 0 );
}

Here's what happens when I run it:

dhm@warthog[79]$ mkfifo /tmp/fifo
dhm@warthog[80]$ ./a.out
A: read 8: [Hello, w]
A: read 5: [orld
]
A: nothing readable
A: nothing readable
A: nothing readable

[...]
This is correct behaviour for a fifo - it doesnt care who is reading and who is writing to it. This makes them inappropriate for two way communications - they are usually used when a signle program reads from it, and a lot of programs write to it.

If you want two-way communications either use two fifos - one for incomming and one for outgoing messages (yuck) - or use unix domain sockets, which are designed with this particular use in mind.

Sigma_

Not the solution you were looking for? Getting a personalized solution is easy.

Ask the Experts

Author

Commented:
OK. If it is FIFO's behaviour, why does select keep on saying that there is still something to read even after the original writer did read it. It only stops saying that after the real reader on the other side has read from the FIFO.
dhm

Commented:
In my test program, select *doesn't* return "readable."  Are you select()ing on other conditions (writable, exceptions) as well as readable?  Maybe it's another condition that's unblocking the select(). If your read() is actually failing but you don't notice, then whatever was read on the first pass will still be in the buffer; if you print it out, it'll look like you got the same message over and over again.
Whoops, mommy did always say to read things carefully. I'm not sure why you are having problems with select, dim's ideas sound pretty good. But you know, you dont actually need to use select (unless you want to do something useful while waiting for input). A read on a fifo will block until another process writes to it. Also, if you dont accept my answer, you'd do well to reject it (I know this sounds awfully harsh), this will give dim a chance.
dhm

Commented:
That's dHm, not dIm! :-)
Access more of Experts Exchange with a free account
Thanks for using Experts Exchange.

Create a free account to continue.

Limited access with a free account allows you to:

  • View three pieces of content (articles, solutions, posts, and videos)
  • Ask the experts questions (counted toward content limit)
  • Customize your dashboard and profile

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.