Date: Thu, 11 Nov 2004 17:19:20 +0200 (EET) From: Diomidis Spinellis <dds@aueb.gr> To: FreeBSD-gnats-submit@FreeBSD.org Subject: kern/73821: poll(2) returns POLLIN / POLLOUT on TS_ZOMBIE ttys Message-ID: <200411111519.iABFJKkK082967@istlab.dmst.aueb.gr> Resent-Message-ID: <200411111520.iABFKJ2d087608@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>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@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:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200411111519.iABFJKkK082967>