Subject: kern/11836: Non-blocking BPF read returns 0, not -1 with EWOULDBLOCK, if no data
To: None <gnats-bugs@gnats.netbsd.org>
From: None <guy@alum.mit.edu>
List: netbsd-bugs
Date: 12/28/2000 14:52:12
>Number: 11836
>Category: kern
>Synopsis: Non-blocking BPF read returns 0, not -1 with EWOULDBLOCK, if no data
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Thu Dec 28 14:52:00 PST 2000
>Closed-Date:
>Last-Modified:
>Originator: Guy Harris
>Release: -current
>Organization:
>Environment:
(Bug found by code inspection and from FreeBSD and OpenBSD changes to
address the same problem.)
>Description:
A read on a BPF device in non-blocking mode will, if no data is
available to be read, return 0, rather than returning -1 and
setting "errno" to EWOULDBLOCK.
The FreeBSD change for this notes that this causes problems with
threaded programs; their userland threads package puts file descriptors
into non-blocking mode, and expects I/O that would block to return
-1 and set "errno" to EWOULDBLOCK - it uses this as an indication that
the thread doing the I/O operation should be put to sleep.
>How-To-Repeat:
>Fix:
The following patch to "syssrc/sys/net/bpf.c" picks up the OpenBSD
fix for this.
Index: bpf.c
===================================================================
RCS file: /cvsroot/syssrc/sys/net/bpf.c,v
retrieving revision 1.59
diff -c -r1.59 bpf.c
*** bpf.c 2000/12/12 17:55:21 1.59
--- bpf.c 2000/12/28 22:49:39
***************
*** 434,441 ****
if (d->bd_rtout != -1)
error = tsleep((caddr_t)d, PRINET|PCATCH, "bpf",
d->bd_rtout);
! else
! error = EWOULDBLOCK; /* User requested non-blocking I/O */
if (error == EINTR || error == ERESTART) {
splx(s);
return (error);
--- 434,446 ----
if (d->bd_rtout != -1)
error = tsleep((caddr_t)d, PRINET|PCATCH, "bpf",
d->bd_rtout);
! else {
! if (d->bd_rtout == -1) {
! /* User requested non-blocking I/O */
! error = EWOULDBLOCK;
! } else
! error = 0;
! }
if (error == EINTR || error == ERESTART) {
splx(s);
return (error);
***************
*** 1198,1205 ****
}
/*
! * Attach an interface to bpf. driverp is a pointer to a (struct bpf_if *)
! * in the driver's softc; dlt is the link layer type; hdrlen is the fixed
* size of the link header (variable length headers not yet supported).
*/
void
--- 1203,1209 ----
}
/*
! * Attach an interface to bpf. dlt is the link layer type; hdrlen is the fixed
* size of the link header (variable length headers not yet supported).
*/
void
>Release-Note:
>Audit-Trail:
>Unformatted: