diff options
| author | Evan Haas <evan@lagerdata.com> | 2020-04-11 20:46:14 -0700 |
|---|---|---|
| committer | Garrett D'Amore <garrett@damore.org> | 2020-05-25 22:36:08 -0700 |
| commit | bdbddbc805d1d0450476707f20ccbbde2ede8cf7 (patch) | |
| tree | 9bf0528035840912a84b1b44d6838f8ba9505cd4 /tools/nngcat | |
| parent | 88c8eb81b3a1e4e5dfb0a7ead1d4a62467d07063 (diff) | |
| download | nng-bdbddbc805d1d0450476707f20ccbbde2ede8cf7.tar.gz nng-bdbddbc805d1d0450476707f20ccbbde2ede8cf7.tar.bz2 nng-bdbddbc805d1d0450476707f20ccbbde2ede8cf7.zip | |
fixes #1007 nngcat should accept data from stdin
Allows passing a filename of `-` to the `--file` option in order to read from
stdin. Also removes the requirement for the file to be seekable - this allows
nngcat to be used as part of a shell pipeline, or with other non-seekable files
Diffstat (limited to 'tools/nngcat')
| -rw-r--r-- | tools/nngcat/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | tools/nngcat/nngcat.c | 56 | ||||
| -rwxr-xr-x | tools/nngcat/nngcat_stdin_pipe_test.sh | 44 |
3 files changed, 86 insertions, 15 deletions
diff --git a/tools/nngcat/CMakeLists.txt b/tools/nngcat/CMakeLists.txt index 6edf3bda..bcfc575b 100644 --- a/tools/nngcat/CMakeLists.txt +++ b/tools/nngcat/CMakeLists.txt @@ -29,5 +29,6 @@ if (NNG_ENABLE_NNGCAT) add_nngcat_test (nngcat_pubsub 20) add_nngcat_test (nngcat_recvmaxsz 20) add_nngcat_test (nngcat_unlimited 20) + add_nngcat_test (nngcat_stdin_pipe 20) endif() endif() diff --git a/tools/nngcat/nngcat.c b/tools/nngcat/nngcat.c index ab891830..7b5146c0 100644 --- a/tools/nngcat/nngcat.c +++ b/tools/nngcat/nngcat.c @@ -1,6 +1,7 @@ // // Copyright 2019 Staysail Systems, Inc. <info@staysail.tech> // Copyright 2018 Capitar IT Group BV <info@capitar.com> +// Copyright 2020 Lager Data, Inc. <support@lagerdata.com> // // This software is supplied under the terms of the MIT License, a // copy of which should be located in the distribution where this @@ -272,7 +273,8 @@ help(void) printf(" --key <file>\n"); printf(" --zt-home <path>\n"); printf("\n<src> may be one of:\n"); - printf(" --file <file> (or alias -F <file>)\n"); + printf(" --file <file> (or alias -F <file>). " + "Use - for standard input.\n"); printf(" --data <data> (or alias -D <data>)\n"); exit(1); } @@ -309,28 +311,52 @@ static void loadfile(const char *path, void **datap, size_t *lenp) { FILE * f; + size_t total_read = 0; + size_t allocation_size = BUFSIZ; char * fdata; - size_t len; + char * realloc_result; - if ((f = fopen(path, "r")) == NULL) { - fatal("Cannot open file %s: %s", path, strerror(errno)); - } - if (fseek(f, 0, SEEK_END) != 0) { - fatal("Cannot seek to end of file: %s", strerror(errno)); + if (strcmp(path, "-") == 0) { + f = stdin; + } else { + if ((f = fopen(path, "rb")) == NULL) { + fatal("Cannot open file %s: %s", path, strerror(errno)); + } } - len = ftell(f); - (void) fseek(f, 0, SEEK_SET); - if ((fdata = malloc(len + 1)) == NULL) { + + if ((fdata = malloc(allocation_size + 1)) == NULL) { fatal("Out of memory."); } - fdata[len] = '\0'; - if (fread(fdata, 1, len, f) != len) { - fatal("Read file %s failed: %s", path, strerror(errno)); + while (1) { + total_read += fread(fdata + total_read, 1, allocation_size - total_read, f); + if (ferror(f)) { + if (errno == EINTR) { + continue; + } + fatal("Read from %s failed: %s", path, strerror(errno)); + } + if (feof(f)) { + break; + } + if (total_read == allocation_size) { + if (allocation_size > SIZE_MAX / 2) { + fatal("Out of memory."); + } + allocation_size *= 2; + if ((realloc_result = realloc(fdata, allocation_size + 1)) == NULL) { + free(fdata); + fatal("Out of memory."); + } + fdata = realloc_result; + } + } + if (f != stdin) { + fclose(f); } - fclose(f); + fdata[total_read] = '\0'; *datap = fdata; - *lenp = len; + *lenp = total_read; } static void diff --git a/tools/nngcat/nngcat_stdin_pipe_test.sh b/tools/nngcat/nngcat_stdin_pipe_test.sh new file mode 100755 index 00000000..5fec0ab7 --- /dev/null +++ b/tools/nngcat/nngcat_stdin_pipe_test.sh @@ -0,0 +1,44 @@ +#!/bin/bash + +# +# Copyright 2018 Staysail Systems, Inc. <info@staysail.tech> +# Copyright 2018 Capitar IT Group BV <info@capitar.com> +# Copyright 2020 Lager Data, Inc. <support@lagerdata.com> +# +# This software is supplied under the terms of the MIT License, a +# copy of which should be located in the distribution where this +# file was obtained (LICENSE.txt). A copy of the license may also be +# found online at https://opensource.org/licenses/MIT. +# + +NNGCAT=${NNGCAT:=$1} +NNGCAT=${NNGCAT:-./nngcat} +ADDR="ipc:///tmp/nngcat_stdin_pipe_test" +OUTPUT=/tmp/nngcat_stdin_pipe_test.$$.out + +echo -n "Verify reading from stdin pipe: " + +trap "rm $OUTPUT" 0 + +${NNGCAT} --listen ${ADDR} --count=1 --recv-timeout=3 --recv-maxsz=0 --pull0 --raw > $OUTPUT 2>/dev/null & +bgid=$! + +sleep 1 +# for speed of execution, run these in the background, they should be ignored +echo "hello world" | ${NNGCAT} --connect ${ADDR} --delay=1 --push0 --file - +wait "$bgid" 2>/dev/null + +sum=$(cksum ${OUTPUT}) +sum=${sum%% *} + +# This matches "hello world\n" since echo adds a trailing newline +if [[ ${sum} == 3733384285 ]] +then + echo "pass" + exit 0 +fi +echo "FAIL: Checksum failed (Wanted 3733384285 got ${sum})" +echo "OUTPUT:" +ls -la ${OUTPUT} + +exit 1 |
