At EOF, pv waits for bytes already written to an output pipe to be consumed before finishing. If the downstream reader exits without reading those bytes, the pipe can keep reporting unread data forever. Since pv has no more input, there is no later write that would fail with EPIPE and break the wait. Detect this EOF drain-wait case with a non-blocking poll() on the output pipe. When the pipe reports that its readers are gone, mark the pipe closed and stop waiting for bytes that can no longer be consumed. While a reader is still present, keep the existing behaviour and continue waiting for the pipe buffer to drain. Add regression coverage for both ways pv can reach this state: direct input that leaves unread output bytes behind, and a pipeline where the original producer fails but an intermediate filter such as gzip still emits a valid empty stream. The latter matters because pv can still have pending output at EOF even when the command at the start of the pipeline failed immediately. Signed-off-by: Wolfgang Hoschek <wolfgang.hoschek@mac.com>
157 lines
5.0 KiB
Makefile
157 lines
5.0 KiB
Makefile
## Process this file with automake to produce Makefile.in
|
|
|
|
AUTOMAKE_OPTIONS = subdir-objects
|
|
|
|
SUBDIRS = po
|
|
|
|
bin_PROGRAMS = pv
|
|
dist_doc_DATA = README.md docs/INSTALL docs/COPYING docs/NEWS.md docs/ACKNOWLEDGEMENTS.md docs/DEVELOPERS.md
|
|
dist_man1_MANS = docs/pv.1
|
|
|
|
EXTRA_DIST = docs/pv.1.md docs/benchmark-rw-syscalls-vs-data.sh docs/release.cf
|
|
|
|
pv_SOURCES = \
|
|
src/main/debug.c \
|
|
src/main/help.c \
|
|
src/main/main.c \
|
|
src/main/options.c \
|
|
src/main/version.c \
|
|
src/pv/calc.c \
|
|
src/pv/cursor.c \
|
|
src/pv/display.c \
|
|
src/pv/elapsedtime.c \
|
|
src/pv/file.c \
|
|
src/pv/format/averagerate.c \
|
|
src/pv/format/barstyle.c \
|
|
src/pv/format/bufferpercent.c \
|
|
src/pv/format/bytes.c \
|
|
src/pv/format/eta.c \
|
|
src/pv/format/fineta.c \
|
|
src/pv/format/lastwritten.c \
|
|
src/pv/format/name.c \
|
|
src/pv/format/previousline.c \
|
|
src/pv/format/progressbar.c \
|
|
src/pv/format/rate.c \
|
|
src/pv/format/ratio.c \
|
|
src/pv/format/sgr.c \
|
|
src/pv/format/timer.c \
|
|
src/pv/loop.c \
|
|
src/pv/number.c \
|
|
src/pv/proctitle.c \
|
|
src/pv/remote.c \
|
|
src/pv/signal.c \
|
|
src/pv/state.c \
|
|
src/pv/string.c \
|
|
src/pv/transfer.c \
|
|
src/pv/watchpid.c \
|
|
src/include/config-aux.h \
|
|
src/include/options.h \
|
|
src/include/pv-internal.h \
|
|
src/include/pv.h
|
|
|
|
## Allow tests to write diagnostic info to fd 9 to reach the original
|
|
## stderr even when the test driver is sending test output to a file.
|
|
AM_TESTS_FD_REDIRECT = 9>&2
|
|
|
|
AM_TESTS_ENVIRONMENT = \
|
|
. $(srcdir)/tests/test-env.sh \
|
|
;
|
|
TESTS = \
|
|
tests/Bug_-_Display_length_at_magnitude_boundary_-_Bytes.test \
|
|
tests/Bug_-_Display_length_at_magnitude_boundary_-_Rate.test \
|
|
tests/Bug_-_Install_all_files.test \
|
|
tests/Display_-_--average-rate.test \
|
|
tests/Display_-_--bits.test \
|
|
tests/Display_-_--buffer-percent.test \
|
|
tests/Display_-_--bytes.test \
|
|
tests/Display_-_--eta_-_plausible_values.test \
|
|
tests/Display_-_--fineta_-_plausible_values.test \
|
|
tests/Display_-_--last-written.test \
|
|
tests/Display_-_--numeric_--bytes_--line-mode.test \
|
|
tests/Display_-_--numeric_--bytes.test \
|
|
tests/Display_-_--numeric.test \
|
|
tests/Display_-_--numeric_--timer.test \
|
|
tests/Display_-_--progress_-_basic_movement.test \
|
|
tests/Display_-_--progress_-_increasing.test \
|
|
tests/Display_-_--quiet.test \
|
|
tests/Display_-_--rate_-_displayed_value_changes.test \
|
|
tests/Display_-_--timer_-_displayed_value_changes.test \
|
|
tests/General_-_--pidfile.test \
|
|
tests/General_-_--size_argument_handling.test \
|
|
tests/Integrity_-_Basic.test \
|
|
tests/Integrity_-_Binary_data.test \
|
|
tests/Integrity_-_From_bursty_source.test \
|
|
tests/Integrity_-_Large_file_support.test \
|
|
tests/Integrity_-_On_closed_output_pipe_at_EOF.test \
|
|
tests/Integrity_-_On_failed_input_pipe_at_EOF.test \
|
|
tests/Integrity_-_On_output_pipe_close.test \
|
|
tests/Integrity_-_When_adjusted_remotely.test \
|
|
tests/Memory_safety_-_Basic.test \
|
|
tests/Memory_safety_-_Process_title.test \
|
|
tests/Memory_safety_-_Remote_control_receiver.test \
|
|
tests/Memory_safety_-_Remote_control_sender.test \
|
|
tests/Memory_safety_-_Watchfd.test \
|
|
tests/Modifiers_-_--direct-io.test \
|
|
tests/Modifiers_-_--force.test \
|
|
tests/Modifiers_-_--interval.test \
|
|
tests/Modifiers_-_--line-mode.test \
|
|
tests/Modifiers_-_--size_from_file_size.test \
|
|
tests/Modifiers_-_--size_from_dir_size.test \
|
|
tests/Modifiers_-_--size.test \
|
|
tests/Modifiers_-_--sync.test \
|
|
tests/Monitor_-_Basic.test \
|
|
tests/Sparse_-_Basic.test \
|
|
tests/Terminal_-_Detect_width.test \
|
|
tests/Transfer_-_--rate-limit.test \
|
|
tests/Transfer_-_--remote.test \
|
|
tests/Transfer_-_--stop-at-size.test \
|
|
tests/Transfer_-_--stop-at-size_reads.test \
|
|
tests/Watchfd_-_Multiple_arguments.test \
|
|
tests/Watchfd_-_Multiple_descriptors.test \
|
|
tests/Watchfd_-_Single_descriptor.test
|
|
|
|
EXTRA_DIST += $(TESTS) tests/run-valgrind.sh tests/test-env.sh
|
|
|
|
docs/pv.1.md: $(srcdir)/docs/pv.1
|
|
test -d docs || mkdir docs
|
|
pandoc --from man --to markdown < $< | sed '/\*\*\*\*/{s/\*//g;s/^/**/;s/$$/**/}' | sed '/^```/,/^```/d' | sed 's/^\\\[/[/' > $@
|
|
|
|
SUFFIXES = .c .o .e
|
|
|
|
.c.e:
|
|
-splint -badflag +posixlib $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) -DSPLINT=1 $< > $@ 2>&1
|
|
-flawfinder $< >> $@ 2>&1
|
|
|
|
indent:
|
|
cd $(srcdir) && indent -npro -kr -i8 -cd42 -c45 -l120 src/*/*.c src/*/*/*.c
|
|
|
|
indentclean:
|
|
rm -f $(srcdir)/src/*/*.c~ $(srcdir)/src/*/*/*.c~
|
|
|
|
analyse: $(pv_SOURCES:.c=.e) FORCE
|
|
grep -E -e '^Finished checking --' -e 'Hits = ' $+ 2>/dev/null || true
|
|
|
|
FORCE:
|
|
|
|
clean-local:
|
|
rm -f src/*/*.e src/*/*/*.e
|
|
|
|
# Convenience alias for "make check": "make test"
|
|
test: check
|
|
|
|
# Generate a package manifest if MAINTAINER is set.
|
|
dist-hook:
|
|
if test -n "$(MAINTAINER)"; then \
|
|
cd "$(top_distdir)" \
|
|
&& { printf "%s\n\n" "Check file integrity with 'sha512sum -c MANIFEST && echo OK'."; \
|
|
find -type f -not -name MANIFEST -exec sha512sum '{}' ';' | sort -k 2; } \
|
|
| gpg -u "$(MAINTAINER)" --clearsign > MANIFEST; \
|
|
else true; fi
|
|
|
|
# "release" target - requires MAINTAINER variable to select GPG key.
|
|
release: distcheck
|
|
gpg --list-secret-keys 2>&1 | grep -F 'uid' | grep -Fq "$(MAINTAINER)"
|
|
gpg -u "$(MAINTAINER)" -ab $(distdir).tar.gz
|
|
cp -f $(distdir).tar.gz.asc $(distdir).tar.gz.txt
|
|
chmod 644 $(distdir).tar.gz $(distdir).tar.gz.asc $(distdir).tar.gz.txt
|