Add `scm_t_off' type so that `scm_t_port' has a fixed layout.
authorLudovic Courtès <ludo@gnu.org>
Thu, 25 Jun 2009 21:32:44 +0000 (23:32 +0200)
committerLudovic Courtès <ludo@gnu.org>
Thu, 25 Jun 2009 21:32:44 +0000 (23:32 +0200)
* 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.

NEWS
doc/ref/api-io.texi
libguile/fports.c
libguile/gen-scmconfig.c
libguile/ports.c
libguile/ports.h
libguile/r6rs-ports.c
libguile/rw.c
libguile/strports.c

diff --git a/NEWS b/NEWS
index 5175a09..a598083 100644 (file)
--- 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+
index 12c19b7..b0b5741 100644 (file)
@@ -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
index de788c9..f6e0556 100644 (file)
@@ -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)
       {
index 85ebfae..98fcc88 100644 (file)
@@ -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");
index 248e0a4..98207b0 100644 (file)
@@ -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);
       
index 64a0a89..8a21b09 100644 (file)
@@ -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 <sys/types.h>
 
 \f
 
@@ -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);
index d77c214..e3aa99e 100644 (file)
@@ -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:
index f6d3142..cb62b79 100644 (file)
@@ -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);
index 3f8a22e..5c67bf9 100644 (file)
@@ -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);