syscalls: Add 'openpty' and 'login-tty'.
* guix/build/syscalls.scm (openpty, login-pty): New procedures. * tests/syscalls.scm ("openpty", "openpty + login-tty"): New tests.
This commit is contained in:
parent
b7b0ac8544
commit
f87371bf3e
@ -180,6 +180,8 @@
|
||||
terminal-window-size
|
||||
terminal-columns
|
||||
terminal-rows
|
||||
openpty
|
||||
login-tty
|
||||
|
||||
utmpx?
|
||||
utmpx-login-type
|
||||
@ -2286,6 +2288,43 @@ PORT, trying to guess a reasonable value if all else fails. The result is
|
||||
always a positive integer."
|
||||
(terminal-dimension window-size-rows port (const 25)))
|
||||
|
||||
(define openpty
|
||||
(let* ((ptr (dynamic-func "openpty" (dynamic-link "libutil")))
|
||||
(proc (pointer->procedure int ptr '(* * * * *)
|
||||
#:return-errno? #t)))
|
||||
(lambda ()
|
||||
"Return two file descriptors: one for the pseudo-terminal control side,
|
||||
and one for the controlled side."
|
||||
(let ((head (make-bytevector (sizeof int)))
|
||||
(inferior (make-bytevector (sizeof int))))
|
||||
(let-values (((ret err)
|
||||
(proc (bytevector->pointer head)
|
||||
(bytevector->pointer inferior)
|
||||
%null-pointer %null-pointer %null-pointer)))
|
||||
(unless (zero? ret)
|
||||
(throw 'system-error "openpty" "~A"
|
||||
(list (strerror err))
|
||||
(list err))))
|
||||
|
||||
(let ((* (lambda (bv)
|
||||
(bytevector-sint-ref bv 0 (native-endianness)
|
||||
(sizeof int)))))
|
||||
(values (* head) (* inferior)))))))
|
||||
|
||||
(define login-tty
|
||||
(let* ((ptr (dynamic-func "login_tty" (dynamic-link "libutil")))
|
||||
(proc (pointer->procedure int ptr (list int)
|
||||
#:return-errno? #t)))
|
||||
(lambda (fd)
|
||||
"Make FD the controlling terminal of the current process (with the
|
||||
TIOCSCTTY ioctl), redirect standard input, standard output and standard error
|
||||
output to this terminal, and close FD."
|
||||
(let-values (((ret err) (proc fd)))
|
||||
(unless (zero? ret)
|
||||
(throw 'system-error "login-pty" "~A"
|
||||
(list (strerror err))
|
||||
(list err)))))))
|
||||
|
||||
|
||||
;;;
|
||||
;;; utmpx.
|
||||
|
@ -26,6 +26,7 @@
|
||||
#:use-module (srfi srfi-1)
|
||||
#:use-module (srfi srfi-26)
|
||||
#:use-module (srfi srfi-64)
|
||||
#:use-module (srfi srfi-71)
|
||||
#:use-module (system foreign)
|
||||
#:use-module ((ice-9 ftw) #:select (scandir))
|
||||
#:use-module (ice-9 match))
|
||||
@ -582,6 +583,40 @@
|
||||
(test-assert "terminal-rows"
|
||||
(> (terminal-rows) 0))
|
||||
|
||||
(test-assert "openpty"
|
||||
(let ((head inferior (openpty)))
|
||||
(and (integer? head) (integer? inferior)
|
||||
(let ((port (fdopen inferior "r+0")))
|
||||
(and (isatty? port)
|
||||
(begin
|
||||
(close-port port)
|
||||
(close-fdes head)
|
||||
#t))))))
|
||||
|
||||
(test-equal "openpty + login-tty"
|
||||
'(hello world)
|
||||
(let ((head inferior (openpty)))
|
||||
(match (primitive-fork)
|
||||
(0
|
||||
(dynamic-wind
|
||||
(const #t)
|
||||
(lambda ()
|
||||
(setvbuf (current-input-port) 'none)
|
||||
(close-fdes head)
|
||||
(login-tty inferior)
|
||||
(write (read))
|
||||
(read)) ;this gets EIO when HEAD is closed
|
||||
(lambda ()
|
||||
(primitive-_exit 42))))
|
||||
(pid
|
||||
(close-fdes inferior)
|
||||
(let ((head (fdopen head "r+0")))
|
||||
(write '(hello world) head)
|
||||
(let ((result (read head)))
|
||||
(close-port head)
|
||||
(waitpid pid)
|
||||
result))))))
|
||||
|
||||
(test-assert "utmpx-entries"
|
||||
(match (utmpx-entries)
|
||||
(((? utmpx? entries) ...)
|
||||
|
Loading…
Reference in New Issue
Block a user