[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.000000000 -0600
+++ ttysnoops.c 2005-11-10 01:42:48.000000000 -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 (sockname, "%s/%s", SPOOLDIR, shorter_ptynam);
                unlink (sockname);
                serv_addr.sun_family = AF_UNIX;
                strncopy (serv_addr.sun_path, sockname);

Attachment: signature.asc
Description: Digital signature

Reply via email to