diff options
Diffstat (limited to 'libguile/fports.c')
-rw-r--r-- | libguile/fports.c | 25 |
1 files changed, 20 insertions, 5 deletions
diff --git a/libguile/fports.c b/libguile/fports.c index 2dc23758f..94ce434d1 100644 --- a/libguile/fports.c +++ b/libguile/fports.c @@ -174,7 +174,8 @@ SCM_DEFINE (scm_setvbuf, "setvbuf", 2, 1, 0, { int cmode; long csize; - SCM drained; + size_t ndrained; + char *drained; scm_t_port *pt; port = SCM_COERCE_OUTPORT (port); @@ -211,9 +212,21 @@ SCM_DEFINE (scm_setvbuf, "setvbuf", 2, 1, 0, pt = SCM_PTAB_ENTRY (port); if (SCM_INPUT_PORT_P (port)) - drained = scm_drain_input (port); + { + /* Drain pending input from PORT. Don't use `scm_drain_input' since + it returns a string, whereas we want binary input here. */ + ndrained = pt->read_end - pt->read_pos; + if (pt->read_buf == pt->putback_buf) + ndrained += pt->saved_read_end - pt->saved_read_pos; + + if (ndrained > 0) + { + drained = scm_gc_malloc_pointerless (ndrained, "file port"); + scm_take_from_input_buffers (port, drained, ndrained); + } + } else - drained = scm_nullstr; + ndrained = 0; if (SCM_OUTPUT_PORT_P (port)) scm_flush_unlocked (port); @@ -232,8 +245,10 @@ SCM_DEFINE (scm_setvbuf, "setvbuf", 2, 1, 0, scm_fport_buffer_add (port, csize, csize); - if (scm_is_true (drained) && scm_c_string_length (drained)) - scm_unread_string (drained, port); + if (ndrained > 0) + /* Put DRAINED back to PORT. */ + while (ndrained-- > 0) + scm_unget_byte (drained[ndrained], port); return SCM_UNSPECIFIED; } |