Hi,
I, for some reason, wanted to start a shell in Hemlock, and noticed
that it didn't work, since it couldn't find a pty. Some further search
of source showed me that RUN-PROGRAM with output to a pty didn't work
either; it seems that the approach that CMUCL takes in EXT::FIND-A-PTY
doesn't work on my system. (Neither does SBCL, which uses the same.)
I'm running Debian/unstable, currently on a 2.6.8.1 kernel; I do have
compatibility with "old" pty:s compiled in. I know precious little about
unix programming on this level, but looking in the info file for glibc
and run-program.lisp I came up with the following, which enables me to
run a shell in Hemlock (although there's an extra #\Return on the end
of each line, but I think that used to be there earlier as well), and
RUN-PROGRAM other stuff with :PTY T.
I'm not at all certain whether this is a correct approach, though; it
seems to be something that changed in (my installation of) Linux, not
in CMUCL.
---
(in-package :unix)
#+glibc2
(without-package-locks
(def-alien-type nil
(struct sgttyb
#+linux (sg-flags #+mach short #-mach int) ; mode flags
(sg-ispeed char) ; input speed.
(sg-ospeed char) ; output speed
(sg-erase char) ; erase character
#-linux (sg-kill char) ; kill character
#-linux (sg-flags #+mach short #-mach int) ; mode flags
#+linux (sg-kill char)
#+linux (t (struct termios))
#+linux (check int)))
)
(in-package :ext)
(without-package-locks
(alien:def-alien-routine ("getpt" c-getpt) c-call:int
(fildes c-call:int :out))
(alien:def-alien-routine ("ptsname" c-ptsname) c-call:c-string
(fildes c-call:int))
(alien:def-alien-routine ("unlockpt" c-unlockpt) c-call:int
(fildes c-call:int))
(alien:def-alien-routine ("grantpt" c-grantpt) c-call:int
(fildes c-call:int))
(defun find-a-pty ()
"Returns the master fd, the slave fd, and the name of the tty"
(multiple-value-bind
(master-fd errno)
(c-getpt)
(when (and (<= 0 (c-grantpt master-fd)) (<= 0 (c-unlockpt master-fd)))
(let* ((slave-name (c-ptsname master-fd))
(slave-fd (unix:unix-open slave-name
unix:o_rdwr
#o666)))
(when (and slave-name (<= 0 slave-fd))
(return-from find-a-pty
(values master-fd
slave-fd
slave-name)))))
(unix:unix-close master-fd))
(error "Could not find a pty."))
)
---
The versions of my packages are:
cmucl: 19a-release-20040728-7
sbcl: 1:0.8.14.24-1
Regards,
'mr
--
[Emacs] is written in Lisp, which is the only computer language that is
beautiful. -- Neal Stephenson, _In the Beginning was the Command Line_