diff options
author | jhb <jhb@FreeBSD.org> | 2007-11-08 15:51:52 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2007-11-08 15:51:52 +0000 |
commit | 3a40a5ed4b786bf73f078c9fe24b319789a2c8a6 (patch) | |
tree | 9c3468dbd516a1fccc1177499a42176db0f72c6c /sys | |
parent | 6111e1564791ad4687b645ebd1434014c6ea9827 (diff) | |
download | FreeBSD-src-3a40a5ed4b786bf73f078c9fe24b319789a2c8a6.zip FreeBSD-src-3a40a5ed4b786bf73f078c9fe24b319789a2c8a6.tar.gz |
Make it easier to add more ptys to the pty(4) driver:
- Use unit2minor() and minor2unit() to generate minor numbers to support
unit numbers higher than 255.
- Use simple string operations on the 'names' array rather than hard-coded
constants and switch statements so that more ptys can be added by simply
expanding the 'names' array.
MFC after: 1 week
Diffstat (limited to 'sys')
-rw-r--r-- | sys/kern/tty_pty.c | 31 |
1 files changed, 12 insertions, 19 deletions
diff --git a/sys/kern/tty_pty.c b/sys/kern/tty_pty.c index 9079a64..01b7ae9 100644 --- a/sys/kern/tty_pty.c +++ b/sys/kern/tty_pty.c @@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$"); #include "opt_tty.h" #include <sys/param.h> #include <sys/systm.h> +#include <sys/libkern.h> #include <sys/lock.h> #include <sys/mutex.h> #include <sys/sx.h> @@ -127,9 +128,6 @@ static char *names = "pqrsPQRS"; * * pts == /dev/tty[pqrsPQRS][0123456789abcdefghijklmnopqrstuv] * ptc == /dev/pty[pqrsPQRS][0123456789abcdefghijklmnopqrstuv] - * - * XXX: define and add mapping of upper minor bits to allow more - * than 256 ptys. */ static struct cdev * ptyinit(struct cdev *devc, struct thread *td) @@ -137,9 +135,10 @@ ptyinit(struct cdev *devc, struct thread *td) struct ptsc *pt; int n; - n = minor(devc); - /* For now we only map the lower 8 bits of the minor */ - if (n & ~0xff) + n = minor2unit(minor(devc)); + + /* We only allow for up to 32 ptys per char in "names". */ + if (n >= 32 * strlen(names)) return (NULL); devc->si_flags &= ~SI_CHEAPCLONE; @@ -760,32 +759,26 @@ static void pty_clone(void *arg, struct ucred *cr, char *name, int namelen, struct cdev **dev) { + char *cp; int u; if (*dev != NULL) return; if (bcmp(name, "pty", 3) != 0) return; - if (name[5] != '\0') + if (name[5] != '\0' || name[3] == '\0') return; - switch (name[3]) { - case 'p': u = 0; break; - case 'q': u = 32; break; - case 'r': u = 64; break; - case 's': u = 96; break; - case 'P': u = 128; break; - case 'Q': u = 160; break; - case 'R': u = 192; break; - case 'S': u = 224; break; - default: return; - } + cp = index(names, name[3]); + if (cp == NULL) + return; + u = (cp - names) * 32; if (name[4] >= '0' && name[4] <= '9') u += name[4] - '0'; else if (name[4] >= 'a' && name[4] <= 'v') u += name[4] - 'a' + 10; else return; - *dev = make_dev_credf(MAKEDEV_REF, &ptc_cdevsw, u, cr, + *dev = make_dev_credf(MAKEDEV_REF, &ptc_cdevsw, unit2minor(u), cr, UID_ROOT, GID_WHEEL, 0666, "pty%c%r", names[u / 32], u % 32); (*dev)->si_flags |= SI_CHEAPCLONE; return; |