kern/149857: kqueue not reporting EOF under certain circumstances

Volodymyr Kostyrko c.kworr at gmail.com
Sat Aug 21 20:40:02 UTC 2010


>Number:         149857
>Category:       kern
>Synopsis:       kqueue not reporting EOF under certain circumstances
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sat Aug 21 20:40:01 UTC 2010
>Closed-Date:
>Last-Modified:
>Originator:     Volodymyr Kostyrko
>Release:        RELENG_8
>Organization:
>Environment:
FreeBSD limbo.lan 8.1-STABLE FreeBSD 8.1-STABLE #0 r211484M: Thu Aug 19 10:06:29 EEST 2010     arcade at limbo.lan:/usr/obj/usr/src/sys/MINIMAL_8  i386
>Description:
kqueue ignores EOF event in some cases. I've tried to ping python people thinking that this one can be python based but they don't think this happens in python. In any case http://bugs.python.org/issue9591 is the place for this bug in python roundup.
>How-To-Repeat:
Sorry for the python code, I'm bad at C.

Generally this program only eats everything what comes on stdin, logs any kevents faced and exits on stream end. Two EOF cases are checked - when kqueue returns 1 >> 15 (32768) or when we receive 0 bytes of data instead of value given in kevent.

---------- test.py
#!/usr/bin/env python3.1

import select, sys

kq = select.kqueue()
assert kq.fileno() != -1, "Fatal error: can't initialise kqueue."

kq.control([select.kevent(sys.stdin, select.KQ_FILTER_READ, select.KQ_EV_ADD)], 0)

eof = False
while True:
        kevs = kq.control(None, 1, None)

        for kev in kevs:
                print(kev.filter, kev.data, kev.flags, kev.ident, kev.fflags)
                if kev.filter == select.KQ_FILTER_READ and kev.data > 0:
                        buffer = sys.stdin.read(kev.data)
                        if len(buffer) == 0:
                                print('eof')
                                eof = True
                if kev.flags >> 15 == 1 or eof:
                        eof = True
                        kq.control([select.kevent(sys.stdin, select.KQ_FILTER_READ, select.KQ_EV_DELETE)], 0)

        if len(kevs) == 0 or eof:
                break
---------- test.py

Now let's have some fun:

# cat test.py | ./test.py
-1 684 32768 0 0
#

This hangs:
# ./test.py < test.py
-1 684 0 0 0
<- We are hanging and waiting for other data.

I have tested that on RELENG_8 and RELENG_8_1 and results are the same.
>Fix:
None.

>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list