diff options
author | David Thompson <dthompson2@worcester.edu> | 2015-07-30 15:46:48 -0400 |
---|---|---|
committer | David Thompson <dthompson2@worcester.edu> | 2015-10-25 20:27:19 -0400 |
commit | 2c2631658c5572a28cdf3ad8e62f589546bb11e3 (patch) | |
tree | ee9eae8ab2e402649a82eab7487c0e39566ba5e0 | |
parent | 054ee2038e942de75f71c1c8d6a4767a1b0dbf1d (diff) | |
download | guix-2c2631658c5572a28cdf3ad8e62f589546bb11e3.tar.gz |
build: syscalls: Add pseudo-terminal bindings. wip-container
* guix/build/syscalls.scm (openpt, grantpt, unlockpt, ptsname, open-pty-pair, call-with-pty): New procedures.
-rw-r--r-- | guix/build/syscalls.scm | 110 |
1 files changed, 109 insertions, 1 deletions
diff --git a/guix/build/syscalls.scm b/guix/build/syscalls.scm index a3b68c4537..2e375c11ca 100644 --- a/guix/build/syscalls.scm +++ b/guix/build/syscalls.scm @@ -23,6 +23,7 @@ #:use-module (srfi srfi-1) #:use-module (srfi srfi-9) #:use-module (srfi srfi-9 gnu) + #:use-module (srfi srfi-11) #:use-module (ice-9 rdelim) #:use-module (ice-9 regex) #:use-module (ice-9 match) @@ -82,7 +83,13 @@ interface-address interface-netmask interface-broadcast-address - network-interfaces)) + network-interfaces + + openpt + grantpt + unlockpt + ptsname + call-with-pty)) ;;; Commentary: ;;; @@ -849,4 +856,105 @@ network interface. This is implemented using the 'getifaddrs' libc function." (let ((ptr (dynamic-func "freeifaddrs" (dynamic-link)))) (pointer->procedure void ptr '(*)))) + +;;; +;;; Psuedo-Terminals. +;;; + +;; See misc/sys/select.h in GNU libc. + +(define cc-t uint8) +(define speed-t unsigned-int) +(define tcflag-t unsigned-int) +(define NCCS 32) + +;; (define-c-struct termios +;; values->termios +;; read-termios +;; write-termios! +;; (c-iflag tcflag-t) +;; (c-oflag tcflag-t) +;; (c-cflag tcflag-t) +;; (c-lflag tcflag-t) +;; (c-line cc-t) +;; (c)) + +(define TIOCSCTTY #x540E) + +(define getpt + (let* ((ptr (dynamic-func "getpt" (dynamic-link))) + (proc (pointer->procedure int ptr '()))) + (lambda () + "Open a new master pseudo-terminal and return its file descriptor." + (let* ((ret (proc)) + (err (errno))) + (if (= ret -1) + (throw 'system-error "getpt" "~A" + (list (strerror err)) + (list err)) + ret))))) + +(define grantpt + (let* ((ptr (dynamic-func "grantpt" (dynamic-link))) + (proc (pointer->procedure int ptr (list int)))) + (lambda (fdes) + "Changes the ownership and access permission of the slave +pseudo-terminal device corresponding to the master pseudo-terminal device +associated with the file descriptor FDES." + (let* ((ret (proc fdes)) + (err (errno))) + (unless (zero? ret) + (throw 'system-error "grantpt" "~d: ~A" + (list fdes (strerror err)) + (list err))))))) + +(define unlockpt + (let* ((ptr (dynamic-func "unlockpt" (dynamic-link))) + (proc (pointer->procedure int ptr (list int)))) + (lambda (fdes) + "Unlocks the slave pseudo-terminal device corresponding to the master +pseudo-terminal device associated with the file descriptor FDES." + (let* ((ret (proc fdes)) + (err (errno))) + (unless (zero? ret) + (throw 'system-error "unlockpt" "~d: ~A" + (list fdes (strerror err)) + (list err))))))) + +(define ptsname + (let* ((ptr (dynamic-func "ptsname" (dynamic-link))) + (proc (pointer->procedure '* ptr (list int)))) + (lambda (fdes) + "If the file descriptor FDES is associated with a master pseudo-terminal +device, return the file name of the associated slave pseudo-terminal file. +Otherwise, return #f." + (let ((ret (proc fdes))) + (and (not (null-pointer? ret)) + (pointer->string ret)))))) + +(define (open-pty-pair) + "Open a new pseudo-terminal pair and return the corresponding ports." + (let ((master (getpt))) + (catch #t + (lambda () + (grantpt master) + (unlockpt master) + (let ((name (ptsname master))) + (values (fdopen master "r+") + (open-file name "r+")))) + (lambda args + (close master) + (apply throw args))))) + +(define (call-with-pty proc) + "Apply PROC with the master and slave side of a new pseudo-terminal pair." + (let-values (((master slave) (open-pty-pair))) + (dynamic-wind + (const #t) + (lambda () + (proc master slave)) + (lambda () + (close slave) + (close master))))) + ;;; syscalls.scm ends here |