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:
parent
4d98a72b88
commit
abe0cc7a21
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user