diff options
author | cperciva <cperciva@FreeBSD.org> | 2008-01-15 13:59:13 +0000 |
---|---|---|
committer | cperciva <cperciva@FreeBSD.org> | 2008-01-15 13:59:13 +0000 |
commit | 2f49f42d9897ece98b6573c303c5f917a2e7e0f0 (patch) | |
tree | bd137abc0e589d119fb45a7656f45a563f635214 /lib/libutil | |
parent | 291172a6df72327af2842f5dc9da5e5426ad139f (diff) | |
download | FreeBSD-src-2f49f42d9897ece98b6573c303c5f917a2e7e0f0.zip FreeBSD-src-2f49f42d9897ece98b6573c303c5f917a2e7e0f0.tar.gz |
Back out last commit, since it accidentally broke pts.
The security fix will be re-committed soon, hopefully without breaking
anything.
Diffstat (limited to 'lib/libutil')
-rw-r--r-- | lib/libutil/pty.c | 58 |
1 files changed, 55 insertions, 3 deletions
diff --git a/lib/libutil/pty.c b/lib/libutil/pty.c index 15f258b..1fe8be2 100644 --- a/lib/libutil/pty.c +++ b/lib/libutil/pty.c @@ -49,8 +49,10 @@ static char sccsid[] = "@(#)pty.c 8.3 (Berkeley) 5/16/94"; #include <termios.h> #include <unistd.h> -int -openpty(int *amaster, int *aslave, char *name, struct termios *termp, +int __use_pts(void); + +static int +new_openpty(int *amaster, int *aslave, char *name, struct termios *termp, struct winsize *winp) { const char *slavename; @@ -92,7 +94,7 @@ openpty(int *amaster, int *aslave, char *name, struct termios *termp, *aslave = slave; if (name) - strcpy(name, slavename); + strcpy(name, ptsname(master)); if (termp) tcsetattr(slave, TCSAFLUSH, termp); if (winp) @@ -102,6 +104,56 @@ openpty(int *amaster, int *aslave, char *name, struct termios *termp, } int +openpty(int *amaster, int *aslave, char *name, struct termios *termp, struct winsize *winp) +{ + char line[] = "/dev/ptyXX"; + const char *cp1, *cp2; + int master, slave, ttygid; + struct group *gr; + + if (__use_pts()) + return (new_openpty(amaster, aslave, name, termp, winp)); + + if ((gr = getgrnam("tty")) != NULL) + ttygid = gr->gr_gid; + else + ttygid = -1; + + for (cp1 = "pqrsPQRSlmnoLMNO"; *cp1; cp1++) { + line[8] = *cp1; + for (cp2 = "0123456789abcdefghijklmnopqrstuv"; *cp2; cp2++) { + line[5] = 'p'; + line[9] = *cp2; + if ((master = open(line, O_RDWR, 0)) == -1) { + if (errno == ENOENT) + break; /* try the next pty group */ + } else { + line[5] = 't'; + (void) chown(line, getuid(), ttygid); + (void) chmod(line, S_IRUSR|S_IWUSR|S_IWGRP); + (void) revoke(line); + if ((slave = open(line, O_RDWR, 0)) != -1) { + *amaster = master; + *aslave = slave; + if (name) + strcpy(name, line); + if (termp) + (void) tcsetattr(slave, + TCSAFLUSH, termp); + if (winp) + (void) ioctl(slave, TIOCSWINSZ, + (char *)winp); + return (0); + } + (void) close(master); + } + } + } + errno = ENOENT; /* out of ptys */ + return (-1); +} + +int forkpty(int *amaster, char *name, struct termios *termp, struct winsize *winp) { int master, slave, pid; |