summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/kern/tty_pty.c29
1 files changed, 24 insertions, 5 deletions
diff --git a/sys/kern/tty_pty.c b/sys/kern/tty_pty.c
index 5d28fe6..3827e82 100644
--- a/sys/kern/tty_pty.c
+++ b/sys/kern/tty_pty.c
@@ -100,6 +100,9 @@ static struct cdevsw ptc_cdevsw = {
.d_flags = D_TTY | D_NEEDGIANT,
};
+static struct mtx ptyinit_lock;
+MTX_SYSINIT(ptyinit_lock, &ptyinit_lock, "ptyinit", MTX_DEF);
+
#define BUFSIZ 100 /* Chunk size iomoved to/from user */
struct ptsc {
@@ -151,8 +154,16 @@ ptyinit(struct cdev *devc, struct thread *td)
pt->pt_tty = ttyalloc();
pt->pt_tty->t_sc = pt;
- devc->si_drv1 = pt;
- devc->si_tty = pt->pt_tty;
+ mtx_lock(&ptyinit_lock);
+ if (devc->si_drv1 == NULL) {
+ devc->si_drv1 = pt;
+ devc->si_tty = pt->pt_tty;
+ mtx_unlock(&ptyinit_lock);
+ } else {
+ mtx_unlock(&ptyinit_lock);
+ ttyrel(pt->pt_tty);
+ free(pt, M_PTY);
+ }
return (devc);
}
@@ -335,9 +346,17 @@ ptcopen(struct cdev *dev, int flag, int devtype, struct thread *td)
* 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;
+ tp = ttyalloc();
+ mtx_lock(&ptyinit_lock);
+ if (pt->pt_tty == NULL) {
+ pt->pt_tty = tp;
+ pt->pt_tty->t_sc = pt;
+ dev->si_tty = pt->pt_tty;
+ mtx_unlock(&ptyinit_lock);
+ } else {
+ mtx_unlock(&ptyinit_lock);
+ ttyrel(tp);
+ }
}
tp = dev->si_tty;
OpenPOWER on IntegriCloud