]> git.saurik.com Git - apple/xnu.git/blob - bsd/kern/tty_tty.c
d6ad89213d71a3b5562852534e6710472e82507c
[apple/xnu.git] / bsd / kern / tty_tty.c
1 /*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28 /* Copyright (c) 1997 Apple Computer, Inc. All Rights Reserved */
29 /*-
30 * Copyright (c) 1982, 1986, 1991, 1993
31 * The Regents of the University of California. All rights reserved.
32 *
33 * Redistribution and use in source and binary forms, with or without
34 * modification, are permitted provided that the following conditions
35 * are met:
36 * 1. Redistributions of source code must retain the above copyright
37 * notice, this list of conditions and the following disclaimer.
38 * 2. Redistributions in binary form must reproduce the above copyright
39 * notice, this list of conditions and the following disclaimer in the
40 * documentation and/or other materials provided with the distribution.
41 * 3. All advertising materials mentioning features or use of this software
42 * must display the following acknowledgement:
43 * This product includes software developed by the University of
44 * California, Berkeley and its contributors.
45 * 4. Neither the name of the University nor the names of its contributors
46 * may be used to endorse or promote products derived from this software
47 * without specific prior written permission.
48 *
49 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
50 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
51 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
53 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59 * SUCH DAMAGE.
60 *
61 * @(#)tty_tty.c 8.2 (Berkeley) 9/23/93
62 */
63
64 /*
65 * Indirect driver for controlling tty.
66 */
67 #include <sys/param.h>
68 #include <sys/systm.h>
69 #include <sys/conf.h>
70 #include <sys/ioctl.h>
71 #include <sys/proc_internal.h>
72 #include <sys/tty.h>
73 #include <sys/vnode_internal.h>
74 #include <sys/file_internal.h>
75 #ifndef NeXT
76 #include <sys/kernel.h>
77 #ifdef DEVFS
78 #include <sys/devfsext.h>
79 #endif /*DEVFS*/
80
81 static d_open_t cttyopen;
82 static d_read_t cttyread;
83 static d_write_t cttywrite;
84 static d_ioctl_t cttyioctl;
85 static d_select_t cttyselect;
86
87 #endif /* !NeXT */
88
89 /* Forward declarations for cdevsw[] entry */
90 /* XXX we should consider making these static */
91 int cttyopen(dev_t dev, int flag, int mode, struct proc *p);
92 int cttyread(dev_t dev, struct uio *uio, int flag);
93 int cttywrite(dev_t dev, struct uio *uio, int flag);
94 int cttyioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p);
95 int cttyselect(dev_t dev, int flag, void* wql, struct proc *p);
96
97 #ifndef NeXT
98
99 #define CDEV_MAJOR 1
100 /* Don't make static, fdesc_vnops uses this. */
101 struct cdevsw ctty_cdevsw =
102 { cttyopen, nullclose, cttyread, cttywrite, /*1*/
103 cttyioctl, nullstop, nullreset, nodevtotty,/* tty */
104 cttyselect, nommap, NULL, "ctty", NULL, -1 };
105
106 #endif /* !NeXT */
107
108 #define cttyvp(p) ((p)->p_flag & P_CONTROLT ? (p)->p_session->s_ttyvp : NULL)
109
110 /*ARGSUSED*/
111 int
112 cttyopen(__unused dev_t dev, int flag, __unused int mode, struct proc *p)
113 {
114 struct vnode *ttyvp = cttyvp(p);
115 struct vfs_context context;
116 int error;
117
118 if (ttyvp == NULL)
119 return (ENXIO);
120
121 context.vc_proc = p;
122 context.vc_ucred = kauth_cred_proc_ref(p);
123 error = VNOP_OPEN(ttyvp, flag, &context);
124 kauth_cred_unref(&context.vc_ucred);
125
126 return (error);
127 }
128
129 /*ARGSUSED*/
130 int
131 cttyread(__unused dev_t dev, struct uio *uio, int flag)
132 {
133 struct proc *p = current_proc();
134 register struct vnode *ttyvp = cttyvp(p);
135 struct vfs_context context;
136 int error;
137
138 if (ttyvp == NULL)
139 return (EIO);
140
141 context.vc_proc = p;
142 context.vc_ucred = NOCRED;
143
144 error = VNOP_READ(ttyvp, uio, flag, &context);
145
146 return (error);
147 }
148
149 /*ARGSUSED*/
150 int
151 cttywrite(__unused dev_t dev, struct uio *uio, int flag)
152 {
153 struct proc *p = current_proc();
154 register struct vnode *ttyvp = cttyvp(p);
155 struct vfs_context context;
156 int error;
157
158 if (ttyvp == NULL)
159 return (EIO);
160
161 context.vc_proc = p;
162 context.vc_ucred = NOCRED;
163
164 error = VNOP_WRITE(ttyvp, uio, flag, &context);
165
166 return (error);
167 }
168
169 /*ARGSUSED*/
170 #ifndef NeXT
171 static int
172 cttyioctl(dev, cmd, addr, flag, p)
173 dev_t dev;
174 int cmd;
175 caddr_t addr;
176 int flag;
177 struct proc *p;
178 #else
179 int
180 cttyioctl(__unused dev_t dev, u_long cmd, caddr_t addr, int flag,
181 struct proc *p)
182 #endif /* !NeXT */
183 {
184 struct vnode *ttyvp = cttyvp(p);
185 struct vfs_context context;
186
187 if (ttyvp == NULL)
188 return (EIO);
189 if (cmd == TIOCSCTTY) /* don't allow controlling tty to be set */
190 return EINVAL; /* to controlling tty -- infinite recursion */
191 if (cmd == TIOCNOTTY) {
192 if (!SESS_LEADER(p)) {
193 p->p_flag &= ~P_CONTROLT;
194 return (0);
195 } else
196 return (EINVAL);
197 }
198 context.vc_proc = p;
199 context.vc_ucred = NOCRED;
200
201 return (VNOP_IOCTL(ttyvp, cmd, addr, flag, &context));
202 }
203
204 /*ARGSUSED*/
205 int
206 cttyselect(__unused dev_t dev, int flag, void* wql, struct proc *p)
207 {
208 struct vnode *ttyvp = cttyvp(p);
209 struct vfs_context context;
210
211 context.vc_proc = p;
212 context.vc_ucred = NOCRED;
213
214 if (ttyvp == NULL)
215 return (1); /* try operation to get EOF/failure */
216 return (VNOP_SELECT(ttyvp, flag, FREAD|FWRITE, wql, &context));
217 }
218
219 #ifndef NeXT
220 static ctty_devsw_installed = 0;
221 #ifdef DEVFS
222 static void *ctty_devfs_token;
223 #endif
224
225 static void
226 ctty_drvinit(void *unused)
227 {
228 dev_t dev;
229
230 if( ! ctty_devsw_installed ) {
231 dev = makedev(CDEV_MAJOR,0);
232 cdevsw_add(&dev,&ctty_cdevsw,NULL);
233 ctty_devsw_installed = 1;
234 #ifdef DEVFS
235 ctty_devfs_token =
236 devfs_add_devswf(&ctty_cdevsw, 0, DV_CHR, 0, 0,
237 0666, "tty");
238 #endif
239 }
240 }
241
242 SYSINIT(cttydev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,ctty_drvinit,NULL)
243
244
245 #endif /* !NeXT */