From e4936f3763ca166659591d49e1f9534cac47a7f3 Mon Sep 17 00:00:00 2001 From: Martin Blapp Date: Fri, 29 Sep 2006 09:52:57 +0000 Subject: [PATCH] Free tty struct after last close. This should fix the pty-leak by numbers. Remove workarounds for tty_refcount beeing 0, this will be fixed differently later. Back out rev 1.145 since we initialize the tty struct from scratch and bad things can't happen anymore. --- sys/kern/tty_pty.c | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/sys/kern/tty_pty.c b/sys/kern/tty_pty.c index af005ab22a1d..4afb80354c15 100644 --- a/sys/kern/tty_pty.c +++ b/sys/kern/tty_pty.c @@ -171,7 +171,11 @@ static void pty_destroy_slave(struct ptsc *pt) { + if (pt->pt_tty->t_refcnt > 1) + return; pt->pt_tty->t_dev = NULL; + ttyrel(pt->pt_tty); + pt->pt_tty = NULL; destroy_dev(pt->devs); pt->devs = NULL; } @@ -180,7 +184,7 @@ static void pty_maybe_destroy_slave(struct ptsc *pt) { - if (0 && pt->pt_devc_open == 0 && pt->pt_devs_open == 0) + if (pt->pt_devc_open == 0 && pt->pt_devs_open == 0) pty_destroy_slave(pt); } @@ -197,11 +201,6 @@ ptsopen(struct cdev *dev, int flag, int devtype, struct thread *td) pt = dev->si_drv1; tp = dev->si_tty; - /* XXX It can happen that devfs_open calls us with tp->t_refcnt == 0 */ - if (tp == NULL || tp->t_refcnt == 0) { - return (ENXIO); - } - if ((tp->t_state & TS_ISOPEN) == 0) { ttyinitmode(tp, 1, 0); } else if (tp->t_state & TS_XCLUDE && suser(td)) @@ -319,12 +318,19 @@ ptcopen(struct cdev *dev, int flag, int devtype, struct thread *td) ptyinit(dev, td); if (!dev->si_drv1) return(ENXIO); - tp = dev->si_tty; - /* XXX It can happen that devfs_open calls us with tp->t_refcnt == 0 */ - if (tp == NULL || tp->t_refcnt == 0) { - return (ENXIO); - } + pt = dev->si_drv1; + /* + * In case we have destroyed the struct tty at the last connect time, + * we need to recreate it. + */ + if (pt->pt_tty == NULL) { + pt->pt_tty = ttyalloc(); + pt->pt_tty->t_sc = pt; + dev->si_tty = pt->pt_tty; + pty_create_slave(td->td_ucred, pt, minor(dev)); + } + tp = dev->si_tty; if (tp->t_oproc) return (EIO); @@ -333,7 +339,6 @@ ptcopen(struct cdev *dev, int flag, int devtype, struct thread *td) tp->t_stop = ptsstop; (void)ttyld_modem(tp, 1); tp->t_lflag &= ~EXTPROC; - pt = dev->si_drv1; pt->pt_prison = td->td_ucred->cr_prison; pt->pt_flags = 0; pt->pt_send = 0;