xref: /original-bsd/sys/kern/tty_tty.c (revision 0ac4996f)
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*/
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*/
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*/
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*/
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*/
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