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