diff options
author | Justus Winter <[email protected]> | 2016-11-07 16:40:43 +0000 |
---|---|---|
committer | Justus Winter <[email protected]> | 2016-11-07 16:40:43 +0000 |
commit | abe0cc7a21d2b0b5c77cc525b999d1ede2d29185 (patch) | |
tree | 10a41e272a22868f49565d71e899d06d4d04d86c | |
parent | gpgscm: Drop 'len' argument from splice. (diff) | |
download | gnupg-abe0cc7a21d2b0b5c77cc525b999d1ede2d29185.tar.gz gnupg-abe0cc7a21d2b0b5c77cc525b999d1ede2d29185.zip |
gpgscm: Generalize splice to write to multiple sinks.
* tests/gpgscm/ffi.c (ordinal_suffix): New function.
(do_splice): Generalize splice to write to multiple sinks.
* tests/gpgscm/lib.scm (splice): Document this fact.
Signed-off-by: Justus Winter <[email protected]>
Diffstat (limited to '')
-rw-r--r-- | tests/gpgscm/ffi.c | 44 | ||||
-rw-r--r-- | tests/gpgscm/lib.scm | 5 |
2 files changed, 42 insertions, 7 deletions
diff --git a/tests/gpgscm/ffi.c b/tests/gpgscm/ffi.c index 18aff9824..d4bf3ef07 100644 --- a/tests/gpgscm/ffi.c +++ b/tests/gpgscm/ffi.c @@ -995,17 +995,36 @@ do_file_equal (scheme *sc, pointer args) goto out; } +static const char * +ordinal_suffix (int n) +{ + switch (n) + { + case 1: return "st"; + case 2: return "nd"; + case 3: return "rd"; + default: return "th"; + } + assert (! "reached"); +} + static pointer do_splice (scheme *sc, pointer args) { FFI_PROLOG (); int source; - int sink; char buffer[1024]; ssize_t bytes_read; + pointer sinks, sink; FFI_ARG_OR_RETURN (sc, int, source, number, args); - FFI_ARG_OR_RETURN (sc, int, sink, number, args); - FFI_ARGS_DONE_OR_RETURN (sc, args); + sinks = args; + if (sinks == sc->NIL) + return ffi_sprintf (sc, "need at least one sink"); + for (sink = sinks; sink != sc->NIL; sink = pair_cdr (sink), ffi_arg_index++) + if (! sc->vptr->is_number (pair_car (sink))) + return ffi_sprintf (sc, "%d%s argument is not a number", + ffi_arg_index, ordinal_suffix (ffi_arg_index)); + while (1) { bytes_read = read (source, buffer, sizeof buffer); @@ -1013,8 +1032,23 @@ do_splice (scheme *sc, pointer args) break; if (bytes_read < 0) FFI_RETURN_ERR (sc, gpg_error_from_syserror ()); - if (write (sink, buffer, bytes_read) != bytes_read) - FFI_RETURN_ERR (sc, gpg_error_from_syserror ()); + + for (sink = sinks; sink != sc->NIL; sink = pair_cdr (sink)) + { + int fd = sc->vptr->ivalue (pair_car (sink)); + char *p = buffer; + ssize_t left = bytes_read; + + while (left) + { + ssize_t written = write (fd, p, left); + if (written < 0) + FFI_RETURN_ERR (sc, gpg_error_from_syserror ()); + assert (written <= left); + left -= written; + p += written; + } + } } FFI_RETURN (sc); } diff --git a/tests/gpgscm/lib.scm b/tests/gpgscm/lib.scm index 7d2d1ebac..27779e24a 100644 --- a/tests/gpgscm/lib.scm +++ b/tests/gpgscm/lib.scm @@ -207,8 +207,9 @@ ;; Get our process id. (ffi-define (getpid)) -;; Copy data from file descriptor SOURCE to SINK. -(ffi-define (splice source sink)) +;; Copy data from file descriptor SOURCE to every file descriptor in +;; SINKS. +(ffi-define (splice source . sinks)) ;; ;; Random numbers. |