1 /* $OpenBSD: tty_tty.c,v 1.8 2003/09/23 16:51:12 millert Exp $ */
2 /* $NetBSD: tty_tty.c,v 1.13 1996/03/30 22:24:46 christos Exp $ */
3
4 /*-
5 * Copyright (c) 1982, 1986, 1991, 1993
6 * The Regents of the University of California. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the University nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 *
32 * @(#)tty_tty.c 8.2 (Berkeley) 9/23/93
33 */
34
35 /*
36 * Indirect driver for controlling tty.
37 */
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/ioctl.h>
41 #include <sys/proc.h>
42 #include <sys/tty.h>
43 #include <sys/vnode.h>
44 #include <sys/file.h>
45 #include <sys/conf.h>
46
47
48 #define cttyvp(p) ((p)->p_flag & P_CONTROLT ? (p)->p_session->s_ttyvp : NULL)
49
50 /*ARGSUSED*/
51 int
cttyopen(dev,flag,mode,p)52 cttyopen(dev, flag, mode, p)
53 dev_t dev;
54 int flag, mode;
55 struct proc *p;
56 {
57 struct vnode *ttyvp = cttyvp(p);
58 int error;
59
60 if (ttyvp == NULL)
61 return (ENXIO);
62 vn_lock(ttyvp, LK_EXCLUSIVE | LK_RETRY, p);
63 #ifdef PARANOID
64 /*
65 * Since group is tty and mode is 620 on most terminal lines
66 * and since sessions protect terminals from processes outside
67 * your session, this check is probably no longer necessary.
68 * Since it inhibits setuid root programs that later switch
69 * to another user from accessing /dev/tty, we have decided
70 * to delete this test. (mckusick 5/93)
71 */
72 error = VOP_ACCESS(ttyvp,
73 (flag&FREAD ? VREAD : 0) | (flag&FWRITE ? VWRITE : 0), p->p_ucred, p);
74 if (!error)
75 #endif /* PARANOID */
76 error = VOP_OPEN(ttyvp, flag, NOCRED, p);
77 VOP_UNLOCK(ttyvp, 0, p);
78 return (error);
79 }
80
81 /*ARGSUSED*/
82 int
cttyread(dev,uio,flag)83 cttyread(dev, uio, flag)
84 dev_t dev;
85 struct uio *uio;
86 int flag;
87 {
88 struct proc *p = uio->uio_procp;
89 register struct vnode *ttyvp = cttyvp(uio->uio_procp);
90 int error;
91
92 if (ttyvp == NULL)
93 return (EIO);
94 vn_lock(ttyvp, LK_EXCLUSIVE | LK_RETRY, p);
95 error = VOP_READ(ttyvp, uio, flag, NOCRED);
96 VOP_UNLOCK(ttyvp, 0, p);
97 return (error);
98 }
99
100 /*ARGSUSED*/
101 int
cttywrite(dev,uio,flag)102 cttywrite(dev, uio, flag)
103 dev_t dev;
104 struct uio *uio;
105 int flag;
106 {
107 struct proc *p = uio->uio_procp;
108 register struct vnode *ttyvp = cttyvp(uio->uio_procp);
109 int error;
110
111 if (ttyvp == NULL)
112 return (EIO);
113 vn_lock(ttyvp, LK_EXCLUSIVE | LK_RETRY, p);
114 error = VOP_WRITE(ttyvp, uio, flag, NOCRED);
115 VOP_UNLOCK(ttyvp, 0, p);
116 return (error);
117 }
118
119 /*ARGSUSED*/
120 int
cttyioctl(dev,cmd,addr,flag,p)121 cttyioctl(dev, cmd, addr, flag, p)
122 dev_t dev;
123 u_long cmd;
124 caddr_t addr;
125 int flag;
126 struct proc *p;
127 {
128 struct vnode *ttyvp = cttyvp(p);
129
130 if (ttyvp == NULL)
131 return (EIO);
132 if (cmd == TIOCSCTTY) /* XXX */
133 return (EINVAL);
134 if (cmd == TIOCNOTTY) {
135 if (!SESS_LEADER(p)) {
136 p->p_flag &= ~P_CONTROLT;
137 return (0);
138 } else
139 return (EINVAL);
140 }
141 return (VOP_IOCTL(ttyvp, cmd, addr, flag, NOCRED, p));
142 }
143
144 /*ARGSUSED*/
145 int
cttypoll(dev,events,p)146 cttypoll(dev, events, p)
147 dev_t dev;
148 int events;
149 struct proc *p;
150 {
151 struct vnode *ttyvp = cttyvp(p);
152
153 if (ttyvp == NULL) /* try operation to get EOF/failure */
154 return (seltrue(dev, events, p));
155 return (VOP_POLL(ttyvp, events, p));
156 }
157