diff options
Diffstat (limited to 'lib/libutil')
-rw-r--r-- | lib/libutil/openpty.3 | 25 | ||||
-rw-r--r-- | lib/libutil/pty.c | 39 |
2 files changed, 60 insertions, 4 deletions
diff --git a/lib/libutil/openpty.3 b/lib/libutil/openpty.3 index 4794f7846c0..986912b6e05 100644 --- a/lib/libutil/openpty.3 +++ b/lib/libutil/openpty.3 @@ -1,4 +1,4 @@ -.\" $OpenBSD: openpty.3,v 1.11 2003/06/02 20:18:42 millert Exp $ +.\" $OpenBSD: openpty.3,v 1.12 2004/02/10 01:31:20 millert Exp $ .\" Copyright (c) 1995 .\" The Regents of the University of California. All rights reserved. .\" @@ -78,6 +78,24 @@ is non-null, the window size of the slave will be set to the values in .Fa winp . .Pp The +.Fn openpty +function works in the following way: +first it attempts to allocate the pseudo-tty through the +.Pa /dev/ptm +device (see +.Xr pty 4 +for details) and if that fails it searches for a free psuedo-tty by iterating +through all existing pseudo-tty devices in +.Pa /dev . +When a free pseudo-tty is found, its ownership is changed to +the UID of the caller, permissions are set to correct values, +and all earlier uses of that device are revoked (see +.Xr revoke 2 +for details). +The first method can work for any user, the second method requires +super-user privileges in most cases. +.Pp +The .Fn login_tty function prepares for a login on the tty .Fa fd @@ -132,6 +150,7 @@ returns the process ID of the child process. .Sh FILES .Bl -tag -width /dev/[pt]ty[pqrstuvwxyzPQRST][0123456789abcdef] -compact .It Pa /dev/[pt]ty[pqrstuvwxyzPQRST][0123456789abcdef] +.It Pa /dev/ptm .El .Sh ERRORS .Fn openpty @@ -154,4 +173,6 @@ or .Fn fork fails. .Sh SEE ALSO -.Xr fork 2 +.Xr fork 2 , +.Xr revoke 2 , +.Xr pty 4 diff --git a/lib/libutil/pty.c b/lib/libutil/pty.c index 743daf70491..a8fa7671537 100644 --- a/lib/libutil/pty.c +++ b/lib/libutil/pty.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pty.c,v 1.10 2003/06/02 20:18:42 millert Exp $ */ +/* $OpenBSD: pty.c,v 1.11 2004/02/10 01:31:20 millert Exp $ */ /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. @@ -30,7 +30,7 @@ #if defined(LIBC_SCCS) && !defined(lint) /* from: static char sccsid[] = "@(#)pty.c 8.1 (Berkeley) 6/4/93"; */ -static const char rcsid[] = "$Id: pty.c,v 1.10 2003/06/02 20:18:42 millert Exp $"; +static const char rcsid[] = "$Id: pty.c,v 1.11 2004/02/10 01:31:20 millert Exp $"; #endif /* LIBC_SCCS and not lint */ #include <sys/cdefs.h> @@ -44,6 +44,7 @@ static const char rcsid[] = "$Id: pty.c,v 1.10 2003/06/02 20:18:42 millert Exp $ #include <stdio.h> #include <string.h> #include <grp.h> +#include <sys/tty.h> #include "util.h" @@ -60,7 +61,41 @@ openpty(amaster, aslave, name, termp, winp) register const char *cp1, *cp2; register int master, slave, ttygid; struct group *gr; + struct ptmget ptm; + int fd; + /* Try to use /dev/ptm and the PTMGET ioctl to get a properly set up + * and owned pty/tty pair. If this fails, (because we might not have + * the ptm device, etc.) fall back to using the traditional method + * of walking through the pty entries in /dev for the moment, until + * there is less chance of people being seriously boned by running + * kernels without /dev/ptm in them. + */ + + fd = open(PATH_PTMDEV, O_RDWR, 0); + if (fd == -1) + goto walkit; + if ((ioctl(fd, PTMGET, &ptm) == -1)) { + close(fd); + goto walkit; + } + close(fd); + master = ptm.cfd; + slave = ptm.sfd; + if (name) { + /* + * Manual page says "at least 16 characters". + */ + strlcpy(name, ptm.sn, 16); + } + *amaster = master; + *aslave = slave; + if (termp) + (void) tcsetattr(slave, TCSAFLUSH, termp); + if (winp) + (void) ioctl(slave, TIOCSWINSZ, (char *)winp); + return (0); + walkit: if ((gr = getgrnam("tty")) != NULL) ttygid = gr->gr_gid; else |