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 <justus@g10code.com>
This commit is contained in:
Justus Winter 2016-11-07 17:40:43 +01:00
parent 4d98a72b88
commit abe0cc7a21
2 changed files with 42 additions and 7 deletions

View File

@ -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);
}

View File

@ -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.