pty.c (61473) | pty.c (64880) |
---|---|
1/* 2 * Copyright (c) 1982, 1986, 1989, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 17 unchanged lines hidden (view full) --- 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * @(#)tty_pty.c 8.4 (Berkeley) 2/20/95 | 1/* 2 * Copyright (c) 1982, 1986, 1989, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 17 unchanged lines hidden (view full) --- 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * @(#)tty_pty.c 8.4 (Berkeley) 2/20/95 |
34 * $FreeBSD: head/sys/kern/tty_pty.c 61473 2000-06-10 07:12:40Z peter $ | 34 * $FreeBSD: head/sys/kern/tty_pty.c 64880 2000-08-20 21:34:39Z phk $ |
35 */ 36 37/* 38 * Pseudo-teletype Driver 39 * (Actually two drivers, requiring two entries in 'cdevsw') 40 */ 41#include "opt_compat.h" | 35 */ 36 37/* 38 * Pseudo-teletype Driver 39 * (Actually two drivers, requiring two entries in 'cdevsw') 40 */ 41#include "opt_compat.h" |
42#include "opt_devfs.h" |
|
42#include <sys/param.h> 43#include <sys/systm.h> 44#if defined(COMPAT_43) || defined(COMPAT_SUNOS) 45#include <sys/ioctl_compat.h> 46#endif 47#include <sys/proc.h> 48#include <sys/tty.h> 49#include <sys/conf.h> 50#include <sys/fcntl.h> 51#include <sys/poll.h> 52#include <sys/kernel.h> 53#include <sys/vnode.h> 54#include <sys/signalvar.h> 55#include <sys/malloc.h> 56 | 43#include <sys/param.h> 44#include <sys/systm.h> 45#if defined(COMPAT_43) || defined(COMPAT_SUNOS) 46#include <sys/ioctl_compat.h> 47#endif 48#include <sys/proc.h> 49#include <sys/tty.h> 50#include <sys/conf.h> 51#include <sys/fcntl.h> 52#include <sys/poll.h> 53#include <sys/kernel.h> 54#include <sys/vnode.h> 55#include <sys/signalvar.h> 56#include <sys/malloc.h> 57 |
58#ifdef DEVFS 59#include <sys/eventhandler.h> 60#include <fs/devfs/devfs.h> 61#endif 62 |
|
57MALLOC_DEFINE(M_PTY, "ptys", "pty data structures"); 58 59static void ptsstart __P((struct tty *tp)); 60static void ptsstop __P((struct tty *tp, int rw)); 61static void ptcwakeup __P((struct tty *tp, int flag)); | 63MALLOC_DEFINE(M_PTY, "ptys", "pty data structures"); 64 65static void ptsstart __P((struct tty *tp)); 66static void ptsstop __P((struct tty *tp, int rw)); 67static void ptcwakeup __P((struct tty *tp, int flag)); |
62static void ptyinit __P((int n)); | 68static dev_t ptyinit __P((int n)); |
63 64static d_open_t ptsopen; 65static d_close_t ptsclose; 66static d_read_t ptsread; 67static d_write_t ptswrite; 68static d_ioctl_t ptyioctl; 69static d_open_t ptcopen; 70static d_close_t ptcclose; --- 59 unchanged lines hidden (view full) --- 130 * This function creates and initializes a pts/ptc pair 131 * 132 * pts == /dev/tty[pqrsPQRS][0123456789abcdefghijklmnopqrstuv] 133 * ptc == /dev/pty[pqrsPQRS][0123456789abcdefghijklmnopqrstuv] 134 * 135 * XXX: define and add mapping of upper minor bits to allow more 136 * than 256 ptys. 137 */ | 69 70static d_open_t ptsopen; 71static d_close_t ptsclose; 72static d_read_t ptsread; 73static d_write_t ptswrite; 74static d_ioctl_t ptyioctl; 75static d_open_t ptcopen; 76static d_close_t ptcclose; --- 59 unchanged lines hidden (view full) --- 136 * This function creates and initializes a pts/ptc pair 137 * 138 * pts == /dev/tty[pqrsPQRS][0123456789abcdefghijklmnopqrstuv] 139 * ptc == /dev/pty[pqrsPQRS][0123456789abcdefghijklmnopqrstuv] 140 * 141 * XXX: define and add mapping of upper minor bits to allow more 142 * than 256 ptys. 143 */ |
138static void | 144static dev_t |
139ptyinit(n) 140 int n; 141{ 142 dev_t devs, devc; 143 char *names = "pqrsPQRS"; 144 struct pt_ioctl *pt; 145 146 /* For now we only map the lower 8 bits of the minor */ 147 if (n & ~0xff) | 145ptyinit(n) 146 int n; 147{ 148 dev_t devs, devc; 149 char *names = "pqrsPQRS"; 150 struct pt_ioctl *pt; 151 152 /* For now we only map the lower 8 bits of the minor */ 153 if (n & ~0xff) |
148 return; | 154 return (NODEV); |
149 150 pt = malloc(sizeof(*pt), M_PTY, M_WAITOK); 151 bzero(pt, sizeof(*pt)); 152 pt->devs = devs = make_dev(&pts_cdevsw, n, 153 0, 0, 0666, "tty%c%r", names[n / 32], n % 32); 154 pt->devc = devc = make_dev(&ptc_cdevsw, n, 155 0, 0, 0666, "pty%c%r", names[n / 32], n % 32); 156 157 devs->si_drv1 = devc->si_drv1 = pt; 158 devs->si_tty = devc->si_tty = &pt->pt_tty; 159 ttyregister(&pt->pt_tty); | 155 156 pt = malloc(sizeof(*pt), M_PTY, M_WAITOK); 157 bzero(pt, sizeof(*pt)); 158 pt->devs = devs = make_dev(&pts_cdevsw, n, 159 0, 0, 0666, "tty%c%r", names[n / 32], n % 32); 160 pt->devc = devc = make_dev(&ptc_cdevsw, n, 161 0, 0, 0666, "pty%c%r", names[n / 32], n % 32); 162 163 devs->si_drv1 = devc->si_drv1 = pt; 164 devs->si_tty = devc->si_tty = &pt->pt_tty; 165 ttyregister(&pt->pt_tty); |
166 return (devc); |
|
160} 161 162/*ARGSUSED*/ 163static int 164ptsopen(dev, flag, devtype, p) 165 dev_t dev; 166 int flag, devtype; 167 struct proc *p; 168{ 169 register struct tty *tp; 170 int error; | 167} 168 169/*ARGSUSED*/ 170static int 171ptsopen(dev, flag, devtype, p) 172 dev_t dev; 173 int flag, devtype; 174 struct proc *p; 175{ 176 register struct tty *tp; 177 int error; |
171 int minr; 172 dev_t nextdev; | |
173 struct pt_ioctl *pti; 174 | 178 struct pt_ioctl *pti; 179 |
180#ifndef DEVFS 181 { 182 int minr = lminor(dev); |
|
175 /* | 183 /* |
176 * XXX: Gross hack for DEVFS: | |
177 * If we openned this device, ensure we have the 178 * next one too, so people can open it. 179 */ | 184 * If we openned this device, ensure we have the 185 * next one too, so people can open it. 186 */ |
180 minr = lminor(dev); | |
181 if (minr < 255) { | 187 if (minr < 255) { |
182 nextdev = makedev(major(dev), minr + 1); | 188 dev_t nextdev = makedev(major(dev), minr + 1); |
183 if (!nextdev->si_drv1) { 184 ptyinit(minr + 1); 185 } 186 } 187 if (!dev->si_drv1) 188 ptyinit(minor(dev)); | 189 if (!nextdev->si_drv1) { 190 ptyinit(minr + 1); 191 } 192 } 193 if (!dev->si_drv1) 194 ptyinit(minor(dev)); |
195 } 196#endif |
|
189 if (!dev->si_drv1) 190 return(ENXIO); 191 pti = dev->si_drv1; 192 tp = dev->si_tty; 193 if ((tp->t_state & TS_ISOPEN) == 0) { 194 ttychars(tp); /* Set up default chars */ 195 tp->t_iflag = TTYDEF_IFLAG; 196 tp->t_oflag = TTYDEF_OFLAG; --- 145 unchanged lines hidden (view full) --- 342ptcopen(dev, flag, devtype, p) 343 dev_t dev; 344 int flag, devtype; 345 struct proc *p; 346{ 347 register struct tty *tp; 348 struct pt_ioctl *pti; 349 | 197 if (!dev->si_drv1) 198 return(ENXIO); 199 pti = dev->si_drv1; 200 tp = dev->si_tty; 201 if ((tp->t_state & TS_ISOPEN) == 0) { 202 ttychars(tp); /* Set up default chars */ 203 tp->t_iflag = TTYDEF_IFLAG; 204 tp->t_oflag = TTYDEF_OFLAG; --- 145 unchanged lines hidden (view full) --- 350ptcopen(dev, flag, devtype, p) 351 dev_t dev; 352 int flag, devtype; 353 struct proc *p; 354{ 355 register struct tty *tp; 356 struct pt_ioctl *pti; 357 |
358#ifndef DEVFS |
|
350 if (!dev->si_drv1) 351 ptyinit(minor(dev)); | 359 if (!dev->si_drv1) 360 ptyinit(minor(dev)); |
361#endif |
|
352 if (!dev->si_drv1) 353 return(ENXIO); 354 tp = dev->si_tty; 355 if (tp->t_oproc) 356 return (EIO); 357 tp->t_timeout = -1; 358 tp->t_oproc = ptsstart; 359 tp->t_stop = ptsstop; --- 451 unchanged lines hidden (view full) --- 811 } 812 } 813 return (error); 814} 815 816 817static void ptc_drvinit __P((void *unused)); 818 | 362 if (!dev->si_drv1) 363 return(ENXIO); 364 tp = dev->si_tty; 365 if (tp->t_oproc) 366 return (EIO); 367 tp->t_timeout = -1; 368 tp->t_oproc = ptsstart; 369 tp->t_stop = ptsstop; --- 451 unchanged lines hidden (view full) --- 821 } 822 } 823 return (error); 824} 825 826 827static void ptc_drvinit __P((void *unused)); 828 |
829#ifdef DEVFS 830static void pty_clone __P((void *arg, char *name, int namelen, dev_t *dev)); 831 |
|
819static void | 832static void |
833pty_clone(arg, name, namelen, dev) 834 void *arg; 835 char *name; 836 int namelen; 837 dev_t *dev; 838{ 839 int u; 840 841 if (*dev != NODEV) 842 return; 843 if (bcmp(name, "pty", 3) != 0) 844 return; 845 if (name[5] != '\0') 846 return; 847 switch (name[3]) { 848 case 'p': u = 0; break; 849 case 'q': u = 32; break; 850 case 'r': u = 64; break; 851 case 's': u = 96; break; 852 case 'P': u = 128; break; 853 case 'Q': u = 160; break; 854 case 'R': u = 192; break; 855 case 'S': u = 224; break; 856 default: return; 857 } 858 if (name[4] >= '0' && name[4] <= '9') 859 u += name[4] - '0'; 860 else if (name[4] >= 'a' && name[4] <= 'v') 861 u += name[4] - 'a' + 10; 862 else 863 return; 864 *dev = ptyinit(u); 865 return; 866} 867 868 869#endif 870 871static void |
|
820ptc_drvinit(unused) 821 void *unused; 822{ | 872ptc_drvinit(unused) 873 void *unused; 874{ |
875#ifdef DEVFS 876 EVENTHANDLER_REGISTER(devfs_clone, pty_clone, 0, 1000); 877#else |
|
823 cdevsw_add(&pts_cdevsw); 824 cdevsw_add(&ptc_cdevsw); | 878 cdevsw_add(&pts_cdevsw); 879 cdevsw_add(&ptc_cdevsw); |
825 /* XXX: Gross hack for DEVFS */ | |
826 ptyinit(0); | 880 ptyinit(0); |
881#endif |
|
827} 828 829SYSINIT(ptcdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR_C,ptc_drvinit,NULL) | 882} 883 884SYSINIT(ptcdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR_C,ptc_drvinit,NULL) |