This is the mail archive of the newlib@sourceware.org mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

fix ftello(stdin) when __LARGE64_FILES


On cygwin, where __LARGE64_FILES is default, this program exposes a bug in 64-
bit support of ftello/fgetpos:

$ cat foo.c
#include <stdio.h>
#include <unistd.h>

int main(int argc, char **argv)
{
   fpos_t pos;
   FILE *f;
   if (argc > 2)
      f = freopen(argv[1], "r", stdin);
   else if (argc > 1)
      f = fopen(argv[1], "r");
   else
      f = stdin;
   getc(f);
   printf("ftell:%d ", (int) ftell(f));
   printf("ftello:%d ", (int) ftello(f));
   fgetpos(f, &pos);
   printf("fgetpos:%d ", (int) pos);
   printf("lseek:%d ", (int) lseek(fileno(f), 0, SEEK_CUR));
   return 0;
}
$ echo hello > blah
$ ./foo < blah
ftell:1 ftello:-1 fgetpos:-1 lseek:1 

The problem here was that ftello is mapped to ftello64 in cygwin, but ftello64 
checks only the field fp->_seek64 when determining if the file is seekable.  
Unless the creation of std{in,out,err} also defaults to allowing 64-bit access, 
the _seek64 field is left NULL, explaining why ftello and ftell disagreed.

$ ./foo blah 1
ftell:1 ftello:1 fgetpos:1 lseek:1 
$ ./foo blah
ftell:1 ftello:1 fgetpos:1 lseek:1 

The use of freopen(NULL) or of a different FILE than stdin both worked around 
the problem, proving that it is localized to the initial setup of stdin.

Meanwhile, why is there __sseek64_r, but not __sseek_r?  I think there is a 
reentrancy problem here - if you use something other than _REENT, it looks like 
any FILE operation such as fseek that invokes _lseek_r under the hood is not 
preserving errno correctly to the alternate struct _reent.  I'll attempt a 
patch for this in a followup mail.

OK to apply?

2007-04-30  Eric Blake  <ebb9@byu.net>

	* libc/stdio64/local64.h: Delete, move contents to...
	* libc/stdio/local.h: ...here.
	* libc/stdio64/fdopen64.c: Update includes.
	* libc/stdio64/fopen64.c: Likewise.
	* libc/stdio64/freopen64.c: Likewise.
	* libc/stdio64/fseeko64.c: Likewise.
	* libc/stdio64/ftello64.c: Likewise.
	* libc/stdio/findfp.c (std) [__LARGE64_FILES]: Open stdin, stdout,
	and stderr with 64-bit offset.
	* libc/stdio/fseek.c (_fseek_r): Avoid compile warning.
	* libc/stdio/makebuf.c (__smakebuf_r): Likewise.
	* libc/stdio/mktemp.c (_gettemp): Likewise.

Index: libc/stdio/findfp.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/findfp.c,v
retrieving revision 1.17
diff -u -b -r1.17 findfp.c
--- libc/stdio/findfp.c	26 Sep 2006 21:22:19 -0000	1.17
+++ libc/stdio/findfp.c	30 Apr 2007 14:25:48 -0000
@@ -52,7 +52,13 @@
   ptr->_lbfsize = 0;
   ptr->_cookie = ptr;
   ptr->_read = __sread;
+#ifndef __LARGE64_FILES
   ptr->_write = __swrite;
+#else /* __LARGE64_FILES */
+  ptr->_write = __swrite64;
+  ptr->_seek64 = __sseek64;
+  ptr->_flags |= __SL64;
+#endif /* __LARGE64_FILES */
   ptr->_seek = __sseek;
   ptr->_close = __sclose;
 #if !defined(__SINGLE_THREAD__) && !defined(_REENT_SMALL)
Index: libc/stdio/fseek.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/fseek.c,v
retrieving revision 1.15
diff -u -b -r1.15 fseek.c
--- libc/stdio/fseek.c	15 Mar 2007 18:40:48 -0000	1.15
+++ libc/stdio/fseek.c	30 Apr 2007 14:25:48 -0000
@@ -126,7 +126,11 @@
   _fpos_t target;
   _fpos_t curoff = 0;
   size_t n;
+#ifdef __USE_INTERNAL_STAT64
+  struct stat64 st;
+#else
   struct stat st;
+#endif
   int havepos;
 
   /* Make sure stdio is set up.  */
Index: libc/stdio/local.h
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/local.h,v
retrieving revision 1.20
diff -u -b -r1.20 local.h
--- libc/stdio/local.h	15 Mar 2007 21:32:13 -0000	1.20
+++ libc/stdio/local.h	30 Apr 2007 14:25:48 -0000
@@ -46,6 +46,14 @@
 extern int    _EXFUN(_fwalk_reent,(struct _reent *, int (*)(struct _reent *, 
FILE *)));
 struct _glue * _EXFUN(__sfmoreglue,(struct _reent *,int n));
 
+#ifdef __LARGE64_FILES
+extern _fpos64_t _EXFUN(__sseek64,(void *, _fpos64_t, int));
+extern _fpos64_t _EXFUN(__sseek64_r,(struct _reent *, void *, _fpos64_t, int));
+extern _READ_WRITE_RETURN_TYPE _EXFUN(__swrite64,(void *, char const *, int));
+extern _READ_WRITE_RETURN_TYPE _EXFUN(__swrite64_r,(struct _reent *, void *,
+                                      char const *, int));
+#endif
+
 /* Called by the main entry point fns to ensure stdio has been initialized.  */
 
 #ifdef _REENT_SMALL
Index: libc/stdio/makebuf.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/makebuf.c,v
retrieving revision 1.7
diff -u -b -r1.7 makebuf.c
--- libc/stdio/makebuf.c	15 Mar 2007 18:40:48 -0000	1.7
+++ libc/stdio/makebuf.c	30 Apr 2007 14:25:48 -0000
@@ -41,7 +41,11 @@
 {
   register size_t size, couldbetty;
   register _PTR p;
+#ifdef __USE_INTERNAL_STAT64
+  struct stat64 st;
+#else
   struct stat st;
+#endif
 
   if (fp->_flags & __SNBF)
     {
Index: libc/stdio/mktemp.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/mktemp.c,v
retrieving revision 1.8
diff -u -b -r1.8 mktemp.c
--- libc/stdio/mktemp.c	23 Apr 2004 20:01:55 -0000	1.8
+++ libc/stdio/mktemp.c	30 Apr 2007 14:25:48 -0000
@@ -108,7 +108,11 @@
        register int *doopen)
 {
   register char *start, *trv;
+#ifdef __USE_INTERNAL_STAT64
+  struct stat64 sbuf;
+#else
   struct stat sbuf;
+#endif
   unsigned int pid;
 
   pid = _getpid_r (ptr);
Index: libc/stdio64/fdopen64.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio64/fdopen64.c,v
retrieving revision 1.3
diff -u -b -r1.3 fdopen64.c
--- libc/stdio64/fdopen64.c	25 Mar 2004 22:29:17 -0000	1.3
+++ libc/stdio64/fdopen64.c	30 Apr 2007 14:25:48 -0000
@@ -28,7 +28,7 @@
 
 #include <stdio.h>
 #include <errno.h>
-#include "local64.h"
+#include "local.h"
 #include <_syslist.h>
 #include <sys/lock.h>
 
Index: libc/stdio64/fopen64.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio64/fopen64.c,v
retrieving revision 1.6
diff -u -b -r1.6 fopen64.c
--- libc/stdio64/fopen64.c	11 Jun 2004 20:37:10 -0000	1.6
+++ libc/stdio64/fopen64.c	30 Apr 2007 14:25:48 -0000
@@ -66,7 +66,7 @@
 
 #include <stdio.h>
 #include <errno.h>
-#include "local64.h"
+#include "local.h"
 #ifdef __CYGWIN__
 #include <fcntl.h>
 #endif
Index: libc/stdio64/freopen64.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio64/freopen64.c,v
retrieving revision 1.14
diff -u -b -r1.14 freopen64.c
--- libc/stdio64/freopen64.c	16 Mar 2007 20:05:10 -0000	1.14
+++ libc/stdio64/freopen64.c	30 Apr 2007 14:25:48 -0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1990, 2006 The Regents of the University of California.
+ * Copyright (c) 1990 The Regents of the University of California.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted
@@ -78,7 +78,7 @@
 #include <fcntl.h>
 #include <stdlib.h>
 #include <sys/lock.h>
-#include "local64.h"
+#include "local.h"
 
 /*
  * Re-direct an existing, open (probably) file to some other file.
Index: libc/stdio64/fseeko64.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio64/fseeko64.c,v
retrieving revision 1.9
diff -u -b -r1.9 fseeko64.c
--- libc/stdio64/fseeko64.c	16 Mar 2007 20:05:10 -0000	1.9
+++ libc/stdio64/fseeko64.c	30 Apr 2007 14:25:48 -0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1990, 2007 The Regents of the University of California.
+ * Copyright (c) 1990 The Regents of the University of California.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted
@@ -86,7 +86,7 @@
 #include <errno.h>
 #include <sys/types.h>
 #include <sys/stat.h>
-#include "local64.h"
+#include "local.h"
 
 #define	POS_ERR	(-(_fpos64_t)1)
 
Index: libc/stdio64/ftello64.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio64/ftello64.c,v
retrieving revision 1.5
diff -u -b -r1.5 ftello64.c
--- libc/stdio64/ftello64.c	26 Sep 2006 21:22:19 -0000	1.5
+++ libc/stdio64/ftello64.c	30 Apr 2007 14:25:48 -0000
@@ -80,7 +80,7 @@
 #include <stdio.h>
 #include <errno.h>
 
-#include "local64.h"
+#include "local.h"
 
 #ifdef __LARGE64_FILES
 
Index: libc/stdio64/local64.h
===================================================================
RCS file: libc/stdio64/local64.h
diff -N libc/stdio64/local64.h
--- libc/stdio64/local64.h	22 Aug 2003 18:52:25 -0000	1.3
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,16 +0,0 @@
-/*
- * Information local to this implementation of stdio64,
- * in particular, macros and private variables.
- */
-
-#include "local.h"
-
-#ifdef __LARGE64_FILES
-extern _fpos64_t _EXFUN(__sseek64,(void *, _fpos64_t, int));
-extern _fpos64_t _EXFUN(__sseek64_r,(struct _reent *, void *, _fpos64_t, int));
-extern _fpos64_t _EXFUN(__sseek64_error,(void *, _fpos64_t, int));
-extern _READ_WRITE_RETURN_TYPE _EXFUN(__swrite64,(void *, char const *, int));
-extern _READ_WRITE_RETURN_TYPE _EXFUN(__swrite64_r,(struct _reent *, void *, 
-                                      char const *, int));
-#endif
-




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]