waslap
asked on
FIFO O_RDWR
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.
ASKER
I'm using Lunix. Might be that I'm doing something really stupid causing this.
Could you show the rilevant code?
-julio
-julio
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
[...]
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
[...]
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
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.
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.
That's dHm, not dIm! :-)
What OS are you using?