summaryrefslogtreecommitdiff
path: root/lib/libutil
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libutil')
-rw-r--r--lib/libutil/openpty.325
-rw-r--r--lib/libutil/pty.c39
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