X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/21362eb3e66fd2c787aee132bce100a44d71a99c..36401178fd6817c043cc00b0c00c7f723e58efae:/bsd/kern/tty_tty.c diff --git a/bsd/kern/tty_tty.c b/bsd/kern/tty_tty.c index fac3c37cd..1c9882d96 100644 --- a/bsd/kern/tty_tty.c +++ b/bsd/kern/tty_tty.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * Copyright (c) 1997-2006 Apple Computer, Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * @@ -25,7 +25,6 @@ * * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ -/* Copyright (c) 1997 Apple Computer, Inc. All Rights Reserved */ /*- * Copyright (c) 1982, 1986, 1991, 1993 * The Regents of the University of California. All rights reserved. @@ -72,173 +71,153 @@ #include #include #include -#ifndef NeXT -#include -#ifdef DEVFS -#include -#endif /*DEVFS*/ - -static d_open_t cttyopen; -static d_read_t cttyread; -static d_write_t cttywrite; -static d_ioctl_t cttyioctl; -static d_select_t cttyselect; - -#endif /* !NeXT */ +#include /* Forward declarations for cdevsw[] entry */ /* XXX we should consider making these static */ -int cttyopen(dev_t dev, int flag, int mode, struct proc *p); +int cttyopen(dev_t dev, int flag, int mode, proc_t p); int cttyread(dev_t dev, struct uio *uio, int flag); int cttywrite(dev_t dev, struct uio *uio, int flag); -int cttyioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p); -int cttyselect(dev_t dev, int flag, void* wql, struct proc *p); - -#ifndef NeXT - -#define CDEV_MAJOR 1 -/* Don't make static, fdesc_vnops uses this. */ -struct cdevsw ctty_cdevsw = - { cttyopen, nullclose, cttyread, cttywrite, /*1*/ - cttyioctl, nullstop, nullreset, nodevtotty,/* tty */ - cttyselect, nommap, NULL, "ctty", NULL, -1 }; +int cttyioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, proc_t p); +int cttyselect(dev_t dev, int flag, void* wql, proc_t p); +static vnode_t cttyvp(proc_t p); -#endif /* !NeXT */ -#define cttyvp(p) ((p)->p_flag & P_CONTROLT ? (p)->p_session->s_ttyvp : NULL) - -/*ARGSUSED*/ int -cttyopen(__unused dev_t dev, int flag, __unused int mode, struct proc *p) +cttyopen(__unused dev_t dev, int flag, __unused int mode, proc_t p) { - struct vnode *ttyvp = cttyvp(p); + vnode_t ttyvp = cttyvp(p); struct vfs_context context; int error; if (ttyvp == NULL) return (ENXIO); - context.vc_proc = p; - context.vc_ucred = p->p_ucred; + context.vc_thread = current_thread(); + context.vc_ucred = kauth_cred_proc_ref(p); + error = VNOP_OPEN(ttyvp, flag, &context); + vnode_put(ttyvp); + kauth_cred_unref(&context.vc_ucred); return (error); } -/*ARGSUSED*/ int cttyread(__unused dev_t dev, struct uio *uio, int flag) { - struct proc *p = current_proc(); - register struct vnode *ttyvp = cttyvp(p); + vnode_t ttyvp = cttyvp(current_proc()); struct vfs_context context; int error; if (ttyvp == NULL) return (EIO); - context.vc_proc = p; + context.vc_thread = current_thread(); context.vc_ucred = NOCRED; error = VNOP_READ(ttyvp, uio, flag, &context); + vnode_put(ttyvp); return (error); } -/*ARGSUSED*/ int cttywrite(__unused dev_t dev, struct uio *uio, int flag) { - struct proc *p = current_proc(); - register struct vnode *ttyvp = cttyvp(p); + vnode_t ttyvp = cttyvp(current_proc()); struct vfs_context context; int error; if (ttyvp == NULL) return (EIO); - context.vc_proc = p; + context.vc_thread = current_thread(); context.vc_ucred = NOCRED; error = VNOP_WRITE(ttyvp, uio, flag, &context); + vnode_put(ttyvp); return (error); } -/*ARGSUSED*/ -#ifndef NeXT -static int -cttyioctl(dev, cmd, addr, flag, p) - dev_t dev; - int cmd; - caddr_t addr; - int flag; - struct proc *p; -#else int -cttyioctl(__unused dev_t dev, u_long cmd, caddr_t addr, int flag, - struct proc *p) -#endif /* !NeXT */ +cttyioctl(__unused dev_t dev, u_long cmd, caddr_t addr, int flag, proc_t p) { - struct vnode *ttyvp = cttyvp(p); + vnode_t ttyvp = cttyvp(current_proc()); struct vfs_context context; + struct session *sessp; + int error = 0; if (ttyvp == NULL) return (EIO); - if (cmd == TIOCSCTTY) /* don't allow controlling tty to be set */ - return EINVAL; /* to controlling tty -- infinite recursion */ + if (cmd == TIOCSCTTY) { /* don't allow controlling tty to be set */ + error = EINVAL; /* to controlling tty -- infinite recursion */ + goto out; + } if (cmd == TIOCNOTTY) { - if (!SESS_LEADER(p)) { - p->p_flag &= ~P_CONTROLT; - return (0); - } else - return (EINVAL); + sessp = proc_session(p); + if (!SESS_LEADER(p, sessp)) { + OSBitAndAtomic(~((uint32_t)P_CONTROLT), (UInt32 *)&p->p_flag); + if (sessp != SESSION_NULL) + session_rele(sessp); + error = 0; + goto out; + } else { + if (sessp != SESSION_NULL) + session_rele(sessp); + error = EINVAL; + goto out; + } } - context.vc_proc = p; + context.vc_thread = current_thread(); context.vc_ucred = NOCRED; - return (VNOP_IOCTL(ttyvp, cmd, addr, flag, &context)); + error = VNOP_IOCTL(ttyvp, cmd, addr, flag, &context); +out: + vnode_put(ttyvp); + return (error); } -/*ARGSUSED*/ int -cttyselect(__unused dev_t dev, int flag, void* wql, struct proc *p) +cttyselect(__unused dev_t dev, int flag, void* wql, __unused proc_t p) { - struct vnode *ttyvp = cttyvp(p); + vnode_t ttyvp = cttyvp(current_proc()); struct vfs_context context; + int error; - context.vc_proc = p; + context.vc_thread = current_thread(); context.vc_ucred = NOCRED; if (ttyvp == NULL) return (1); /* try operation to get EOF/failure */ - return (VNOP_SELECT(ttyvp, flag, FREAD|FWRITE, wql, &context)); + error = VNOP_SELECT(ttyvp, flag, FREAD|FWRITE, wql, &context); + vnode_put(ttyvp); + return (error); } -#ifndef NeXT -static ctty_devsw_installed = 0; -#ifdef DEVFS -static void *ctty_devfs_token; -#endif - -static void -ctty_drvinit(void *unused) +/* This returns vnode with ioref */ +static vnode_t +cttyvp(proc_t p) { - dev_t dev; - - if( ! ctty_devsw_installed ) { - dev = makedev(CDEV_MAJOR,0); - cdevsw_add(&dev,&ctty_cdevsw,NULL); - ctty_devsw_installed = 1; -#ifdef DEVFS - ctty_devfs_token = - devfs_add_devswf(&ctty_cdevsw, 0, DV_CHR, 0, 0, - 0666, "tty"); -#endif - } -} + vnode_t vp; + int vid; + struct session *sessp; -SYSINIT(cttydev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,ctty_drvinit,NULL) + sessp = proc_session(p); + session_lock(sessp); + vp = (p->p_flag & P_CONTROLT ? sessp->s_ttyvp : NULLVP); + vid = sessp->s_ttyvid; + session_unlock(sessp); + + session_rele(sessp); + + if (vp != NULLVP) { + /* cannot get an IO reference, return NULLVP */ + if (vnode_getwithvid(vp, vid) != 0) + vp = NULLVP; + } + return(vp); +} -#endif /* !NeXT */