summaryrefslogtreecommitdiff
path: root/libc/stdlib
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2002-01-14 09:10:50 +0000
committerEric Andersen <andersen@codepoet.org>2002-01-14 09:10:50 +0000
commitad3d96f8b792149d4a623584f8b403d40bd60331 (patch)
treea642f520af5de3923c499f886e068e0b9bbdcef3 /libc/stdlib
parent50b14f6bf77048f65377f26fe8737b9bfb8512a1 (diff)
Patch from Brian Stafford <brian@stafford.uklinux.net> to fixup
support for Unix98 PTYs, and optionally exclude the older junk.
Diffstat (limited to 'libc/stdlib')
-rw-r--r--libc/stdlib/getpt.c33
-rw-r--r--libc/stdlib/grantpt.c26
-rw-r--r--libc/stdlib/ptsname.c53
3 files changed, 80 insertions, 32 deletions
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 <stdlib.h>
#include <unistd.h>
#include <paths.h>
-#include <sys/statfs.h>
+
+#if !defined ASSUME_DEVPTS
+# include <sys/statfs.h>
/* 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 <limits.h>
#include <stdlib.h>
+
+/* 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 <sys/statfs.h>
/* 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 <termios.h>
#include <unistd.h>
+#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;
}