kern/65786: Incorrect fifo semantics

Guido Laubner Guido.Laubner at gmx.de
Mon Apr 19 13:30:34 PDT 2004


>Number:         65786
>Category:       kern
>Synopsis:       Incorrect fifo semantics
>Confidential:   no
>Severity:       critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Apr 19 13:30:21 PDT 2004
>Closed-Date:
>Last-Modified:
>Originator:     Guido Laubner
>Release:        5.2.1
>Organization:
>Environment:
FreeBSD doomsday.die-insel.germany.net 5.2.1-RELEASE FreeBSD 5.2.1-RELEASE #0: Mon Feb 23 20:45:55 GMT 2004     root at wv1u.btc.adaptec.com:/usr/obj/usr/src/sys/GENERIC  i386
      
>Description:
I found a strange behaviour of dd. Digging into it I believe it's a
problem of the fifo created by mkfifo(2).
It looks like the fifo allows (and reports correct return codes) for
lseek(2), but when reading form the fifo after the lseek advancing the "read cursor", reading starts from position 0.
Comparing this with a pipe, the pipe behaves correctly :
It allows for lseek and reading starts at the position given in the lseek(2) syscall.
Assuming the pipe is correct, the fifo is not implemented correctly in that is does not position the read "cursor" for the next read properly.
If my assumption is wrong (so the pipe semantics would not hold for
a fifo) the lseek syscall to a fifo should return an error.
>How-To-Repeat:
I've put a shell script and a c-programm together.
The shell script shows the difference in pipe and fifo.
Just run the script and then do more /tmp/c1 ; more /tmp/c2
The output should be identical, but isn't. It shows the pipe working
correctly (/tmp/c2 = "c"), while the fifo did not advance the read pointer (/tmp/c1 = "a" ).
==========================SNIP for SHELL SCRIPT=========================
#!/bin/sh
mkfifo /tmp/fifo
dd if=/tmp/fifo of=/tmp/c1 bs=1 count=1 iseek=2 &
echo abc  >/tmp/fifo
echo abc | dd of=/tmp/c2 bs=1 count=1 iseek=2 
exit
================= SNIP END OF SCRIPT ===================================


The c-program shows, that a fifo does accept the "lseek" system call and
returns correct return code to the lseek, but does not advance the input
pointer for the next read.
to compile : gcc -o main fifo_test.c
to run : mkfifo /tmp/fifo ; ./main & echo abc > /tmp/fifo
which prints : r=2 z=1 c=a  (r=return from lseek, z=return from read
                             c=characer read from fifo)
It should not print "c=a", since the lseek advances the input pointer.

================= SNIP for fifo_test.c =================================
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
main()
{
int o, r, z;
char *c;
   c=(char*)calloc( 2, 1 );
   o=open( "/tmp/fifo", O_RDONLY );
   r=lseek( o, 2, SEEK_SET );
   z=read( o, c, 1 );
   fprintf( stdout, "r=%d z=%d c=%s\n", r, z, c );
}
================= SNIP End of fifo_test.c ==============================
>Fix:
Not known.
>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list