Re: large file support in glib



Sven Neumann <sven gimp org> writes:

> Hi,
> 
> we've discovered that for some obscure reasons g_file_test() fails on
> files larger than 2GB. I also expect g_io_channel_seek() to fail since
> it uses off_t. A clean and simple solution to this problem would be to
> add AC_SYS_LARGE_FILE to configure.in.  This macro would also allow to
> easily disable large file support using the --disable-largefile
> configure option. Unfortunately autoconf-2.13 does not support
> AC_SYS_LARGE_FILE. So the patch would boil down to:
> 
> 
> Index: configure.in
> ===================================================================
> RCS file: /cvs/gnome/glib/configure.in,v
> retrieving revision 1.265
> diff -u -p -r1.265 configure.in
> --- configure.in	2002/02/09 20:08:02	1.265
> +++ configure.in	2002/02/13 18:23:10
> @@ -5,8 +5,8 @@ builtin(include, acglib.m4)dnl
>  builtin(include, glib/libcharset/codeset.m4)dnl
>  builtin(include, glib/libcharset/glibc21.m4)dnl
>  
> -# require autoconf 2.13
> -AC_PREREQ(2.13)
> +# require autoconf 2.52
> +AC_PREREQ(2.52)
>  
>  # Process this file with autoconf to produce a configure script.
>  AC_INIT(glib/glib.h)
> @@ -195,6 +195,8 @@ AC_LANG_RESTORE
>  
>  AM_PROG_CC_STDC
>  AC_PROG_INSTALL
> +
> +AC_SYS_LARGEFILE
>  
>  #
>  # Find pkg-config
> 
> 
> 
> Probably it's time to do the switch to autoconf-2.5 now. What do you
> think?

I think it's OK. I've been using it for ~9 months and most packages
now build with it fine; certainly all the stuff in GNOME CVS.

It looks like we actually only need 2.50 for AC_SYS_LARGEFILE, but
since I don't have any recent experience with 2.50/2.51 systems,
so requiring 2.52 is probably safest.

My one concern with AC_SYS_LARGEFILE is that it causes -n32 to
be used on IRIX, which could be an unexpected side-effect, and
probably will cause bad things to happen further down the 
dependecny chain if the user isn't already specifying -n32.

I'm applying, in aggregate the following patch. (fingers crossed)

The handling of (off_t)offset != offset could probably be improved;
I took the simple approach of treating it like a EINVAL return
from LSEEK below.

Regards,
                                        Owen

Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/glib/ChangeLog,v
retrieving revision 1.1025
diff -u -p -r1.1025 ChangeLog
--- ChangeLog	2002/02/15 09:58:47	1.1025
+++ ChangeLog	2002/02/15 16:24:18
@@ -1,3 +1,12 @@
+Fri Feb 15 10:41:51 2002  Owen Taylor  <otaylor redhat com>
+
+	* configure.in: Require autoconf-2.52, run AC_SYS_LARGEFILE.
+	(#71410, Sven Neumann)
+
+	* glib/giounix.c glib/giowin32.c glib/giochannel.[ch]:
+	Change offset type for g_io_channel_seek[_position] to
+	gint64.
+
 2002-02-15  Sebastian Wilhelmi  <wilhelmi ira uka de>
 
 	* tests/thread-test.c: Do not assume, that after
Index: configure.in
===================================================================
RCS file: /cvs/gnome/glib/configure.in,v
retrieving revision 1.265
diff -u -p -r1.265 configure.in
--- configure.in	2002/02/09 20:08:02	1.265
+++ configure.in	2002/02/15 16:24:19
@@ -5,8 +5,8 @@ builtin(include, acglib.m4)dnl
 builtin(include, glib/libcharset/codeset.m4)dnl
 builtin(include, glib/libcharset/glibc21.m4)dnl
 
-# require autoconf 2.13
-AC_PREREQ(2.13)
+# require autoconf 2.52
+AC_PREREQ(2.52)
 
 # Process this file with autoconf to produce a configure script.
 AC_INIT(glib/glib.h)
@@ -195,6 +195,8 @@ AC_LANG_RESTORE
 
 AM_PROG_CC_STDC
 AC_PROG_INSTALL
+
+AC_SYS_LARGEFILE
 
 #
 # Find pkg-config
Index: glib/giochannel.c
===================================================================
RCS file: /cvs/gnome/glib/glib/giochannel.c,v
retrieving revision 1.32
diff -u -p -r1.32 giochannel.c
--- glib/giochannel.c	2002/01/28 21:17:45	1.32
+++ glib/giochannel.c	2002/02/15 16:24:19
@@ -239,7 +239,7 @@ g_io_channel_write (GIOChannel  *channel
  **/
 GIOError 
 g_io_channel_seek  (GIOChannel   *channel,
-		    glong         offset, 
+		    gint64        offset, 
 		    GSeekType     type)
 {
   GError *err = NULL;
@@ -799,7 +799,7 @@ g_io_channel_get_close_on_unref	(GIOChan
  **/
 GIOStatus
 g_io_channel_seek_position	(GIOChannel* channel,
-				 glong       offset,
+				 gint64      offset,
 				 GSeekType   type,
 				 GError    **error)
 {
Index: glib/giochannel.h
===================================================================
RCS file: /cvs/gnome/glib/glib/giochannel.h,v
retrieving revision 1.17
diff -u -p -r1.17 giochannel.h
--- glib/giochannel.h	2001/09/10 23:59:33	1.17
+++ glib/giochannel.h	2002/02/15 16:24:19
@@ -145,7 +145,7 @@ struct _GIOFuncs
 				  gsize        *bytes_written,
 				  GError      **err);
   GIOStatus (*io_seek)           (GIOChannel   *channel, 
-				  glong         offset, 
+				  gint64        offset, 
 				  GSeekType     type,
 				  GError      **err);
   GIOStatus  (*io_close)         (GIOChannel   *channel,
@@ -173,7 +173,7 @@ GIOError  g_io_channel_write    (GIOChan
 			         gsize          count,
 			         gsize         *bytes_written);
 GIOError  g_io_channel_seek     (GIOChannel    *channel,
-			         glong          offset, 
+			         gint64         offset, 
 			         GSeekType      type);
 void      g_io_channel_close    (GIOChannel    *channel);
 #endif /* G_DISABLE_DEPRECATED */
@@ -254,7 +254,7 @@ GIOStatus   g_io_channel_write_unichar  
 					   gunichar      thechar,
 					   GError      **error);
 GIOStatus   g_io_channel_seek_position    (GIOChannel   *channel,
-					   glong         offset,
+					   gint64        offset,
 					   GSeekType     type,
 					   GError      **error);
 GIOChannel* g_io_channel_new_file         (const gchar  *filename,
Index: glib/giounix.c
===================================================================
RCS file: /cvs/gnome/glib/glib/giounix.c,v
retrieving revision 1.24
diff -u -p -r1.24 giounix.c
--- glib/giounix.c	2001/12/20 08:52:01	1.24
+++ glib/giounix.c	2002/02/15 16:24:19
@@ -31,6 +31,8 @@
  * MT safe
  */
 
+#include "config.h"
+
 #include "glib.h"
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -73,7 +75,7 @@ static GIOStatus	g_io_unix_write		(GIOCh
 						 gsize        *bytes_written,
 						 GError      **err);
 static GIOStatus	g_io_unix_seek		(GIOChannel   *channel,
-						 glong         offset,
+						 gint64        offset,
 						 GSeekType     type,
 						 GError      **err);
 static GIOStatus	g_io_unix_close		(GIOChannel   *channel,
@@ -251,12 +253,13 @@ g_io_unix_write (GIOChannel  *channel, 
 
 static GIOStatus
 g_io_unix_seek (GIOChannel *channel,
-		glong       offset, 
+		gint64      offset, 
 		GSeekType   type,
                 GError    **err)
 {
   GIOUnixChannel *unix_channel = (GIOUnixChannel *)channel;
   int whence;
+  off_t tmp_offset;
   off_t result;
 
   switch (type)
@@ -275,7 +278,16 @@ g_io_unix_seek (GIOChannel *channel,
       g_assert_not_reached ();
     }
 
-  result = lseek (unix_channel->fd, offset, whence);
+  tmp_offset = offset;
+  if (tmp_offset != offset)
+    {
+      g_set_error (err, G_IO_CHANNEL_ERROR,
+		   g_io_channel_error_from_errno (EINVAL),
+		   strerror (EINVAL));
+      return G_IO_STATUS_ERROR;
+    }
+  
+  result = lseek (unix_channel->fd, tmp_offset, whence);
 
   if (result < 0)
     {
Index: glib/giowin32.c
===================================================================
RCS file: /cvs/gnome/glib/glib/giowin32.c,v
retrieving revision 1.39
diff -u -p -r1.39 giowin32.c
--- glib/giowin32.c	2001/12/22 08:29:05	1.39
+++ glib/giowin32.c	2002/02/15 16:24:19
@@ -32,6 +32,8 @@
 /* Define this to get (very) verbose logging of all channels */
 /* #define G_IO_WIN32_DEBUG */
 
+#include "config.h"
+
 #include "glib.h"
 
 #include <stdlib.h>
@@ -898,12 +900,13 @@ g_io_win32_fd_write (GIOChannel  *channe
 
 static GIOStatus
 g_io_win32_fd_seek (GIOChannel *channel,
-		    glong       offset,
+		    gint64      offset,
 		    GSeekType   type,
 		    GError    **err)
 {
   GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
   int whence;
+  off_t tmp_offset;
   off_t result;
   
   switch (type)
@@ -921,8 +924,17 @@ g_io_win32_fd_seek (GIOChannel *channel,
       whence = -1; /* Keep the compiler quiet */
       g_assert_not_reached();
     }
+
+  tmp_offset = offset;
+  if (tmp_offset != offset)
+    {
+      g_set_error (err, G_IO_CHANNEL_ERROR,
+		   g_io_channel_error_from_errno (EINVAL),
+		   strerror (EINVAL));
+      return G_IO_STATUS_ERROR;
+    }
   
-  result = lseek (win32_channel->fd, offset, whence);
+  result = lseek (win32_channel->fd, tmp_offset, whence);
   
   if (result < 0)
     {




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]