diff options
| author | Ludovic Courtès <ludo@gnu.org> | 2014-03-24 21:09:15 +0100 |
|---|---|---|
| committer | Ludovic Courtès <ludo@gnu.org> | 2014-03-24 21:09:15 +0100 |
| commit | 80dea563a3dad98bda60385188509ca79a3651f8 (patch) | |
| tree | 5b42a15306a812ed3a53e495a6f41840c8195b36 | |
| parent | 6ef91c8fc0798de87bc2fe3852f6dad5e6429cd4 (diff) | |
utils: Add 'filtered-output-port' and 'compressed-output-port'.
* guix/utils.scm (filtered-output-port, compressed-output-port): New
procedures.
* tests/utils.scm ("compressed-output-port + decompressed-port"): New
test.
| -rw-r--r-- | guix/utils.scm | 44 | ||||
| -rw-r--r-- | tests/utils.scm | 19 |
2 files changed, 62 insertions, 1 deletions
diff --git a/guix/utils.scm b/guix/utils.scm index f786c83f471..44060c46b59 100644 --- a/guix/utils.scm +++ b/guix/utils.scm | |||
| @@ -73,7 +73,8 @@ | |||
| 73 | 73 | ||
| 74 | filtered-port | 74 | filtered-port |
| 75 | compressed-port | 75 | compressed-port |
| 76 | decompressed-port)) | 76 | decompressed-port |
| 77 | compressed-output-port)) | ||
| 77 | 78 | ||
| 78 | 79 | ||
| 79 | ;;; | 80 | ;;; |
| @@ -223,6 +224,47 @@ a symbol such as 'xz." | |||
| 223 | ('gzip (filtered-port `(,%gzip "-c") input)) | 224 | ('gzip (filtered-port `(,%gzip "-c") input)) |
| 224 | (else (error "unsupported compression scheme" compression)))) | 225 | (else (error "unsupported compression scheme" compression)))) |
| 225 | 226 | ||
| 227 | (define (filtered-output-port command output) | ||
| 228 | "Return an output port. Data written to that port is filtered through | ||
| 229 | COMMAND and written to OUTPUT, an output file port. In addition, return a | ||
| 230 | list of PIDs to wait for. OUTPUT must be unbuffered; otherwise, any buffered | ||
| 231 | data is lost." | ||
| 232 | (match (pipe) | ||
| 233 | ((in . out) | ||
| 234 | (match (primitive-fork) | ||
| 235 | (0 | ||
| 236 | (dynamic-wind | ||
| 237 | (const #f) | ||
| 238 | (lambda () | ||
| 239 | (close-port out) | ||
| 240 | (close-port (current-input-port)) | ||
| 241 | (dup2 (fileno in) 0) | ||
| 242 | (close-port (current-output-port)) | ||
| 243 | (dup2 (fileno output) 1) | ||
| 244 | (catch 'system-error | ||
| 245 | (lambda () | ||
| 246 | (apply execl (car command) command)) | ||
| 247 | (lambda args | ||
| 248 | (format (current-error-port) | ||
| 249 | "filtered-output-port: failed to execute '~{~a ~}': ~a~%" | ||
| 250 | command (strerror (system-error-errno args)))))) | ||
| 251 | (lambda () | ||
| 252 | (primitive-_exit 1)))) | ||
| 253 | (child | ||
| 254 | (close-port in) | ||
| 255 | (values out (list child))))))) | ||
| 256 | |||
| 257 | (define (compressed-output-port compression output) | ||
| 258 | "Return an output port whose input is compressed according to COMPRESSION, | ||
| 259 | a symbol such as 'xz, and then written to OUTPUT. In addition return a list | ||
| 260 | of PIDs to wait for." | ||
| 261 | (match compression | ||
| 262 | ((or #f 'none) (values output '())) | ||
| 263 | ('bzip2 (filtered-output-port `(,%bzip2 "-c") output)) | ||
| 264 | ('xz (filtered-output-port `(,%xz "-c") output)) | ||
| 265 | ('gzip (filtered-output-port `(,%gzip "-c") output)) | ||
| 266 | (else (error "unsupported compression scheme" compression)))) | ||
| 267 | |||
| 226 | 268 | ||
| 227 | ;;; | 269 | ;;; |
| 228 | ;;; Nixpkgs. | 270 | ;;; Nixpkgs. |
diff --git a/tests/utils.scm b/tests/utils.scm index 39cad701b89..adbfdf55baa 100644 --- a/tests/utils.scm +++ b/tests/utils.scm | |||
| @@ -162,6 +162,25 @@ | |||
| 162 | (equal? (get-bytevector-all decompressed) data))))) | 162 | (equal? (get-bytevector-all decompressed) data))))) |
| 163 | 163 | ||
| 164 | (false-if-exception (delete-file temp-file)) | 164 | (false-if-exception (delete-file temp-file)) |
| 165 | (test-equal "compressed-output-port + decompressed-port" | ||
| 166 | '((0) "Hello, compressed port!") | ||
| 167 | (let ((text "Hello, compressed port!") | ||
| 168 | (output (open-file temp-file "w0b"))) | ||
| 169 | (let-values (((compressed pids) | ||
| 170 | (compressed-output-port 'xz output))) | ||
| 171 | (display text compressed) | ||
| 172 | (close-port compressed) | ||
| 173 | (close-port output) | ||
| 174 | (and (every (compose zero? cdr waitpid) pids) | ||
| 175 | (let*-values (((input) | ||
| 176 | (open-file temp-file "r0b")) | ||
| 177 | ((decompressed pids) | ||
| 178 | (decompressed-port 'xz input))) | ||
| 179 | (let ((str (get-string-all decompressed))) | ||
| 180 | (list (map (compose cdr waitpid) pids) | ||
| 181 | str))))))) | ||
| 182 | |||
| 183 | (false-if-exception (delete-file temp-file)) | ||
| 165 | (test-equal "fcntl-flock wait" | 184 | (test-equal "fcntl-flock wait" |
| 166 | 42 ; the child's exit status | 185 | 42 ; the child's exit status |
| 167 | (let ((file (open-file temp-file "w0"))) | 186 | (let ((file (open-file temp-file "w0"))) |
