kern/73821: poll(2) returns POLLIN / POLLOUT on TS_ZOMBIE ttys
Diomidis Spinellis
dds at aueb.gr
Thu Nov 11 07:20:19 PST 2004
>Number: 73821
>Category: kern
>Synopsis: poll(2) returns POLLIN / POLLOUT on TS_ZOMBIE ttys
>Confidential: no
>Severity: serious
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Thu Nov 11 15:20:18 GMT 2004
>Closed-Date:
>Last-Modified:
>Originator: Diomidis Spinellis
>Release: FreeBSD 4.10-STABLE i386
>Organization:
AUEB
>Environment:
System: FreeBSD istlab.dmst.aueb.gr 4.10-STABLE FreeBSD 4.10-STABLE #23: Fri Oct 8 15:53:45 EEST 2004 dds at istlab.dmst.aueb.gr:/usr/obj/usr/src/sys/ISTLAB i386
>Description:
When a tty line toggles its DCD it enters the TS_ZOMBIE state. In
that state input and output are not possible. Yet poll(2) will
return POLLIN / POLLOUT in that state - even if no I/O is possible.
Example:
$ pstat -t
LINE RAW CAN OUT IHIWT ILOWT OHWT LWT COL STATE SESS PGID DISC
cuaa0 22 0 0 11520 10080 4104 256 7274 OlZ 0 0 term
$ strace -p 8539
poll([{fd=4, events=POLLIN|POLLRDNORM|POLLERR, revents=POLLIN|POLLRDNORM}], 1, 0) = 1
read(4, "", 1024) = 0
In the above example /dev/cuaa0 is in the TS_ZOMBIE state (Z). Poll(2) returns
POLLIN, yet read(2) returns 0.
>How-To-Repeat:
Probably by toggling the DCD line of a device read by a program using
poll(2).
>Fix:
Modify tty's poll(2) interface to return POLLERR for TS_ZOMBIE ttys.
POLLERR is defined as:
An error has occurred on the device or stream.
Can not return POLLHUP because according to POSIX 1003.1 (2004):
POLLHUP
The device has been disconnected. This event and POLLOUT are mutually-exclusive; a stream can never be writable if a hangup has occurred.
The following patch implements the proposed change:
Index: tty.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/tty.c,v
retrieving revision 1.240
diff -u -r1.240 tty.c
--- tty.c 3 Nov 2004 19:16:55 -0000 1.240
+++ tty.c 11 Nov 2004 14:55:25 -0000
@@ -1283,19 +1283,20 @@
s = spltty();
if (events & (POLLIN | POLLRDNORM)) {
- if (ttnread(tp) > 0 || ISSET(tp->t_state, TS_ZOMBIE))
+ if (ttnread(tp) > 0)
revents |= events & (POLLIN | POLLRDNORM);
else
selrecord(td, &tp->t_rsel);
}
if (events & (POLLOUT | POLLWRNORM)) {
- if ((tp->t_outq.c_cc <= tp->t_olowat &&
- ISSET(tp->t_state, TS_CONNECTED))
- || ISSET(tp->t_state, TS_ZOMBIE))
+ if (tp->t_outq.c_cc <= tp->t_olowat &&
+ ISSET(tp->t_state, TS_CONNECTED))
revents |= events & (POLLOUT | POLLWRNORM);
else
selrecord(td, &tp->t_wsel);
}
+ if (ISSET(tp->t_state, TS_ZOMBIE))
+ revents |= POLLERR;
splx(s);
return (revents);
}
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list