1 /*-
2 * Copyright (c) 1982, 1986, 1991, 1993, 1995
3 * The Regents of the University of California. All rights reserved.
4 *
5 * %sccs.include.redist.c%
6 *
7 * @(#)tty_tty.c 8.4 (Berkeley) 05/14/95
8 */
9
10 /*
11 * Indirect driver for controlling tty.
12 */
13 #include <sys/param.h>
14 #include <sys/systm.h>
15 #include <sys/conf.h>
16 #include <sys/ioctl.h>
17 #include <sys/proc.h>
18 #include <sys/tty.h>
19 #include <sys/vnode.h>
20 #include <sys/file.h>
21
22 #define cttyvp(p) ((p)->p_flag & P_CONTROLT ? (p)->p_session->s_ttyvp : NULL)
23
24 /*ARGSUSED*/
cttyopen(dev,flag,mode,p)25 cttyopen(dev, flag, mode, p)
26 dev_t dev;
27 int flag, mode;
28 struct proc *p;
29 {
30 struct vnode *ttyvp = cttyvp(p);
31 int error;
32
33 if (ttyvp == NULL)
34 return (ENXIO);
35 vn_lock(ttyvp, LK_EXCLUSIVE | LK_RETRY, p);
36 #ifdef PARANOID
37 /*
38 * Since group is tty and mode is 620 on most terminal lines
39 * and since sessions protect terminals from processes outside
40 * your session, this check is probably no longer necessary.
41 * Since it inhibits setuid root programs that later switch
42 * to another user from accessing /dev/tty, we have decided
43 * to delete this test. (mckusick 5/93)
44 */
45 error = VOP_ACCESS(ttyvp,
46 (flag&FREAD ? VREAD : 0) | (flag&FWRITE ? VWRITE : 0), p->p_ucred, p);
47 if (!error)
48 #endif /* PARANOID */
49 error = VOP_OPEN(ttyvp, flag, NOCRED, p);
50 VOP_UNLOCK(ttyvp, 0, p);
51 return (error);
52 }
53
54 /*ARGSUSED*/
cttyread(dev,uio,flag)55 cttyread(dev, uio, flag)
56 dev_t dev;
57 struct uio *uio;
58 int flag;
59 {
60 struct proc *p = uio->uio_procp;
61 register struct vnode *ttyvp = cttyvp(p);
62 int error;
63
64 if (ttyvp == NULL)
65 return (EIO);
66 vn_lock(ttyvp, LK_EXCLUSIVE | LK_RETRY, p);
67 error = VOP_READ(ttyvp, uio, flag, NOCRED);
68 VOP_UNLOCK(ttyvp, 0, p);
69 return (error);
70 }
71
72 /*ARGSUSED*/
cttywrite(dev,uio,flag)73 cttywrite(dev, uio, flag)
74 dev_t dev;
75 struct uio *uio;
76 int flag;
77 {
78 struct proc *p = uio->uio_procp;
79 struct vnode *ttyvp = cttyvp(uio->uio_procp);
80 int error;
81
82 if (ttyvp == NULL)
83 return (EIO);
84 vn_lock(ttyvp, LK_EXCLUSIVE | LK_RETRY, p);
85 error = VOP_WRITE(ttyvp, uio, flag, NOCRED);
86 VOP_UNLOCK(ttyvp, 0, p);
87 return (error);
88 }
89
90 /*ARGSUSED*/
cttyioctl(dev,cmd,addr,flag,p)91 cttyioctl(dev, cmd, addr, flag, p)
92 dev_t dev;
93 u_long cmd;
94 caddr_t addr;
95 int flag;
96 struct proc *p;
97 {
98 struct vnode *ttyvp = cttyvp(p);
99
100 if (ttyvp == NULL)
101 return (EIO);
102 if (cmd == TIOCNOTTY) {
103 if (!SESS_LEADER(p)) {
104 p->p_flag &= ~P_CONTROLT;
105 return (0);
106 } else
107 return (EINVAL);
108 }
109 return (VOP_IOCTL(ttyvp, cmd, addr, flag, NOCRED, p));
110 }
111
112 /*ARGSUSED*/
cttyselect(dev,flag,p)113 cttyselect(dev, flag, p)
114 dev_t dev;
115 int flag;
116 struct proc *p;
117 {
118 struct vnode *ttyvp = cttyvp(p);
119
120 if (ttyvp == NULL)
121 return (1); /* try operation to get EOF/failure */
122 return (VOP_SELECT(ttyvp, flag, FREAD|FWRITE, NOCRED, p));
123 }
124