diff --git a/share/man/man4/pts.4 b/share/man/man4/pts.4 index dc13a90014f4..d0e8832b9598 100644 --- a/share/man/man4/pts.4 +++ b/share/man/man4/pts.4 @@ -147,15 +147,6 @@ The files used by this pseudo-terminals implementation are: .Pp .Bl -tag -width ".Pa /dev/pts/[num]" -.It Pa /dev/ptmx -Control device, returns a file descriptor to a new master -pseudo-terminal when opened. -This device should not be opened directly. -It's only available for binary compatibility. -New devices should only be allocated with -.Xr posix_openpt 2 -and -.Xr openpty 3 . .It Pa /dev/pts/[num] Pseudo-terminal slave devices. .El diff --git a/share/man/man4/pty.4 b/share/man/man4/pty.4 index 515f912363b4..f72a8bee81c0 100644 --- a/share/man/man4/pty.4 +++ b/share/man/man4/pty.4 @@ -32,7 +32,7 @@ .Os .Sh NAME .Nm pty -.Nd BSD-style compatibility pseudo-terminal driver +.Nd BSD-style and System V-style compatibility pseudo-terminal driver .Sh SYNOPSIS .Cd "device pty" .Sh DESCRIPTION @@ -48,6 +48,12 @@ driver. A device node for this terminal shall be created, which has the name .Pa /dev/ttyXX . .Pp +The +.Nm +driver also provides a cloning System V +.Pa /dev/ptmx +device. +.Pp New code should not try to allocate pseudo-terminals using this interface. It is only provided for compatibility with older C libraries @@ -63,6 +69,9 @@ device names: Pseudo-terminal master devices. .It Pa /dev/tty[l-sL-S][0-9a-v] Pseudo-terminal slave devices. +.It Pa /dev/ptmx +Control device, returns a file descriptor to a new master +pseudo-terminal when opened. .El .Sh DIAGNOSTICS None. @@ -75,7 +84,7 @@ A pseudo-terminal driver appeared in .Bx 4.2 . .Sh BUGS -Unlike previous implementations, the master slave device nodes are +Unlike previous implementations, the master and slave device nodes are destroyed when the PTY becomes unused. A call to .Xr stat 2 diff --git a/sys/dev/pty/pty.c b/sys/dev/pty/pty.c index d3dce9f1746a..c24396a69ca2 100644 --- a/sys/dev/pty/pty.c +++ b/sys/dev/pty/pty.c @@ -47,6 +47,9 @@ __FBSDID("$FreeBSD$"); * the pts(4) driver. We just call into pts(4) to create the actual PTY. * To make sure we don't use the same PTY multiple times, we abuse * si_drv1 inside the cdev to mark whether the PTY is in use. + * + * It also implements a /dev/ptmx device node, which is useful for Linux + * binary emulation. */ static unsigned int pty_warningcnt = 1; @@ -118,6 +121,20 @@ pty_clone(void *arg, struct ucred *cr, char *name, int namelen, NULL, UID_ROOT, GID_WHEEL, 0666, "%s", name); } +static int +ptmx_fdopen(struct cdev *dev __unused, int fflags, struct thread *td, + struct file *fp) +{ + + return (pts_alloc(fflags & (FREAD|FWRITE), td, fp)); +} + +static struct cdevsw ptmx_cdevsw = { + .d_version = D_VERSION, + .d_fdopen = ptmx_fdopen, + .d_name = "ptmx", +}; + static int pty_modevent(module_t mod, int type, void *data) { @@ -125,6 +142,7 @@ pty_modevent(module_t mod, int type, void *data) switch(type) { case MOD_LOAD: EVENTHANDLER_REGISTER(dev_clone, pty_clone, 0, 1000); + make_dev(&ptmx_cdevsw, 0, UID_ROOT, GID_WHEEL, 0666, "ptmx"); break; case MOD_SHUTDOWN: break; diff --git a/sys/kern/tty_pts.c b/sys/kern/tty_pts.c index b38070a3f12e..350244b334dd 100644 --- a/sys/kern/tty_pts.c +++ b/sys/kern/tty_pts.c @@ -32,7 +32,7 @@ __FBSDID("$FreeBSD$"); /* Add compatibility bits for FreeBSD. */ #define PTS_COMPAT -/* Add /dev/ptyXX compat bits. */ +/* Add pty(4) compat bits. */ #define PTS_EXTERNAL /* Add bits to make Linux binaries work. */ #define PTS_LINUX @@ -694,7 +694,10 @@ static struct ttydevsw pts_class = { .tsw_free = ptsdrv_free, }; -static int +#ifndef PTS_EXTERNAL +static +#endif /* !PTS_EXTERNAL */ +int pts_alloc(int fflags, struct thread *td, struct file *fp) { int unit, ok; @@ -815,29 +818,11 @@ posix_openpt(struct thread *td, struct posix_openpt_args *uap) return (0); } -#if defined(PTS_COMPAT) || defined(PTS_LINUX) -static int -ptmx_fdopen(struct cdev *dev, int fflags, struct thread *td, struct file *fp) -{ - - return (pts_alloc(fflags & (FREAD|FWRITE), td, fp)); -} - -static struct cdevsw ptmx_cdevsw = { - .d_version = D_VERSION, - .d_fdopen = ptmx_fdopen, - .d_name = "ptmx", -}; -#endif /* PTS_COMPAT || PTS_LINUX */ - static void pts_init(void *unused) { pts_pool = new_unrhdr(0, INT_MAX, NULL); -#if defined(PTS_COMPAT) || defined(PTS_LINUX) - make_dev(&ptmx_cdevsw, 0, UID_ROOT, GID_WHEEL, 0666, "ptmx"); -#endif /* PTS_COMPAT || PTS_LINUX */ } SYSINIT(pts, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, pts_init, NULL); diff --git a/sys/sys/tty.h b/sys/sys/tty.h index d5d38459ee4a..13c89f92c07b 100644 --- a/sys/sys/tty.h +++ b/sys/sys/tty.h @@ -202,6 +202,7 @@ void tty_info(struct tty *tp); void ttyconsdev_select(const char *name); /* Pseudo-terminal hooks. */ +int pts_alloc(int fflags, struct thread *td, struct file *fp); int pts_alloc_external(int fd, struct thread *td, struct file *fp, struct cdev *dev, const char *name);