-/* $OpenBSD: tty_pty.c,v 1.106 2021/02/04 07:54:51 claudio Exp $ */
+/* $OpenBSD: tty_pty.c,v 1.107 2021/02/04 13:32:33 claudio Exp $ */
/* $NetBSD: tty_pty.c,v 1.33.4.1 1996/06/02 09:08:11 mrg Exp $ */
/*
struct nameidata cnd, snd;
struct filedesc *fdp = p->p_fd;
struct file *cfp = NULL, *sfp = NULL;
- struct vnode *cvp = NULL, *svp = NULL;
int cindx, sindx;
uid_t uid;
gid_t gid;
switch (cmd) {
case PTMGET:
+ fdplock(fdp);
+ /* Grab two filedescriptors. */
+ if ((error = falloc(p, &cfp, &cindx)) != 0) {
+ fdpunlock(fdp);
+ break;
+ }
+ if ((error = falloc(p, &sfp, &sindx)) != 0) {
+ fdremove(fdp, cindx);
+ closef(cfp, p);
+ fdpunlock(fdp);
+ break;
+ }
+
retry:
/* Find and open a free master pty. */
newdev = pty_getfree();
if ((error = check_pty(newdev)))
- return (error);
+ goto bad;
pti = pt_softc[minor(newdev)];
NDINIT(&cnd, LOOKUP, NOFOLLOW|LOCKLEAF, UIO_SYSSPACE,
pti->pty_pn, p);
*/
if (error == EIO && !pty_isfree(minor(newdev)))
goto retry;
- return (error);
+ goto bad;
}
- cvp = cnd.ni_vp;
- VOP_UNLOCK(cvp);
+ cfp->f_flag = FREAD|FWRITE;
+ cfp->f_type = DTYPE_VNODE;
+ cfp->f_ops = &vnops;
+ cfp->f_data = (caddr_t) cnd.ni_vp;
+ VOP_UNLOCK(cnd.ni_vp);
/*
* Open the slave.
/* now open it */
if ((error = ptm_vn_open(&snd)) != 0)
goto bad;
- svp = snd.ni_vp;
- VOP_UNLOCK(svp);
-
- fdplock(fdp);
- /* Grab two filedescriptors. */
- if ((error = falloc(p, &cfp, &cindx)) != 0) {
- fdpunlock(fdp);
- goto bad;
- }
- if ((error = falloc(p, &sfp, &sindx)) != 0) {
- fdremove(fdp, cindx);
- closef(cfp, p);
- fdpunlock(fdp);
- goto bad;
- }
-
- cfp->f_flag = FREAD|FWRITE;
- cfp->f_type = DTYPE_VNODE;
- cfp->f_ops = &vnops;
- cfp->f_data = (caddr_t)cvp;
-
sfp->f_flag = FREAD|FWRITE;
sfp->f_type = DTYPE_VNODE;
sfp->f_ops = &vnops;
- sfp->f_data = (caddr_t)svp;
+ sfp->f_data = (caddr_t) snd.ni_vp;
+ VOP_UNLOCK(snd.ni_vp);
/* now, put the indexen and names into struct ptmget */
ptm->cfd = cindx;
break;
}
return (error);
-
bad:
- if (svp)
- vrele(svp);
- if (cvp)
- vrele(cvp);
+ fdremove(fdp, cindx);
+ closef(cfp, p);
+ fdremove(fdp, sindx);
+ closef(sfp, p);
+ fdpunlock(fdp);
return (error);
}