From 24aeea28c141f3f8af1c8953de55bb48a4272398 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 9 Dec 2018 12:16:10 -0700 Subject: [PATCH] file-position: repair for OS pipe after peek Closes #2419 --- pkgs/racket-test-core/tests/racket/port.rktl | 14 ++++++++++++++ racket/src/racket/src/port.c | 4 +++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/pkgs/racket-test-core/tests/racket/port.rktl b/pkgs/racket-test-core/tests/racket/port.rktl index fe92fec24f..d2f23f52ae 100644 --- a/pkgs/racket-test-core/tests/racket/port.rktl +++ b/pkgs/racket-test-core/tests/racket/port.rktl @@ -921,6 +921,20 @@ (delete-file path)) +;; Check `file-position`, OS-level pipes, and peek +(when (and (memq (system-type) '(unix macosx)) + (file-exists? "/bin/cat")) + (define-values (sp stdout-in stdin-out no-stderr) (subprocess #f #f (current-error-port) "/bin/cat")) + (write-bytes #"abcd\n" stdin-out) + (close-output-port stdin-out) + (test 0 file-position stdout-in) + (test #"abc" peek-bytes 3 0 stdout-in) + (test 0 file-position stdout-in) + (test #\a read-char stdout-in) + (test 1 file-position stdout-in) + (close-input-port stdout-in) + (subprocess-wait sp)) + ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Check reader error-message formatting for a struct port diff --git a/racket/src/racket/src/port.c b/racket/src/racket/src/port.c index 9c0b688728..89dc3ff298 100644 --- a/racket/src/racket/src/port.c +++ b/racket/src/racket/src/port.c @@ -4202,6 +4202,7 @@ do_file_position(const char *who, int argc, Scheme_Object *argv[], int can_false return scheme_void; } else { mzlonglong pll; + int already_ungot = 0; if (f) { pll = BIG_OFF_T_IZE(ftello)(f); } else if (fd) { @@ -4210,6 +4211,7 @@ do_file_position(const char *who, int argc, Scheme_Object *argv[], int can_false sz = rktio_get_file_position(scheme_rktio, fd); if (!sz) { pll = do_tell(argv[0], 0); + already_ungot = 1; } else { pll = *sz; free(sz); @@ -4247,7 +4249,7 @@ do_file_position(const char *who, int argc, Scheme_Object *argv[], int can_false } /* Back up for un-gotten & peeked chars: */ - if (SCHEME_INPUT_PORTP(argv[0])) { + if (!already_ungot && SCHEME_INPUT_PORTP(argv[0])) { Scheme_Input_Port *ip; ip = scheme_input_port_record(argv[0]); pll -= ip->ungotten_count;