[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