149594Sbostic /*-
2*69409Smckusick * Copyright (c) 1982, 1986, 1991, 1993, 1995
363180Sbostic * The Regents of the University of California. All rights reserved.
423393Smckusick *
549594Sbostic * %sccs.include.redist.c%
649594Sbostic *
7*69409Smckusick * @(#)tty_tty.c 8.4 (Berkeley) 05/14/95
823393Smckusick */
935Sbill
1035Sbill /*
113117Swnj * Indirect driver for controlling tty.
1235Sbill */
1356517Sbostic #include <sys/param.h>
1456517Sbostic #include <sys/systm.h>
1556517Sbostic #include <sys/conf.h>
1656517Sbostic #include <sys/ioctl.h>
1756517Sbostic #include <sys/proc.h>
1856517Sbostic #include <sys/tty.h>
1956517Sbostic #include <sys/vnode.h>
2056517Sbostic #include <sys/file.h>
2135Sbill
2264587Sbostic #define cttyvp(p) ((p)->p_flag & P_CONTROLT ? (p)->p_session->s_ttyvp : NULL)
2339554Smarc
2435Sbill /*ARGSUSED*/
cttyopen(dev,flag,mode,p)2547648Skarels cttyopen(dev, flag, mode, p)
268558Sroot dev_t dev;
2747648Skarels int flag, mode;
2847648Skarels struct proc *p;
2935Sbill {
3047545Skarels struct vnode *ttyvp = cttyvp(p);
3139554Smarc int error;
3235Sbill
3339554Smarc if (ttyvp == NULL)
348558Sroot return (ENXIO);
35*69409Smckusick vn_lock(ttyvp, LK_EXCLUSIVE | LK_RETRY, p);
3659454Smckusick #ifdef PARANOID
3759454Smckusick /*
3859490Smckusick * Since group is tty and mode is 620 on most terminal lines
3959454Smckusick * and since sessions protect terminals from processes outside
4059454Smckusick * your session, this check is probably no longer necessary.
4159454Smckusick * Since it inhibits setuid root programs that later switch
4259454Smckusick * to another user from accessing /dev/tty, we have decided
4359490Smckusick * to delete this test. (mckusick 5/93)
4459454Smckusick */
4541191Smckusick error = VOP_ACCESS(ttyvp,
4648018Smckusick (flag&FREAD ? VREAD : 0) | (flag&FWRITE ? VWRITE : 0), p->p_ucred, p);
4749915Smckusick if (!error)
4859454Smckusick #endif /* PARANOID */
4949915Smckusick error = VOP_OPEN(ttyvp, flag, NOCRED, p);
50*69409Smckusick VOP_UNLOCK(ttyvp, 0, p);
5149915Smckusick return (error);
5235Sbill }
5335Sbill
5435Sbill /*ARGSUSED*/
cttyread(dev,uio,flag)5549177Skarels cttyread(dev, uio, flag)
567824Sroot dev_t dev;
577824Sroot struct uio *uio;
5852502Storek int flag;
5935Sbill {
60*69409Smckusick struct proc *p = uio->uio_procp;
61*69409Smckusick register struct vnode *ttyvp = cttyvp(p);
6239589Smckusick int error;
6335Sbill
6439554Smarc if (ttyvp == NULL)
6547648Skarels return (EIO);
66*69409Smckusick vn_lock(ttyvp, LK_EXCLUSIVE | LK_RETRY, p);
6739589Smckusick error = VOP_READ(ttyvp, uio, flag, NOCRED);
68*69409Smckusick VOP_UNLOCK(ttyvp, 0, p);
6939589Smckusick return (error);
7035Sbill }
7135Sbill
7235Sbill /*ARGSUSED*/
cttywrite(dev,uio,flag)7349177Skarels cttywrite(dev, uio, flag)
747824Sroot dev_t dev;
757824Sroot struct uio *uio;
7652502Storek int flag;
7735Sbill {
78*69409Smckusick struct proc *p = uio->uio_procp;
79*69409Smckusick struct vnode *ttyvp = cttyvp(uio->uio_procp);
8039589Smckusick int error;
8135Sbill
8239554Smarc if (ttyvp == NULL)
8347648Skarels return (EIO);
84*69409Smckusick vn_lock(ttyvp, LK_EXCLUSIVE | LK_RETRY, p);
8539589Smckusick error = VOP_WRITE(ttyvp, uio, flag, NOCRED);
86*69409Smckusick VOP_UNLOCK(ttyvp, 0, p);
8739589Smckusick return (error);
8835Sbill }
8935Sbill
9035Sbill /*ARGSUSED*/
cttyioctl(dev,cmd,addr,flag,p)9147648Skarels cttyioctl(dev, cmd, addr, flag, p)
925618Sroot dev_t dev;
9368171Scgd u_long cmd;
945618Sroot caddr_t addr;
955618Sroot int flag;
9647648Skarels struct proc *p;
9735Sbill {
9847648Skarels struct vnode *ttyvp = cttyvp(p);
9935Sbill
10039554Smarc if (ttyvp == NULL)
10147648Skarels return (EIO);
1025390Swnj if (cmd == TIOCNOTTY) {
10347648Skarels if (!SESS_LEADER(p)) {
10464587Sbostic p->p_flag &= ~P_CONTROLT;
10539554Smarc return (0);
10639554Smarc } else
10739554Smarc return (EINVAL);
1085390Swnj }
10948018Smckusick return (VOP_IOCTL(ttyvp, cmd, addr, flag, NOCRED, p));
11035Sbill }
1114487Swnj
1128591Sroot /*ARGSUSED*/
cttyselect(dev,flag,p)11347648Skarels cttyselect(dev, flag, p)
1148591Sroot dev_t dev;
1158591Sroot int flag;
11647648Skarels struct proc *p;
1174487Swnj {
11847648Skarels struct vnode *ttyvp = cttyvp(p);
1194487Swnj
12039554Smarc if (ttyvp == NULL)
12143382Skarels return (1); /* try operation to get EOF/failure */
12248018Smckusick return (VOP_SELECT(ttyvp, flag, FREAD|FWRITE, NOCRED, p));
1234487Swnj }
124