tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: kevent() not reporting closed slave pty (via master pty)



On Wed, 2019-02-06 at 17:42 +0100, Michał Górny wrote:
> Hi,
> 
> I've been debugging a hanging test in LLDB.  The particular test is
> meant to verify that LLDB handles EOF on pty correctly.  For this
> purpose, it creates a pty and monitors it via kevent, then opens a slave
> and closes it.  Apparently, it expects kevent to report that master pty
> has no longer any slaves open.
> 
> I've tested this a bit and verified that read() from master pty returns
> immediately if slave pty is closed.  However, it seems that closing
> the slave pty prevents kevent from reporting anything, therefore making
> it wait forever.
> 

And here's a proposed patch, based on kern/sys_pipe.c.  I still have to
write an ATF test for it.


diff --git a/sys/kern/tty_pty.c b/sys/kern/tty_pty.c
index 1d60596124d3..0a235cc41aaa 100644
--- a/sys/kern/tty_pty.c
+++ b/sys/kern/tty_pty.c
@@ -920,40 +920,44 @@ filt_ptcread(struct knote *kn, long hint)
 
 	if ((hint & NOTE_SUBMIT) == 0) {
 		mutex_spin_enter(&tty_lock);
 	}
 
 	canread = (ISSET(tp->t_state, TS_ISOPEN) &&
 		    ((tp->t_outq.c_cc > 0 && !ISSET(tp->t_state, TS_TTSTOP)) ||
 		     ((pti->pt_flags & PF_PKT) && pti->pt_send) ||
 		     ((pti->pt_flags & PF_UCNTL) && pti->pt_ucntl)));
 
 	if (canread) {
 		/*
 		 * c_cc is number of characters after output post-processing;
 		 * the amount of data actually read(2) depends on
 		 * setting of input flags for the terminal.
 		 */
 		kn->kn_data = tp->t_outq.c_cc;
 		if (((pti->pt_flags & PF_PKT) && pti->pt_send) ||
 		    ((pti->pt_flags & PF_UCNTL) && pti->pt_ucntl))
 			kn->kn_data++;
+	} else if (!ISSET(tp->t_state, TS_ISOPEN) &&
+		   !ISSET(tp->t_state, TS_CARR_ON)) {
+	    kn->kn_flags |= EV_EOF;
+	    canread = 1;
 	}
 
 	if ((hint & NOTE_SUBMIT) == 0) {
 		mutex_spin_exit(&tty_lock);
 	}
 
 	return canread;
 }
 
 static void
 filt_ptcwdetach(struct knote *kn)
 {
 	struct pt_softc *pti;
 
 	pti = kn->kn_hook;
 
 	mutex_spin_enter(&tty_lock);
 	SLIST_REMOVE(&pti->pt_selw.sel_klist, kn, knote, kn_selnext);
 	mutex_spin_exit(&tty_lock);
 }



-- 
Best regards,
Michał Górny

Attachment: signature.asc
Description: This is a digitally signed message part



Home | Main Index | Thread Index | Old Index