1
0
mirror of git://git.gnupg.org/gnupg.git synced 2025-01-30 16:17:02 +01:00

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; 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 static pointer
do_splice (scheme *sc, pointer args) do_splice (scheme *sc, pointer args)
{ {
FFI_PROLOG (); FFI_PROLOG ();
int source; int source;
int sink;
char buffer[1024]; char buffer[1024];
ssize_t bytes_read; ssize_t bytes_read;
pointer sinks, sink;
FFI_ARG_OR_RETURN (sc, int, source, number, args); FFI_ARG_OR_RETURN (sc, int, source, number, args);
FFI_ARG_OR_RETURN (sc, int, sink, number, args); sinks = args;
FFI_ARGS_DONE_OR_RETURN (sc, 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) while (1)
{ {
bytes_read = read (source, buffer, sizeof buffer); bytes_read = read (source, buffer, sizeof buffer);
@ -1013,8 +1032,23 @@ do_splice (scheme *sc, pointer args)
break; break;
if (bytes_read < 0) if (bytes_read < 0)
FFI_RETURN_ERR (sc, gpg_error_from_syserror ()); 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); FFI_RETURN (sc);
} }

View File

@ -207,8 +207,9 @@
;; Get our process id. ;; Get our process id.
(ffi-define (getpid)) (ffi-define (getpid))
;; Copy data from file descriptor SOURCE to SINK. ;; Copy data from file descriptor SOURCE to every file descriptor in
(ffi-define (splice source sink)) ;; SINKS.
(ffi-define (splice source . sinks))
;; ;;
;; Random numbers. ;; Random numbers.