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) | |
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 a3b68c45371..2e375c11cae 100644 --- a/guix/build/syscalls.scm +++ b/guix/build/syscalls.scm | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | #:use-module (srfi srfi-1) | 23 | #:use-module (srfi srfi-1) |
| 24 | #:use-module (srfi srfi-9) | 24 | #:use-module (srfi srfi-9) |
| 25 | #:use-module (srfi srfi-9 gnu) | 25 | #:use-module (srfi srfi-9 gnu) |
| 26 | #:use-module (srfi srfi-11) | ||
| 26 | #:use-module (ice-9 rdelim) | 27 | #:use-module (ice-9 rdelim) |
| 27 | #:use-module (ice-9 regex) | 28 | #:use-module (ice-9 regex) |
| 28 | #:use-module (ice-9 match) | 29 | #:use-module (ice-9 match) |
| @@ -82,7 +83,13 @@ | |||
| 82 | interface-address | 83 | interface-address |
| 83 | interface-netmask | 84 | interface-netmask |
| 84 | interface-broadcast-address | 85 | interface-broadcast-address |
| 85 | network-interfaces)) | 86 | network-interfaces |
| 87 | |||
| 88 | openpt | ||
| 89 | grantpt | ||
| 90 | unlockpt | ||
| 91 | ptsname | ||
| 92 | call-with-pty)) | ||
| 86 | 93 | ||
| 87 | ;;; Commentary: | 94 | ;;; Commentary: |
| 88 | ;;; | 95 | ;;; |
| @@ -849,4 +856,105 @@ network interface. This is implemented using the 'getifaddrs' libc function." | |||
| 849 | (let ((ptr (dynamic-func "freeifaddrs" (dynamic-link)))) | 856 | (let ((ptr (dynamic-func "freeifaddrs" (dynamic-link)))) |
| 850 | (pointer->procedure void ptr '(*)))) | 857 | (pointer->procedure void ptr '(*)))) |
| 851 | 858 | ||
| 859 | |||
| 860 | ;;; | ||
| 861 | ;;; Psuedo-Terminals. | ||
| 862 | ;;; | ||
| 863 | |||
| 864 | ;; See misc/sys/select.h in GNU libc. | ||
| 865 | |||
| 866 | (define cc-t uint8) | ||
| 867 | (define speed-t unsigned-int) | ||
| 868 | (define tcflag-t unsigned-int) | ||
| 869 | (define NCCS 32) | ||
| 870 | |||
| 871 | ;; (define-c-struct termios | ||
| 872 | ;; values->termios | ||
| 873 | ;; read-termios | ||
| 874 | ;; write-termios! | ||
| 875 | ;; (c-iflag tcflag-t) | ||
| 876 | ;; (c-oflag tcflag-t) | ||
| 877 | ;; (c-cflag tcflag-t) | ||
| 878 | ;; (c-lflag tcflag-t) | ||
| 879 | ;; (c-line cc-t) | ||
| 880 | ;; (c)) | ||
| 881 | |||
| 882 | (define TIOCSCTTY #x540E) | ||
| 883 | |||
| 884 | (define getpt | ||
| 885 | (let* ((ptr (dynamic-func "getpt" (dynamic-link))) | ||
| 886 | (proc (pointer->procedure int ptr '()))) | ||
| 887 | (lambda () | ||
| 888 | "Open a new master pseudo-terminal and return its file descriptor." | ||
| 889 | (let* ((ret (proc)) | ||
| 890 | (err (errno))) | ||
| 891 | (if (= ret -1) | ||
| 892 | (throw 'system-error "getpt" "~A" | ||
| 893 | (list (strerror err)) | ||
| 894 | (list err)) | ||
| 895 | ret))))) | ||
| 896 | |||
| 897 | (define grantpt | ||
| 898 | (let* ((ptr (dynamic-func "grantpt" (dynamic-link))) | ||
| 899 | (proc (pointer->procedure int ptr (list int)))) | ||
| 900 | (lambda (fdes) | ||
| 901 | "Changes the ownership and access permission of the slave | ||
| 902 | pseudo-terminal device corresponding to the master pseudo-terminal device | ||
| 903 | associated with the file descriptor FDES." | ||
| 904 | (let* ((ret (proc fdes)) | ||
| 905 | (err (errno))) | ||
| 906 | (unless (zero? ret) | ||
| 907 | (throw 'system-error "grantpt" "~d: ~A" | ||
| 908 | (list fdes (strerror err)) | ||
| 909 | (list err))))))) | ||
| 910 | |||
| 911 | (define unlockpt | ||
| 912 | (let* ((ptr (dynamic-func "unlockpt" (dynamic-link))) | ||
| 913 | (proc (pointer->procedure int ptr (list int)))) | ||
| 914 | (lambda (fdes) | ||
| 915 | "Unlocks the slave pseudo-terminal device corresponding to the master | ||
| 916 | pseudo-terminal device associated with the file descriptor FDES." | ||
| 917 | (let* ((ret (proc fdes)) | ||
| 918 | (err (errno))) | ||
| 919 | (unless (zero? ret) | ||
| 920 | (throw 'system-error "unlockpt" "~d: ~A" | ||
| 921 | (list fdes (strerror err)) | ||
| 922 | (list err))))))) | ||
| 923 | |||
| 924 | (define ptsname | ||
| 925 | (let* ((ptr (dynamic-func "ptsname" (dynamic-link))) | ||
| 926 | (proc (pointer->procedure '* ptr (list int)))) | ||
| 927 | (lambda (fdes) | ||
| 928 | "If the file descriptor FDES is associated with a master pseudo-terminal | ||
| 929 | device, return the file name of the associated slave pseudo-terminal file. | ||
| 930 | Otherwise, return #f." | ||
| 931 | (let ((ret (proc fdes))) | ||
| 932 | (and (not (null-pointer? ret)) | ||
| 933 | (pointer->string ret)))))) | ||
| 934 | |||
| 935 | (define (open-pty-pair) | ||
| 936 | "Open a new pseudo-terminal pair and return the corresponding ports." | ||
| 937 | (let ((master (getpt))) | ||
| 938 | (catch #t | ||
| 939 | (lambda () | ||
| 940 | (grantpt master) | ||
| 941 | (unlockpt master) | ||
| 942 | (let ((name (ptsname master))) | ||
| 943 | (values (fdopen master "r+") | ||
| 944 | (open-file name "r+")))) | ||
| 945 | (lambda args | ||
| 946 | (close master) | ||
| 947 | (apply throw args))))) | ||
| 948 | |||
| 949 | (define (call-with-pty proc) | ||
| 950 | "Apply PROC with the master and slave side of a new pseudo-terminal pair." | ||
| 951 | (let-values (((master slave) (open-pty-pair))) | ||
| 952 | (dynamic-wind | ||
| 953 | (const #t) | ||
| 954 | (lambda () | ||
| 955 | (proc master slave)) | ||
| 956 | (lambda () | ||
| 957 | (close slave) | ||
| 958 | (close master))))) | ||
| 959 | |||
| 852 | ;;; syscalls.scm ends here | 960 | ;;; syscalls.scm ends here |
