;;;-*-Mode: LISP; Package: CCL -*- ;;; ;;; Copyright (C) 2002-2009 Clozure Associates. ;;; This file is part of Clozure CL. ;;; ;;; Clozure CL is licensed under the terms of the Lisp Lesser GNU Public ;;; License , known as the LLGPL and distributed with Clozure CL as the ;;; file "LICENSE". The LLGPL consists of a preamble and the LGPL, ;;; which is distributed with Clozure CL as the file "LGPL". Where these ;;; conflict, the preamble takes precedence. ;;; ;;; Clozure CL is referenced in the preamble as the "LIBRARY." ;;; ;;; The LLGPL is also available online at ;;; http://opensource.franz.com/preamble.html ;;; (very) preliminary support for dealing with TTYs (and PTYs). (in-package "CCL") ;;; Open a (connected) pair of pty file descriptors, such that anything ;;; written to one can be read from the other. #+linuxppc-target (eval-when (:load-toplevel :execute) (open-shared-library "libutil.so")) (defun open-pty-pair () (rlet ((alphap :unsigned 0) (betap :unsigned 0)) (let* ((status (#_openpty alphap betap (%null-ptr) (%null-ptr) (%null-ptr)))) (if (eql status 0) (values (pref alphap :unsigned) (pref betap :unsigned)) (%errno-disp (%get-errno)))))) (defun %get-tty-attributes (tty-fd &optional control-chars) (if (and control-chars (not (and (typep control-chars 'simple-string) (= (length control-chars) #$NCCS)))) (report-bad-arg control-chars '(or null (simple-string #.#$NCCS)))) (rlet ((attr :termios)) (let* ((result (#_tcgetattr tty-fd attr))) (if (< result 0) (values nil nil nil nil nil nil nil) (progn (if control-chars (%str-from-ptr (pref attr :termios.c_cc) #$NCCS control-chars)) (values (pref attr :termios.c_iflag) (pref attr :termios.c_oflag) (pref attr :termios.c_cflag) (pref attr :termios.c_lflag) #+darwin-target 0 #-darwin-target (pref attr :termios.c_line) control-chars (pref attr :termios.c_ispeed) (pref attr :termios.c_ospeed))))))) (defun %set-tty-attributes (tty &key input-modes output-modes control-modes local-modes control-chars input-speed output-speed) (if (and control-chars (not (and (typep control-chars 'simple-string) (= (length control-chars) #$NCCS)))) (report-bad-arg control-chars '(or null (simple-string #.#$NCCS)))) (rlet ((attr :termios)) (let* ((get-ok (#_tcgetattr tty attr)) (write-back nil)) (when (eql 0 get-ok) (when input-modes (setf (pref attr :termios.c_iflag) input-modes) (setq write-back t)) (when output-modes (setf (pref attr :termios.c_oflag) output-modes) (setq write-back t)) (when control-modes (setf (pref attr :termios.c_cflag) control-modes) (setq write-back t)) (when local-modes (setf (pref attr :termios.c_lflag) local-modes) (setq write-back t)) (when control-chars (%cstr-pointer control-chars (pref attr :termios.c_cc) nil) (setq write-back t)) (when input-speed (setf (pref attr :termios.c_ispeed) input-speed) (setq write-back t)) (when output-speed (setf (pref attr :termios.c_ospeed) output-speed) (setq write-back t)) (and write-back (eql 0 (#_tcsetattr tty #$TCSAFLUSH attr))))))) (defun enable-tty-input-modes (tty mask) (let* ((old (nth-value 0 (%get-tty-attributes tty)))) (when old (%set-tty-attributes tty :input-modes (logior old mask))))) (defun disable-tty-input-modes (tty mask) (let* ((old (nth-value 0 (%get-tty-attributes tty)))) (when old (%set-tty-attributes tty :input-modes (logand old (lognot mask)))))) (defun enable-tty-output-modes (tty mask) (let* ((old (nth-value 1 (%get-tty-attributes tty)))) (when old (%set-tty-attributes tty :output-modes (logior old mask))))) (defun disable-tty-output-modes (tty mask) (let* ((old (nth-value 1 (%get-tty-attributes tty)))) (when old (%set-tty-attributes tty :output-modes (logand old (lognot mask)))))) (defun enable-tty-control-modes (tty mask) (let* ((old (nth-value 2 (%get-tty-attributes tty)))) (when old (%set-tty-attributes tty :control-modes (logior old mask))))) (defun disable-tty-control-modes (tty mask) (let* ((old (nth-value 2 (%get-tty-attributes tty)))) (when old (%set-tty-attributes tty :control-modes (logand old (lognot mask)))))) (defun enable-tty-local-modes (tty mask) (let* ((old (nth-value 3 (%get-tty-attributes tty)))) (when old (%set-tty-attributes tty :local-modes (logior old mask))))) (defun disable-tty-local-modes (tty mask) (let* ((old (nth-value 3 (%get-tty-attributes tty)))) (when old (%set-tty-attributes tty :local-modes (logand old (lognot mask)))))) (defun set-tty-raw (tty) (rlet ((attr :termios)) (#_cfmakeraw attr) (eql 0 (#_tcsetattr tty #$TCSAFLUSH attr))))