Annotation of sys/dev/cons.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: cons.c,v 1.18 2007/06/17 18:50:58 jasper Exp $ */
2: /* $NetBSD: cons.c,v 1.30 1996/04/08 19:57:30 jonathan Exp $ */
3:
4: /*
5: * Copyright (c) 1988 University of Utah.
6: * Copyright (c) 1990, 1993
7: * The Regents of the University of California. All rights reserved.
8: *
9: * This code is derived from software contributed to Berkeley by
10: * the Systems Programming Group of the University of Utah Computer
11: * Science Department.
12: *
13: * Redistribution and use in source and binary forms, with or without
14: * modification, are permitted provided that the following conditions
15: * are met:
16: * 1. Redistributions of source code must retain the above copyright
17: * notice, this list of conditions and the following disclaimer.
18: * 2. Redistributions in binary form must reproduce the above copyright
19: * notice, this list of conditions and the following disclaimer in the
20: * documentation and/or other materials provided with the distribution.
21: * 3. Neither the name of the University nor the names of its contributors
22: * may be used to endorse or promote products derived from this software
23: * without specific prior written permission.
24: *
25: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35: * SUCH DAMAGE.
36: *
37: * from: Utah $Hdr: cons.c 1.7 92/01/21$
38: *
39: * @(#)cons.c 8.2 (Berkeley) 1/12/94
40: */
41:
42: #include <sys/param.h>
43: #include <sys/systm.h>
44: #include <sys/proc.h>
45: #include <sys/user.h>
46: #include <sys/buf.h>
47: #include <sys/ioctl.h>
48: #include <sys/tty.h>
49: #include <sys/file.h>
50: #include <sys/conf.h>
51: #include <sys/vnode.h>
52: #include <sys/poll.h>
53:
54: #include <dev/cons.h>
55:
56: struct tty *constty = NULL; /* virtual console output device */
57: struct consdev *cn_tab; /* physical console device info */
58: struct vnode *cn_devvp; /* vnode for underlying device. */
59:
60: int
61: cnopen(dev_t dev, int flag, int mode, struct proc *p)
62: {
63: dev_t cndev;
64:
65: if (cn_tab == NULL)
66: return (0);
67:
68: /*
69: * always open the 'real' console device, so we don't get nailed
70: * later. This follows normal device semantics; they always get
71: * open() calls.
72: */
73: cndev = cn_tab->cn_dev;
74: if (cndev == NODEV)
75: return (ENXIO);
76: #ifdef DIAGNOSTIC
77: if (cndev == dev)
78: panic("cnopen: recursive");
79: #endif
80: if (cn_devvp == NULLVP) {
81: /* try to get a reference on its vnode, but fail silently */
82: cdevvp(cndev, &cn_devvp);
83: }
84: return ((*cdevsw[major(cndev)].d_open)(cndev, flag, mode, p));
85: }
86:
87: int
88: cnclose(dev_t dev, int flag, int mode, struct proc *p)
89: {
90: struct vnode *vp;
91:
92: if (cn_tab == NULL)
93: return (0);
94:
95: /*
96: * If the real console isn't otherwise open, close it.
97: * If it's otherwise open, don't close it, because that'll
98: * screw up others who have it open.
99: */
100: dev = cn_tab->cn_dev;
101: if (cn_devvp != NULLVP) {
102: /* release our reference to real dev's vnode */
103: vrele(cn_devvp);
104: cn_devvp = NULLVP;
105: }
106: if (vfinddev(dev, VCHR, &vp) && vcount(vp))
107: return (0);
108: return ((*cdevsw[major(dev)].d_close)(dev, flag, mode, p));
109: }
110:
111: int
112: cnread(dev_t dev, struct uio *uio, int flag)
113: {
114:
115: /*
116: * If we would redirect input, punt. This will keep strange
117: * things from happening to people who are using the real
118: * console. Nothing should be using /dev/console for
119: * input (except a shell in single-user mode, but then,
120: * one wouldn't TIOCCONS then).
121: */
122: if (constty != NULL)
123: return 0;
124: else if (cn_tab == NULL)
125: return ENXIO;
126:
127: dev = cn_tab->cn_dev;
128: return ((*cdevsw[major(dev)].d_read)(dev, uio, flag));
129: }
130:
131: int
132: cnwrite(dev_t dev, struct uio *uio, int flag)
133: {
134:
135: /*
136: * Redirect output, if that's appropriate.
137: * If there's no real console, return ENXIO.
138: */
139: if (constty != NULL)
140: dev = constty->t_dev;
141: else if (cn_tab == NULL)
142: return ENXIO;
143: else
144: dev = cn_tab->cn_dev;
145: return ((*cdevsw[major(dev)].d_write)(dev, uio, flag));
146: }
147:
148: int
149: cnstop(struct tty *tp, int flag)
150: {
151: return (0);
152: }
153:
154: int
155: cnioctl(dev_t dev, u_long cmd, caddr_t data, int flag,
156: struct proc *p)
157: {
158: int error;
159:
160: /*
161: * Superuser can always use this to wrest control of console
162: * output from the "virtual" console.
163: */
164: if (cmd == TIOCCONS && constty != NULL) {
165: error = suser(p, SUSER_NOACCT);
166: if (error)
167: return (error);
168: constty = NULL;
169: return (0);
170: }
171:
172: /*
173: * Redirect the ioctl, if that's appropriate.
174: * Note that strange things can happen, if a program does
175: * ioctls on /dev/console, then the console is redirected
176: * out from under it.
177: */
178: if (constty != NULL)
179: dev = constty->t_dev;
180: else if (cn_tab == NULL)
181: return ENXIO;
182: else
183: dev = cn_tab->cn_dev;
184: return ((*cdevsw[major(dev)].d_ioctl)(dev, cmd, data, flag, p));
185: }
186:
187: /*ARGSUSED*/
188: int
189: cnpoll(dev_t dev, int rw, struct proc *p)
190: {
191:
192: /*
193: * Redirect the poll, if that's appropriate.
194: * I don't want to think of the possible side effects
195: * of console redirection here.
196: */
197: if (constty != NULL)
198: dev = constty->t_dev;
199: else if (cn_tab == NULL)
200: return POLLERR;
201: else
202: dev = cn_tab->cn_dev;
203: return (ttpoll(cn_tab->cn_dev, rw, p));
204: }
205:
206:
207: int
208: cnkqfilter(dev_t dev, struct knote *kn)
209: {
210:
211: /*
212: * Redirect output, if that's appropriate.
213: * If there's no real console, return 1.
214: */
215: if (constty != NULL)
216: dev = constty->t_dev;
217: else if (cn_tab == NULL)
218: return (1);
219: else
220: dev = cn_tab->cn_dev;
221: if (cdevsw[major(dev)].d_flags & D_KQFILTER)
222: return ((*cdevsw[major(dev)].d_kqfilter)(dev, kn));
223: return (1);
224: }
225:
226: int
227: cngetc(void)
228: {
229:
230: if (cn_tab == NULL)
231: return (0);
232: return ((*cn_tab->cn_getc)(cn_tab->cn_dev));
233: }
234:
235: void
236: cnputc(int c)
237: {
238:
239: if (cn_tab == NULL)
240: return;
241:
242: if (c) {
243: (*cn_tab->cn_putc)(cn_tab->cn_dev, c);
244: if (c == '\n')
245: (*cn_tab->cn_putc)(cn_tab->cn_dev, '\r');
246: }
247: }
248:
249: void
250: cnpollc(int on)
251: {
252: static int refcount = 0;
253:
254: if (cn_tab == NULL)
255: return;
256: if (!on)
257: --refcount;
258: if (refcount == 0)
259: (*cn_tab->cn_pollc)(cn_tab->cn_dev, on);
260: if (on)
261: ++refcount;
262: }
263:
264: void
265: nullcnpollc(dev_t dev, int on)
266: {
267:
268: }
269:
270: void
271: cnbell(u_int pitch, u_int period, u_int volume)
272: {
273: if (cn_tab == NULL || cn_tab->cn_bell == NULL)
274: return;
275:
276: (*cn_tab->cn_bell)(cn_tab->cn_dev, pitch, period, volume);
277: }
CVSweb