X-Git-Url: https://git.hcoop.net/bpt/guile.git/blobdiff_plain/fb484fefebdd9ebcf43169b391f704069b3d4b09..5b744b67f7f8350bd66d6c0b659f9375a6d700fa:/libguile/fports.c diff --git a/libguile/fports.c b/libguile/fports.c index dc3d45ce4..8395f0e65 100644 --- a/libguile/fports.c +++ b/libguile/fports.c @@ -1,5 +1,6 @@ /* Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, - * 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc. + * 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, + * 2014, 2015 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -32,9 +33,7 @@ #ifdef HAVE_STRING_H #include #endif -#ifdef HAVE_UNISTD_H #include -#endif #ifdef HAVE_IO_H #include #endif @@ -58,6 +57,7 @@ #include "libguile/hashtab.h" #include "libguile/fports.h" +#include "libguile/ports-internal.h" #if SIZEOF_OFF_T == SIZEOF_INT #define OFF_T_MAX INT_MAX @@ -78,10 +78,10 @@ scm_t_bits scm_tc16_fport; /* default buffer size, used if the O/S won't supply a value. */ static const size_t default_buffer_size = 1024; -/* create FPORT buffer with specified sizes (or -1 to use default size or - 0 for no buffer. */ +/* Create FPORT buffers with specified sizes (or -1 to use default size + or 0 for no buffer.) */ static void -scm_fport_buffer_add (SCM port, long read_size, int write_size) +scm_fport_buffer_add (SCM port, long read_size, long write_size) #define FUNC_NAME "scm_fport_buffer_add" { scm_t_port *pt = SCM_PTAB_ENTRY (port); @@ -147,18 +147,27 @@ SCM_DEFINE (scm_setvbuf, "setvbuf", 2, 1, 0, "@item _IOFBF\n" "block buffered, using a newly allocated buffer of @var{size} bytes.\n" "If @var{size} is omitted, a default size will be used.\n" - "@end table") + "@end table\n\n" + "Only certain types of ports are supported, most importantly\n" + "file ports.") #define FUNC_NAME s_scm_setvbuf { int cmode; long csize; size_t ndrained; - char *drained; + char *drained = NULL; scm_t_port *pt; + scm_t_ptob_descriptor *ptob; port = SCM_COERCE_OUTPORT (port); - SCM_VALIDATE_OPFPORT (1,port); + SCM_VALIDATE_OPENPORT (1, port); + ptob = SCM_PORT_DESCRIPTOR (port); + + if (ptob->setvbuf == NULL) + scm_wrong_type_arg_msg (FUNC_NAME, 1, port, + "port that supports 'setvbuf'"); + cmode = scm_to_int (mode); if (cmode != _IONBF && cmode != _IOFBF && cmode != _IOLBF) scm_out_of_range (FUNC_NAME, mode); @@ -169,9 +178,8 @@ SCM_DEFINE (scm_setvbuf, "setvbuf", 2, 1, 0, cmode = _IOFBF; } else - { - SCM_SET_CELL_WORD_0 (port, SCM_CELL_WORD_0 (port) & ~(scm_t_bits)SCM_BUFLINE); - } + SCM_SET_CELL_WORD_0 (port, + SCM_CELL_WORD_0 (port) & ~(scm_t_bits) SCM_BUFLINE); if (SCM_UNBNDP (size)) { @@ -216,12 +224,8 @@ SCM_DEFINE (scm_setvbuf, "setvbuf", 2, 1, 0, pt->read_end = pt->saved_read_end; pt->read_buf_size = pt->saved_read_buf_size; } - if (pt->read_buf != &pt->shortbuf) - scm_gc_free (pt->read_buf, pt->read_buf_size, "port buffer"); - if (pt->write_buf != &pt->shortbuf) - scm_gc_free (pt->write_buf, pt->write_buf_size, "port buffer"); - scm_fport_buffer_add (port, csize, csize); + ptob->setvbuf (port, csize, csize); if (ndrained > 0) /* Put DRAINED back to PORT. */ @@ -338,7 +342,8 @@ scm_open_file_with_encoding (SCM filename, SCM mode, SCM port; int fdes, flags = 0, binary = 0; unsigned int retries; - char *file, *md, *ptr; + char *file; + const char *md, *ptr; if (SCM_UNLIKELY (!(scm_is_false (encoding) || scm_is_string (encoding)))) scm_wrong_type_arg_msg (FUNC_NAME, 0, encoding, @@ -349,8 +354,10 @@ scm_open_file_with_encoding (SCM filename, SCM mode, file = scm_to_locale_string (filename); scm_dynwind_free (file); - md = scm_to_locale_string (mode); - scm_dynwind_free (md); + if (SCM_UNLIKELY (!scm_i_try_narrow_string (mode))) + scm_out_of_range (FUNC_NAME, mode); + + md = scm_i_string_chars (mode); switch (*md) { @@ -974,6 +981,7 @@ scm_make_fptob () scm_set_port_seek (tc, fport_seek); scm_set_port_truncate (tc, fport_truncate); scm_set_port_input_waiting (tc, fport_input_waiting); + scm_set_port_setvbuf (tc, scm_fport_buffer_add); return tc; }