[Brian May]
See bug #87371. The title is wrong. devfs is not the issue,
/dev/pts is (I think). I don't think there is any intention to fix
the bug. Over 4 years old. Perhaps this is grounds to drop the
package from Debian.
[Miles Bader]
I'd say so. Or fix the bug.
Kind of quick and dirty, and not particularly tested, since I don't
actually know how to use ttysnoop.
But it's a proof of concept of how easy it is to add unix98 pty support
to an app
--- ttysnoops.c~2005-11-10 00:35:18.0 -0600
+++ ttysnoops.c 2005-11-10 01:42:48.0 -0600
@@ -18,6 +18,7 @@
v0.12d 8-4-98 Carl Declerck- updated #includes a bit
*/
+#define _XOPEN_SOURCE /* ptsname() */
#include sys/types.h
#include sys/stat.h
#include sys/ioctl.h
@@ -54,6 +55,7 @@
int pgmpid = -1, authpid = -1, servpid = -1;
int use_socket = 0, fdmax = 0, proctype = DEAD_PROCESS;
char snoopdev[32], ptynam[32], childproc[128], sockname[128];
+char *short_ptynam, *shorter_ptynam;
/* read a single line from a stream, ignoring all irrelevant stuff */
@@ -148,7 +150,17 @@
}
/* find open a pty to be used by the pty-master */
+int open_unix98_master (char *ptyname)
+{
+ int fd = open(/dev/ptmx, O_RDWR);
+ char *name = unknown;
+ if (fd = 0)
+ name = ptsname(fd);
+ if (name)
+ strcpy(ptyname, name);
+ return fd;
+}
int find_ptyxx (char *ptyname)
{
int fd, i, j;
@@ -180,6 +192,20 @@
/* find open a pty (tty) to be used by pty-client */
+int open_unix98_slave (int ptyfd)
+{
+ int fd;
+ char *name = ptsname(ptyfd);
+
+ grantpt(ptyfd);
+ unlockpt(ptyfd);
+
+ if ((fd = open(name, O_RDWR)) = 0)
+ return fd;
+
+ close(ptyfd);
+ return -1;
+}
int find_ttyxx (char *ttyname, int ptyfd)
{
struct group *grp;
@@ -200,23 +226,36 @@
return (-1);
}
+void abbreviate_ptyname (char *name, char **shortname, char **shortername)
+{
+ *shortname = *shortername = name;
+ if (!name)
+ return;
+ if (strncmp(name, /dev/, 5))
+ return;
+ *shortname = *shortername = name + 5;
+ if (!strncmp(name, /dev/tty, 8))
+ *shortername = name + 8;
+ else if (!strncmp(name, /dev/pts/, 9))
+ *shortername = name + 9;
+}
+
/* fork off the pty-client and redirect its stdin/out/err to the pty */
int fork_pty (int *ptyfd, char *ttynam)
{
struct termios term;
struct winsize twin;
- int ttyfd, pid;
- char name[32];
+ int ttyfd, pid, is_unix98 = 0;
tcgetattr (STDIN_FILENO, term);
ioctl (STDIN_FILENO, TIOCGWINSZ, (char *) twin);
- if ((*ptyfd = find_ptyxx(name)) 0)
+ if ((*ptyfd = open_unix98_master(ttynam)) = 0)
+ is_unix98 = 1;
+ else if ((*ptyfd = find_ptyxx(ttynam)) 0)
errorf (can't open pty\n);
- strcpy (ttynam, leafname(name));
-
if ((pid = fork()) 0)
errorf (can't fork\n);
@@ -224,8 +263,12 @@
{
if (setsid() 0)
errorf (setsid failed\n);
-
- if ((ttyfd = find_ttyxx(name, *ptyfd)) 0)
+
+ if (is_unix98)
+ ttyfd = open_unix98_slave(*ptyfd);
+ else
+ ttyfd = find_ttyxx(ttynam, *ptyfd);
+ if (ttyfd 0)
errorf (can't open tty\n);
close (*ptyfd);
@@ -384,7 +427,7 @@
void closedown (void)
{
if (servpid == getpid())/* only server must clear utmp entry */
- cleanup_utmp (ptynam);
+ cleanup_utmp (short_ptynam);
stty_orig ();
}
@@ -455,14 +498,17 @@
/* fork off the client and load the new image */
- if ((pgmpid = fork_pty(ptyfd, ptynam)) == 0)/* child */
+ if ((pgmpid = fork_pty(ptyfd, ptynam)) 0)
+ errorf (cannot fork\n);
+ abbreviate_ptyname(ptynam, short_ptynam, shorter_ptynam);
+ if (pgmpid == 0)/* child */
{
/* should we update utmp to reflect the change to ttypX ? */
if (proctype == LOGIN_PROCESS)
{
- strncopy (utmp.ut_line, ptynam);
- strncopy (utmp.ut_id, ptynam + 3);
+ strncopy (utmp.ut_line, short_ptynam);
+ strncopy (utmp.ut_id, shorter_ptynam);
*utmp.ut_host = 0;
utmp.ut_addr = 0;
strncopy (utmp.ut_user, LOGIN);
@@ -497,7 +543,7 @@
if ((servfd = socket(AF_UNIX, SOCK_STREAM, 0)) 0)
errorf (can't create server socket\n);
- sprintf (sockname, %s/%s, SPOOLDIR, ptynam);
+ sprintf