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