From ad3d96f8b792149d4a623584f8b403d40bd60331 Mon Sep 17 00:00:00 2001 From: Eric Andersen Date: Mon, 14 Jan 2002 09:10:50 +0000 Subject: Patch from Brian Stafford to fixup support for Unix98 PTYs, and optionally exclude the older junk. --- libc/stdlib/getpt.c | 33 +++++++++++++++++++++++++------- libc/stdlib/grantpt.c | 26 +++++++++++++++++-------- libc/stdlib/ptsname.c | 53 ++++++++++++++++++++++++++++++++++----------------- 3 files changed, 80 insertions(+), 32 deletions(-) (limited to 'libc/stdlib') diff --git a/libc/stdlib/getpt.c b/libc/stdlib/getpt.c index 0ee2d90d6..9e1f255bb 100644 --- a/libc/stdlib/getpt.c +++ b/libc/stdlib/getpt.c @@ -22,33 +22,45 @@ #include #include #include -#include + +#if !defined ASSUME_DEVPTS +# include /* Constant that identifies the `devpts' filesystem. */ -#define DEVPTS_SUPER_MAGIC 0x1cd1 +# define DEVPTS_SUPER_MAGIC 0x1cd1 /* Constant that identifies the `devfs' filesystem. */ -#define DEVFS_SUPER_MAGIC 0x1373 +# define DEVFS_SUPER_MAGIC 0x1373 +#endif /* Path to the master pseudo terminal cloning device. */ #define _PATH_DEVPTMX _PATH_DEV "ptmx" /* Directory containing the UNIX98 pseudo terminals. */ #define _PATH_DEVPTS _PATH_DEV "pts" +#if !defined UNIX98PTY_ONLY /* Prototype for function that opens BSD-style master pseudo-terminals. */ int __bsd_getpt (void); +#endif /* Open a master pseudo terminal and return its file descriptor. */ int getpt (void) { +#if !defined UNIX98PTY_ONLY static int have_no_dev_ptmx; +#endif int fd; +#if !defined UNIX98PTY_ONLY if (!have_no_dev_ptmx) +#endif { fd = open (_PATH_DEVPTMX, O_RDWR); if (fd != -1) { +#if defined ASSUME_DEVPTS + return fd; +#else struct statfs fsbuf; static int devpts_mounted; @@ -69,21 +81,28 @@ getpt (void) are not usable. */ close (fd); have_no_dev_ptmx = 1; +#endif } else { +#if !defined UNIX98PTY_ONLY if (errno == ENOENT || errno == ENODEV) have_no_dev_ptmx = 1; else +#endif return -1; } } +#if !defined UNIX98PTY_ONLY return __bsd_getpt (); +#endif } -#define PTYNAME1 "pqrstuvwxyzabcde"; -#define PTYNAME2 "0123456789abcdef"; +#if !defined UNIX98PTY_ONLY +# define PTYNAME1 "pqrstuvwxyzabcde"; +# define PTYNAME2 "0123456789abcdef"; -#define __getpt __bsd_getpt -#include "bsd_getpt.c" +# define __getpt __bsd_getpt +# include "bsd_getpt.c" +#endif diff --git a/libc/stdlib/grantpt.c b/libc/stdlib/grantpt.c index 7aa49fcd5..d49f0af4f 100644 --- a/libc/stdlib/grantpt.c +++ b/libc/stdlib/grantpt.c @@ -18,6 +18,11 @@ #include #include + +/* If ASSUME_DEVPTS is defined, grantpt() reduces to a stub since we + assume that the devfs/devpts filesystem automatically manages the + permissions. */ +#if !defined ASSUME_DEVPTS #include /* Constant that identifies the `devpts' filesystem. */ @@ -34,18 +39,21 @@ int __unix_grantpt (int fd); pseudo terminal in a safe way. */ static int pts_name (int fd, char **pts, size_t buf_len); +#endif + /* Change the ownership and access permission of the slave pseudo terminal associated with the master pseudo terminal specified by FD. */ int grantpt (int fd) { +#if !defined ASSUME_DEVPTS struct statfs fsbuf; -#ifdef PATH_MAX +# ifdef PATH_MAX char _buf[PATH_MAX]; -#else +# else char _buf[512]; -#endif +# endif char *buf = _buf; if (pts_name (fd, &buf, sizeof (_buf))) @@ -56,11 +64,13 @@ grantpt (int fd) /* If the slave pseudo terminal lives on a `devpts' filesystem, the ownership and access permission are already set. */ - if (fsbuf.f_type == DEVPTS_SUPER_MAGIC || fsbuf.f_type == DEVFS_SUPER_MAGIC) - return 0; - + if (fsbuf.f_type != DEVPTS_SUPER_MAGIC && fsbuf.f_type != DEVFS_SUPER_MAGIC) return __unix_grantpt (fd); +#endif + return 0; } -#define grantpt __unix_grantpt -#include "unix_grantpt.c" +#if !defined ASSUME_DEVPTS +# define grantpt __unix_grantpt +# include "unix_grantpt.c" +#endif diff --git a/libc/stdlib/ptsname.c b/libc/stdlib/ptsname.c index fd50da047..ce4847f35 100644 --- a/libc/stdlib/ptsname.c +++ b/libc/stdlib/ptsname.c @@ -27,6 +27,8 @@ #include #include +#if !defined UNIX98PTY_ONLY + /* Check if DEV corresponds to a master pseudo terminal device. */ #define MASTER_P(Dev) \ (major ((Dev)) == 2 \ @@ -44,22 +46,16 @@ supported. They have been replaced by major numbers 2 (masters) and 3 (slaves). */ -/* Directory where we can find the slave pty nodes. */ -#define _PATH_DEVPTS "/dev/pts/" - /* The are declared in getpt.c. */ extern const char _ptyname1[]; extern const char _ptyname2[]; -/* Static buffer for `ptsname'. */ -static char buffer[sizeof (_PATH_DEVPTS) + 20]; +#endif -/* -extern char * -_itoa_word (unsigned long value, char *buflim, - unsigned int base, int upper_case); -*/ +/* Directory where we can find the slave pty nodes. */ +#define _PATH_DEVPTS "/dev/pts/" +extern char *__ultostr(char *buf, unsigned long uval, int base, int uppercase); /* Store at most BUFLEN characters of the pathname of the slave pseudo terminal associated with the master FD is open on in BUF. @@ -67,7 +63,9 @@ _itoa_word (unsigned long value, char *buflim, int ptsname_r (int fd, char *buf, size_t buflen) { int save_errno = errno; +#if !defined UNIX98PTY_ONLY struct stat st; +#endif int ptyno; if (buf == NULL) @@ -76,26 +74,28 @@ int ptsname_r (int fd, char *buf, size_t buflen) return EINVAL; } +#if !defined UNIX98PTY_ONLY if (!isatty (fd)) { errno = ENOTTY; return ENOTTY; } -#if 0 +#elif !defined TIOCGPTN +# error "UNIX98PTY_ONLY requested but TIOCGPTN is undefined." +#endif #ifdef TIOCGPTN if (ioctl (fd, TIOCGPTN, &ptyno) == 0) { /* Buffer we use to print the number in. For a maximum size for `int' of 8 bytes we never need more than 20 digits. */ char numbuf[21]; - const char *devpts = _PATH_DEVPTS; - const size_t devptslen = strlen (devpts); + static const char devpts[] = _PATH_DEVPTS; char *p; numbuf[20] = '\0'; - p = _itoa_word (ptyno, &numbuf[20], 10, 0); + p = __ultostr (&numbuf[sizeof numbuf - 1], ptyno, 10, 0); - if (buflen < devptslen + strlen (p) + 1) + if (buflen < sizeof devpts + &numbuf[sizeof numbuf - 1] - p) { errno = ERANGE; return ERANGE; @@ -104,9 +104,25 @@ int ptsname_r (int fd, char *buf, size_t buflen) strcpy (buf, devpts); strcat (buf, p); } - else if (errno == EINVAL) -#endif #endif +#if defined UNIX98PTY_ONLY + else + { + /* If the ioctl fails it wasn't a Unix 98 master PTY */ + errno = ENOTTY; + return ENOTTY; + } + /* Note: Don't bother with stat on the slave name and checking the + driver's major device number - the ioctl above succeeded so + we know the fd was a Unix'98 master and the /dev/pts/ prefix + is set by definition. If the name isn't really a slave PTY, + the system is misconfigured anyway - something else will fail + later. + */ +#else +# if !defined TIOCGPTN + else if (errno == EINVAL) +# endif { char *p; @@ -156,6 +172,7 @@ int ptsname_r (int fd, char *buf, size_t buflen) errno = ENOTTY; return ENOTTY; } +#endif errno = save_errno; return 0; @@ -167,5 +184,7 @@ int ptsname_r (int fd, char *buf, size_t buflen) char * ptsname (int fd) { + static char buffer[sizeof (_PATH_DEVPTS) + 20]; + return ptsname_r (fd, buffer, sizeof (buffer)) != 0 ? NULL : buffer; } -- cgit v1.2.3