Last night I upgraded my system to the then-current -CURRENT (upgrading from -CURRENT as of a couple weeks ago), installing new kernel and world. Soon after, I discovered that a Perl script of mine I use to pry statistics out of my Netgear router (telneting to the router under a pseudo-tty with p5-Expect and p5-IO-Tty) was giving me the following error messages: IO::Tty::pty_allocate(nonfatal): grantpt(): Invalid argument at /usr/local/lib/perl5/site_perl/5.8.6/mach/IO/Pty.pm line 24, <STDIN> line 1. IO::Tty::pty_allocate(nonfatal): unlockpt(): Invalid argument at /usr/local/lib/perl5/site_perl/5.8.6/mach/IO/Pty.pm line 24, <STDIN> line 1. IO::Tty::open_slave(nonfatal): ptsname(): Invalid argument at /usr/local/lib/perl5/site_perl/5.8.6/mach/IO/Pty.pm line 24, <STDIN> line 1. pty_allocate(nonfatal): openpty(): Invalid argument at /usr/local/lib/perl5/site_perl/5.8.6/mach/IO/Pty.pm line 24, <STDIN> line 1. IO::Tty::pty_allocate(nonfatal): grantpt(): Invalid argument at /usr/local/lib/perl5/site_perl/5.8.6/mach/IO/Pty.pm line 24, <STDIN> line 1. IO::Tty::pty_allocate(nonfatal): unlockpt(): Invalid argument at /usr/local/lib/perl5/site_perl/5.8.6/mach/IO/Pty.pm line 24, <STDIN> line 1. Further investigation with simplifed test cases revealed that yes indeed, calls by the p5-IO-Tty module to the grantpt()/unlockpt()/ptsname() were failing. Looking at the code for these functions, it's easy to see why. These functions all check to see if the fd they're passed is a valid pty by fstat()ing the fd, looking at the device number, and checking it is a pseudoterminal device node with the ISPTM macro as follows: #define PTM_MAJOR 6 /* pseudo tty master major */ #define PTS_MAJOR 5 /* pseudo tty slave major */ #define PTM_PREFIX "pty" /* pseudo tty master naming convention */ #define PTS_PREFIX "tty" /* pseudo tty slave naming convention */ /* * The following are range values for pseudo TTY devices. Pseudo TTYs have a * name of /dev/[pt]ty[p-sP-S][0-9a-v], yielding 256 combinations per major. */ #define PT_MAX 256 #define PT_DEV1 "pqrsPQRS" #define PT_DEV2 "0123456789abcdefghijklmnopqrstuv" /* * grantpt(3) support utility. */ #define _PATH_PTCHOWN "/usr/libexec/pt_chown" /* * ISPTM(x) returns 0 for struct stat x if x is not a pty master. * The bounds checking may be unnecessary but it does eliminate doubt. */ #define ISPTM(x) (S_ISCHR((x).st_mode) && \ major((x).st_rdev) == PTM_MAJOR && \ minor((x).st_rdev) >= 0 && \ minor((x).st_rdev) < PT_MAX) Yep. The pty master/slave major numbers are hardwired into grantpt.c, and now that pty major device numbers are dynamically allocated, the actual device numbers on a running system don't match what's in the above #define: crw-rw-rw- 1 root wheel 216, 0 Mar 2 01:50 /dev/ptyp0 crw--w---- 1 rmtodd tty 215, 0 Mar 2 01:51 /dev/ttyp0 I managed to work around the immediate problem and stop my script from complaining by bludgeoning the p5-IO-Tty Makefile.PL with a blunt instrument to make it think this system didn't support grantpt() etc. (causing the module to fall back to other methods of dealing with ptys). The proper fix for grantpt.c is less clear, though. Changing it to figure the proper pty major number by stating a known pty node (say, /dev/ptyp0) would work, but from what I understand that's going to break when phk commits his forthcoming patch which will make the whole concept of major numbers go away. Any ideas?Received on Thu Mar 03 2005 - 01:16:10 UTC
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:38:29 UTC