From: Ludovic Courtès Date: Thu, 25 Jun 2009 21:32:44 +0000 (+0200) Subject: Add `scm_t_off' type so that `scm_t_port' has a fixed layout. X-Git-Url: http://git.hcoop.net/bpt/guile.git/commitdiff_plain/f1ce9199335bebab1a62286ac965f33dc91ca97f?hp=376b6bd7a2d2484f5579645becc26c40a97c31a6 Add `scm_t_off' type so that `scm_t_port' has a fixed layout. * libguile/gen-scmconfig.c (main): Produce a definition for `scm_t_off'. * libguile/ports.h (scm_t_port)[read_buf_size, saved_read_buf_size, write_buf_size, seek, truncate]: Use `scm_t_off' instead of `off_t' so that the layout and size of the structure does not depend on the application's `_FILE_OFFSET_BITS' value. Reported by Bill Schottstaedt, see http://lists.gnu.org/archive/html/bug-guile/2009-06/msg00018.html. (scm_set_port_seek, scm_set_port_truncate): Update. * libguile/ports.c (scm_set_port_seek, scm_set_port_truncate): Use `scm_t_off' and `off_t_or_off64_t'. * libguile/fports.c (fport_seek, fport_truncate): Use `scm_t_off' instead of `off_t'. * libguile/r6rs-ports.c (bip_seek, cbp_seek, bop_seek): Use `scm_t_off' instead of `off_t'. * libguile/rw.c (scm_write_string_partial): Likewise. * libguile/strports.c (st_resize_port, st_seek, st_truncate): Likewise. * doc/ref/api-io.texi (Port Implementation): Update prototype of `scm_set_port_seek ()' and `scm_set_port_truncate ()'. * NEWS: Update. --- diff --git a/NEWS b/NEWS index 5175a0900..a5980836e 100644 --- a/NEWS +++ b/NEWS @@ -511,6 +511,11 @@ This procedure corresponds to Scheme's `module-public-interface'. ** `scm_stat' has an additional argument, `exception_on_error' ** `scm_primitive_load_path' has an additional argument `exception_on_not_found' +** `scm_set_port_seek' and `scm_set_port_truncate' use the `scm_t_off' type + +Previously they would use the `off_t' type, which is fragile since its +definition depends on the application's value for `_FILE_OFFSET_BITS'. + * Changes to the distribution ** Guile's license is now LGPLv3+ diff --git a/doc/ref/api-io.texi b/doc/ref/api-io.texi index 12c19b7dc..b0b57412a 100644 --- a/doc/ref/api-io.texi +++ b/doc/ref/api-io.texi @@ -1531,7 +1531,7 @@ implementations take care to avoid this problem. The procedure is set using -@deftypefun void scm_set_port_seek (scm_t_bits tc, off_t (*seek) (SCM port, off_t offset, int whence)) +@deftypefun void scm_set_port_seek (scm_t_bits tc, scm_t_off (*seek) (SCM port, scm_t_off offset, int whence)) @end deftypefun @item truncate @@ -1539,7 +1539,7 @@ Truncate the port data to be specified length. It can be assumed that the current state of @code{rw_active} is @code{SCM_PORT_NEITHER}. Set using -@deftypefun void scm_set_port_truncate (scm_t_bits tc, void (*truncate) (SCM port, off_t length)) +@deftypefun void scm_set_port_truncate (scm_t_bits tc, void (*truncate) (SCM port, scm_t_off length)) @end deftypefun @end table diff --git a/libguile/fports.c b/libguile/fports.c index de788c928..f6e05566b 100644 --- a/libguile/fports.c +++ b/libguile/fports.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2002, 2003, 2004, 2006, 2007, 2008 Free Software Foundation, Inc. +/* Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009 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 @@ -671,8 +671,8 @@ fport_seek_or_seek64 (SCM port, off_t_or_off64_t offset, int whence) fport_seek already. */ #if GUILE_USE_64_CALLS && HAVE_STAT64 && SIZEOF_OFF_T != SIZEOF_OFF64_T -static off_t -fport_seek (SCM port, off_t offset, int whence) +static scm_t_off +fport_seek (SCM port, scm_t_off offset, int whence) { off64_t rv = fport_seek_or_seek64 (port, (off64_t) offset, whence); if (rv > OFF_T_MAX || rv < OFF_T_MIN) @@ -680,7 +680,7 @@ fport_seek (SCM port, off_t offset, int whence) errno = EOVERFLOW; scm_syserror ("fport_seek"); } - return (off_t) rv; + return (scm_t_off) rv; } #else @@ -696,7 +696,7 @@ scm_i_fport_seek (SCM port, SCM offset, int how) } static void -fport_truncate (SCM port, off_t length) +fport_truncate (SCM port, scm_t_off length) { scm_t_fport *fp = SCM_FSTREAM (port); @@ -748,7 +748,7 @@ fport_write (SCM port, const void *data, size_t size) } { - off_t space = pt->write_end - pt->write_pos; + scm_t_off space = pt->write_end - pt->write_pos; if (size <= space) { diff --git a/libguile/gen-scmconfig.c b/libguile/gen-scmconfig.c index 85ebfaed7..98fcc885e 100644 --- a/libguile/gen-scmconfig.c +++ b/libguile/gen-scmconfig.c @@ -400,6 +400,24 @@ main (int argc, char *argv[]) pf ("#define SCM_HAVE_READDIR64_R 0 /* 0 or 1 */\n"); #endif + /* Arrange so that we have a file offset type that reflects the one + used when compiling Guile, regardless of what the application's + `_FILE_OFFSET_BITS' says. See + http://lists.gnu.org/archive/html/bug-guile/2009-06/msg00018.html + for the original bug report. + + Note that we can't define `scm_t_off' in terms of `off_t' or + `off64_t' because they may or may not be available depending on + how the application that uses Guile is compiled. */ + +#if defined GUILE_USE_64_CALLS && defined HAVE_STAT64 + pf ("typedef scm_t_int64 scm_t_off;\n"); +#elif SIZEOF_OFF_T == SIZEOF_INT + pf ("typedef int scm_t_off;\n"); +#else + pf ("typedef long int scm_t_off;\n"); +#endif + #if USE_DLL_IMPORT pf ("\n"); pf ("/* Define some additional CPP macros on Win32 platforms. */\n"); diff --git a/libguile/ports.c b/libguile/ports.c index 248e0a49c..98207b0dc 100644 --- a/libguile/ports.c +++ b/libguile/ports.c @@ -222,15 +222,14 @@ scm_set_port_close (scm_t_bits tc, int (*close) (SCM)) } void -scm_set_port_seek (scm_t_bits tc, off_t (*seek) (SCM port, - off_t OFFSET, - int WHENCE)) +scm_set_port_seek (scm_t_bits tc, + scm_t_off (*seek) (SCM, scm_t_off, int)) { scm_ptobs[SCM_TC2PTOBNUM (tc)].seek = seek; } void -scm_set_port_truncate (scm_t_bits tc, void (*truncate) (SCM port, off_t length)) +scm_set_port_truncate (scm_t_bits tc, void (*truncate) (SCM, scm_t_off)) { scm_ptobs[SCM_TC2PTOBNUM (tc)].truncate = truncate; } @@ -1399,15 +1398,15 @@ SCM_DEFINE (scm_seek, "seek", 3, 0, 0, else if (SCM_OPPORTP (fd_port)) { scm_t_ptob_descriptor *ptob = scm_ptobs + SCM_PTOBNUM (fd_port); - off_t off = scm_to_off_t (offset); - off_t rv; + off_t_or_off64_t off = scm_to_off_t_or_off64_t (offset); + off_t_or_off64_t rv; if (!ptob->seek) SCM_MISC_ERROR ("port is not seekable", scm_cons (fd_port, SCM_EOL)); else rv = ptob->seek (fd_port, off, how); - return scm_from_off_t (rv); + return scm_from_off_t_or_off64_t (rv); } else /* file descriptor?. */ { @@ -1496,7 +1495,7 @@ SCM_DEFINE (scm_truncate_file, "truncate-file", 1, 1, 0, } else if (SCM_OPOUTPORTP (object)) { - off_t c_length = scm_to_off_t (length); + off_t_or_off64_t c_length = scm_to_off_t_or_off64_t (length); scm_t_port *pt = SCM_PTAB_ENTRY (object); scm_t_ptob_descriptor *ptob = scm_ptobs + SCM_PTOBNUM (object); diff --git a/libguile/ports.h b/libguile/ports.h index 64a0a89c7..8a21b09f9 100644 --- a/libguile/ports.h +++ b/libguile/ports.h @@ -29,8 +29,6 @@ #include "libguile/struct.h" #include "libguile/threads.h" -/* Not sure if this is a good idea. We need it for off_t. */ -#include @@ -70,7 +68,7 @@ typedef struct unsigned char *read_buf; /* buffer start. */ const unsigned char *read_pos;/* the next unread char. */ unsigned char *read_end; /* pointer to last buffered char + 1. */ - off_t read_buf_size; /* size of the buffer. */ + scm_t_off read_buf_size; /* size of the buffer. */ /* when chars are put back into the buffer, e.g., using peek-char or unread-string, the read-buffer pointers are switched to cbuf. @@ -79,7 +77,7 @@ typedef struct unsigned char *saved_read_buf; const unsigned char *saved_read_pos; unsigned char *saved_read_end; - off_t saved_read_buf_size; + scm_t_off saved_read_buf_size; /* write requests are saved into this buffer at write_pos until it reaches write_buf + write_buf_size, then the ptob flush is @@ -88,7 +86,7 @@ typedef struct unsigned char *write_buf; /* buffer start. */ unsigned char *write_pos; /* pointer to last buffered char + 1. */ unsigned char *write_end; /* pointer to end of buffer + 1. */ - off_t write_buf_size; /* size of the buffer. */ + scm_t_off write_buf_size; /* size of the buffer. */ unsigned char shortbuf; /* buffer for "unbuffered" streams. */ @@ -185,8 +183,8 @@ typedef struct scm_t_ptob_descriptor int (*fill_input) (SCM port); int (*input_waiting) (SCM port); - off_t (*seek) (SCM port, off_t OFFSET, int WHENCE); - void (*truncate) (SCM port, off_t length); + scm_t_off (*seek) (SCM port, scm_t_off OFFSET, int WHENCE); + void (*truncate) (SCM port, scm_t_off length); } scm_t_ptob_descriptor; @@ -224,12 +222,12 @@ SCM_API void scm_set_port_end_input (scm_t_bits tc, void (*end_input) (SCM port, int offset)); SCM_API void scm_set_port_seek (scm_t_bits tc, - off_t (*seek) (SCM port, - off_t OFFSET, - int WHENCE)); + scm_t_off (*seek) (SCM port, + scm_t_off OFFSET, + int WHENCE)); SCM_API void scm_set_port_truncate (scm_t_bits tc, void (*truncate) (SCM port, - off_t length)); + scm_t_off length)); SCM_API void scm_set_port_input_waiting (scm_t_bits tc, int (*input_waiting) (SCM)); SCM_API SCM scm_char_ready_p (SCM port); size_t scm_take_from_input_buffers (SCM port, char *dest, size_t read_len); diff --git a/libguile/r6rs-ports.c b/libguile/r6rs-ports.c index d77c2147a..e3aa99e16 100644 --- a/libguile/r6rs-ports.c +++ b/libguile/r6rs-ports.c @@ -125,11 +125,11 @@ bip_fill_input (SCM port) return result; } -static off_t -bip_seek (SCM port, off_t offset, int whence) +static scm_t_off +bip_seek (SCM port, scm_t_off offset, int whence) #define FUNC_NAME "bip_seek" { - off_t c_result = 0; + scm_t_off c_result = 0; scm_t_port *c_port = SCM_PTAB_ENTRY (port); switch (whence) @@ -217,12 +217,12 @@ cbp_mark (SCM port) return SCM_BOOL_F; } -static off_t -cbp_seek (SCM port, off_t offset, int whence) +static scm_t_off +cbp_seek (SCM port, scm_t_off offset, int whence) #define FUNC_NAME "cbp_seek" { SCM result; - off_t c_result = 0; + scm_t_off c_result = 0; switch (whence) { @@ -885,8 +885,8 @@ bop_write (SCM port, const void *data, size_t size) buf->len = (buf->len > buf->pos) ? buf->len : buf->pos; } -static off_t -bop_seek (SCM port, off_t offset, int whence) +static scm_t_off +bop_seek (SCM port, scm_t_off offset, int whence) #define FUNC_NAME "bop_seek" { scm_t_bop_buffer *buf; @@ -895,7 +895,7 @@ bop_seek (SCM port, off_t offset, int whence) switch (whence) { case SEEK_CUR: - offset += (off_t) buf->pos; + offset += (scm_t_off) buf->pos; /* Fall through. */ case SEEK_SET: diff --git a/libguile/rw.c b/libguile/rw.c index f6d314275..cb62b79b9 100644 --- a/libguile/rw.c +++ b/libguile/rw.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001, 2006 Free Software Foundation, Inc. +/* Copyright (C) 2001, 2006, 2009 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 @@ -207,7 +207,7 @@ SCM_DEFINE (scm_write_string_partial, "write-string/partial", 1, 3, 0, #define FUNC_NAME s_scm_write_string_partial { const char *src; - long write_len; + scm_t_off write_len; int fdes; { @@ -232,7 +232,7 @@ SCM_DEFINE (scm_write_string_partial, "write-string/partial", 1, 3, 0, SCM port = (SCM_UNBNDP (port_or_fdes)? scm_current_output_port () : port_or_fdes); scm_t_port *pt; - off_t space; + scm_t_off space; SCM_VALIDATE_OPFPORT (2, port); SCM_VALIDATE_OUTPUT_PORT (2, port); diff --git a/libguile/strports.c b/libguile/strports.c index 3f8a22e7d..5c67bf9a8 100644 --- a/libguile/strports.c +++ b/libguile/strports.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1995,1996,1998,1999,2000,2001,2002, 2003, 2005, 2006 Free Software Foundation, Inc. +/* Copyright (C) 1995,1996,1998,1999,2000,2001,2002, 2003, 2005, 2006, 2009 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 @@ -108,7 +108,7 @@ stfill_buffer (SCM port) /* change the size of a port's string to new_size. this doesn't change read_buf_size. */ static void -st_resize_port (scm_t_port *pt, off_t new_size) +st_resize_port (scm_t_port *pt, scm_t_off new_size) { SCM old_stream = SCM_PACK (pt->stream); const char *src = scm_i_string_chars (old_stream); @@ -118,7 +118,7 @@ st_resize_port (scm_t_port *pt, off_t new_size) unsigned long int min_size = min (old_size, new_size); unsigned long int i; - off_t index = pt->write_pos - pt->write_buf; + scm_t_off index = pt->write_pos - pt->write_buf; pt->write_buf_size = new_size; @@ -199,11 +199,11 @@ st_end_input (SCM port, int offset) pt->rw_active = SCM_PORT_NEITHER; } -static off_t -st_seek (SCM port, off_t offset, int whence) +static scm_t_off +st_seek (SCM port, scm_t_off offset, int whence) { scm_t_port *pt = SCM_PTAB_ENTRY (port); - off_t target; + scm_t_off target; if (pt->rw_active == SCM_PORT_READ && offset == 0 && whence == SEEK_CUR) /* special case to avoid disturbing the unread-char buffer. */ @@ -272,7 +272,7 @@ st_seek (SCM port, off_t offset, int whence) } static void -st_truncate (SCM port, off_t length) +st_truncate (SCM port, scm_t_off length) { scm_t_port *pt = SCM_PTAB_ENTRY (port);