diff -ur ../stock/linux-2.6.7-rc1-mm1/drivers/char/tty_io.c linux-2.6.7-rc1-mm1/drivers/char/tty_io.c --- ../stock/linux-2.6.7-rc1-mm1/drivers/char/tty_io.c 2004-05-28 10:28:23.000000000 -0700 +++ linux-2.6.7-rc1-mm1/drivers/char/tty_io.c 2004-05-28 12:27:56.000000000 -0700 @@ -1068,6 +1068,7 @@ { struct tty_struct *tty, *o_tty; int pty_master, tty_closing, o_tty_closing, do_sleep; + int devpts_master; int idx; char buf[64]; @@ -1082,6 +1083,7 @@ idx = tty->index; pty_master = (tty->driver->type == TTY_DRIVER_TYPE_PTY && tty->driver->subtype == PTY_TYPE_MASTER); + devpts_master = pty_master && (tty->driver->flags & TTY_DRIVER_DEVPTS_MEM); o_tty = tty->link; #ifdef TTY_PARANOIA_CHECK @@ -1298,19 +1300,21 @@ o_tty->ldisc = ldiscs[N_TTY]; } + /* + * The release_mem function takes care of the details of clearing + * the slots and preserving the termios structure. + */ + release_mem(tty, idx); + #ifdef CONFIG_UNIX98_PTYS - if (filp->f_dentry->d_inode->i_rdev == MKDEV(TTYAUX_MAJOR,2)) { + /* Make this pty number available for reallocation */ + if (devpts_master) { down(&allocated_ptys_lock); idr_remove(&allocated_ptys, idx); up(&allocated_ptys_lock); } #endif - /* - * The release_mem function takes care of the details of clearing - * the slots and preserving the termios structure. - */ - release_mem(tty, idx); } /* @@ -1330,11 +1334,15 @@ struct tty_struct *tty; int noctty, retval; struct tty_driver *driver; - int index = -1; + int index; dev_t device = inode->i_rdev; unsigned short saved_flags = filp->f_flags; + retry_open: noctty = filp->f_flags & O_NOCTTY; + index = -1; + retval = 0; + if (device == MKDEV(TTYAUX_MAJOR,0)) { if (!current->signal->tty) return -ENXIO; @@ -1392,22 +1400,20 @@ up(&allocated_ptys_lock); return -EIO; } + up(&allocated_ptys_lock); + driver = ptm_driver; retval = init_dev(driver, index, &tty); if (retval) { + down(&allocated_ptys_lock); idr_remove(&allocated_ptys, index); up(&allocated_ptys_lock); return retval; } + set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */ - if (devpts_pty_new(tty->link)) { - /* BADNESS - need to destroy both ptm and pts! */ - idr_remove(&allocated_ptys, index); - up(&allocated_ptys_lock); - return -ENOMEM; - } - up(&allocated_ptys_lock); - noctty = 1; + if (devpts_pty_new(tty->link)) + retval = -ENOMEM; } else #endif { @@ -1429,10 +1435,12 @@ #ifdef TTY_DEBUG_HANGUP printk(KERN_DEBUG "opening %s...", tty->name); #endif - if (tty->driver->open) - retval = tty->driver->open(tty, filp); - else - retval = -ENODEV; + if (!retval) { + if (tty->driver->open) + retval = tty->driver->open(tty, filp); + else + retval = -ENODEV; + } filp->f_flags = saved_flags; if (!retval && test_bit(TTY_EXCLUSIVE, &tty->flags) && !capable(CAP_SYS_ADMIN))