aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustus Winter <[email protected]>2016-11-07 16:40:43 +0000
committerJustus Winter <[email protected]>2016-11-07 16:40:43 +0000
commitabe0cc7a21d2b0b5c77cc525b999d1ede2d29185 (patch)
tree10a41e272a22868f49565d71e899d06d4d04d86c
parentgpgscm: Drop 'len' argument from splice. (diff)
downloadgnupg-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.c44
-rw-r--r--tests/gpgscm/lib.scm5
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.