Browse Source

This commit makes large file support actually work (when enabled in
the config file). I've tested this and it works for me.
-Erik

Eric Andersen 22 years ago
parent
commit
cad937c12d

+ 5 - 0
Makefile

@@ -166,6 +166,11 @@ uClibc_config.h: Makefile Config
 	    echo "#undef __UCLIBC_USE_UNIFIED_SYSCALL__" >> uClibc_config.h ; \
 	fi
 	@echo "#define C_SYMBOL_PREFIX "\""$(C_SYMBOL_PREFIX)"\" >> uClibc_config.h
+	@if [ "$(DOLFS)" = "true" ] ; then \
+	    echo "#define __UCLIBC_HAVE_LFS__ 1" >> uClibc_config.h ; \
+	else \
+	    echo "#undef __UCLIBC_HAVE_LFS__" >> uClibc_config.h ; \
+	fi
 
 subdirs: $(patsubst %, _dir_%, $(DIRS))
 

+ 6 - 8
libc/stdio/Makefile

@@ -24,14 +24,12 @@ TOPDIR=../../
 include $(TOPDIR)Rules.mak
 
 MSRC=stdio.c
-MOBJ=_stdio_init.o \
-     _alloc_stdio_buffer.o _free_stdio_buffer_of_file.o _free_stdio_stream.o \
-     clearerr.o feof.o ferror.o fileno.o \
-     setbuffer.o setvbuf.o setbuf.o setlinebuf.o \
-     fclose.o _fopen.o fopen.o freopen.o fdopen.o fflush.o fsfopen.o \
-     fseek.o rewind.o ftell.o fgetpos.o fsetpos.o \
-     fputc.o fgetc.o fgets.o gets.o fputs.o puts.o ungetc.o \
-     fread.o fwrite.o getchar.o putchar.o _uClibc_fwrite.o _uClibc_fread.o
+MOBJ=_stdio_init.o _alloc_stdio_buffer.o _free_stdio_buffer_of_file.o \
+     _free_stdio_stream.o clearerr.o feof.o ferror.o fileno.o setbuffer.o \
+     setvbuf.o setbuf.o setlinebuf.o fclose.o _fopen.o fopen.o freopen.o \
+     fdopen.o fflush.o fsfopen.o fseek.o rewind.o ftell.o fgetpos.o fsetpos.o \
+     fputc.o fgetc.o fgets.o gets.o fputs.o puts.o ungetc.o fread.o fwrite.o \
+     getchar.o putchar.o _uClibc_fwrite.o _uClibc_fread.o fopen64.o
 
 MSRC2=printf.c
 MOBJ2=printf.o sprintf.o fprintf.o vprintf.o vsprintf.o vfprintf.o snprintf.o \

+ 25 - 9
libc/stdio/stdio.c

@@ -53,7 +53,8 @@ extern off_t _uClibc_fread(unsigned char *buf, off_t bytes, FILE *fp);
 
 /* Used internally to actually open files */
 extern FILE *__fopen __P((__const char *__restrict __filename, int __fd,
-	                FILE *__restrict __stream, __const char *__restrict __mode));
+	                FILE *__restrict __stream, __const char *__restrict __mode,
+			int extra_modes));
 
 /* Note: This def of READING is ok since 1st ungetc puts in buf. */
 #define READING(fp) (fp->bufstart < fp->bufread)
@@ -655,11 +656,12 @@ static __inline FILE *_alloc_stdio_stream(void)
 	return fp;
 }
 
-FILE *__fopen(fname, fd, fp, mode)
+FILE *__fopen(fname, fd, fp, mode, extra_modes)
 const char *fname;
 int fd;
 FILE *fp;
 const char *mode;
+int extra_modes;
 {
 	FILE *nfp;
 	unsigned char *p;
@@ -671,13 +673,13 @@ const char *mode;
 	/* Parse the mode string arg. */
 	switch (*mode++) {
 		case 'r':				/* read */
-			open_mode = O_RDONLY;
+			open_mode = O_RDONLY | extra_modes;
 			break;
 		case 'w':				/* write (create or truncate)*/
-			open_mode = (O_WRONLY | O_CREAT | O_TRUNC);
+			open_mode = (O_WRONLY | O_CREAT | O_TRUNC | extra_modes);
 			break;
 		case 'a':				/* write (create or append) */
-			open_mode = (O_WRONLY | O_CREAT | O_APPEND);
+			open_mode = (O_WRONLY | O_CREAT | O_APPEND | extra_modes);
 			break;
 		default:				/* illegal mode */
 			__set_errno(EINVAL);
@@ -958,7 +960,7 @@ FILE *fp;
 FILE *fopen(const char *__restrict filename,
 			const char *__restrict mode)
 {
-	return __fopen(filename, -1, NULL, mode);
+	return __fopen(filename, -1, NULL, mode, 0);
 }
 #endif
 
@@ -974,7 +976,7 @@ FILE *freopen(__const char *__restrict filename,
 	fp->mode &= (__MODE_FREEFIL | __MODE_FREEBUF); /* Reset the FILE modes. */
 	fp->mode |= _IOFBF;
 
-	return __fopen(filename, -1, fp, mode);
+	return __fopen(filename, -1, fp, mode, 0);
 }
 #endif
 
@@ -986,7 +988,7 @@ FILE *fsfopen(__const char *__restrict filename,
 	fp->bufstart = fp->unbuf;
 	fp->bufend = fp->unbuf + sizeof(fp->unbuf);
 
-	return __fopen(filename, -1, fp, mode);
+	return __fopen(filename, -1, fp, mode, 0);
 }
 #endif
 
@@ -994,7 +996,7 @@ FILE *fsfopen(__const char *__restrict filename,
 #undef fdopen
 FILE *fdopen(int fd, __const char *mode)
 {
-	return __fopen(NULL, fd, NULL, mode);
+	return __fopen(NULL, fd, NULL, mode, 0);
 }
 #endif
 
@@ -1074,3 +1076,17 @@ int fsetpos(FILE *fp, __const fpos_t *pos)
 	return EOF;
 }
 #endif
+
+#ifdef L_fopen64
+#ifdef __UCLIBC_HAVE_LFS__
+#ifndef O_LARGEFILE
+#define O_LARGEFILE	0100000
+#endif
+FILE *fopen64(const char *__restrict filename,
+			const char *__restrict mode)
+{
+	return __fopen(filename, -1, NULL, mode, O_LARGEFILE);
+}
+#endif /* __UCLIBC_HAVE_LFS__ */
+#endif
+

+ 1 - 1
libc/sysdeps/linux/common/Makefile

@@ -27,7 +27,7 @@ include $(TOPDIR)Rules.mak
 CSRC=	waitpid.c kernel_version.c statfix.c getdnnm.c gethstnm.c \
 	mkfifo.c setegid.c wait.c errno.c getpagesize.c seteuid.c \
 	wait3.c setpgrp.c getdtablesize.c create_module.c ptrace.c \
-	cmsg_nxthdr.c
+	cmsg_nxthdr.c open64.c statfix64.c
 COBJS=$(patsubst %.c,%.o, $(CSRC))
 
 MSRC=syscalls.c

+ 48 - 0
libc/sysdeps/linux/common/open64.c

@@ -0,0 +1,48 @@
+/* Copyright (C) 1991, 1995-1997, 1999, 2000 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+
+#include <features.h>
+#include <fcntl.h>
+#include <stdarg.h>
+
+#ifndef O_LARGEFILE
+#define O_LARGEFILE	0100000
+#endif
+
+#ifdef __UCLIBC_HAVE_LFS__
+
+/* Open FILE with access OFLAG.  If OFLAG includes O_CREAT,
+   a third argument is the file protection.  */
+int open64 (const char *file, int oflag, ...)
+{
+  int mode = 0;
+
+  if (oflag & O_CREAT)
+    {
+      va_list arg;
+      va_start (arg, oflag);
+      mode = va_arg (arg, int);
+      va_end (arg);
+    }
+
+  return open(file, oflag | O_LARGEFILE, mode);
+}
+
+#endif /* __UCLIBC_HAVE_LFS__ */
+

+ 51 - 0
libc/sysdeps/linux/common/statfix64.c

@@ -0,0 +1,51 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Convert from the kernel's version of struct stat to libc's version
+ *
+ * Copyright (C) 2000, 2001 by Lineo, inc.  
+ * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+
+/* Pull in whatever this particular arch's kernel thinks the kernel version of
+ * struct stat should look like.  It turns out that each arch has a different
+ * opinion on the subject.  Then pull in libc's version of struct stat... */
+#include "statfix64.h"
+
+#ifdef __UCLIBC_HAVE_LFS__
+
+/* Convert from the kernel's version of struct stat to libc's version  */
+void statfix64(struct libc_stat64 *libcstat, struct kernel_stat64 *kstat)
+{
+	libcstat->st_dev = kstat->st_dev;
+	libcstat->st_ino = kstat->st_ino;
+	libcstat->st_mode = kstat->st_mode;
+	libcstat->st_nlink = kstat->st_nlink;
+	libcstat->st_uid = kstat->st_uid;
+	libcstat->st_gid = kstat->st_gid;
+	libcstat->st_rdev = kstat->st_rdev;
+	libcstat->st_size = kstat->st_size;
+	libcstat->st_blksize = kstat->st_blksize;
+	libcstat->st_blocks = kstat->st_blocks;
+	libcstat->st_atime = kstat->st_atime;
+	libcstat->st_mtime = kstat->st_mtime;
+	libcstat->st_ctime = kstat->st_ctime;
+}
+
+#endif /* __UCLIBC_HAVE_LFS__ */
+

+ 41 - 0
libc/sysdeps/linux/common/statfix64.h

@@ -0,0 +1,41 @@
+#ifndef STATFIX_H
+#define STATFIX_H
+
+#include <features.h>
+
+#define	_FILE_OFFSET_BITS   64
+#define __USE_FILE_OFFSET64
+#define __USE_LARGEFILE64
+
+#ifdef __UCLIBC_HAVE_LFS__
+
+#include <sys/types.h>
+
+/* Pull in whatever this particular arch's kernel thinks the kernel version of
+ * struct stat should look like.  It turns out that each arch has a different
+ * opinion on the subject, and different kernel revs use different names... */
+#define stat kernel_stat
+#define new_stat kernel_stat
+#define stat64 kernel_stat64
+#define new_stat64 kernel_stat64
+#include <asm/stat.h> 
+#undef new_stat64
+#undef stat64
+#undef new_stat
+#undef stat
+
+
+/* Now pull in libc's version of stat */
+#define stat libc_stat
+#define stat64 libc_stat64
+#include <sys/stat.h>
+#undef stat64
+#undef stat
+
+extern void statfix64(struct libc_stat64 *libcstat, struct kernel_stat64 *kstat);
+extern int __fxstat64(int version, int fd, struct libc_stat64 * statbuf);
+
+#endif /* __UCLIBC_HAVE_LFS__ */
+
+#endif
+

+ 110 - 0
libc/sysdeps/linux/common/syscalls.c

@@ -1026,6 +1026,9 @@ loff_t llseek(int fd, loff_t offset, int whence)
 
 	return ret ? (loff_t) ret : result;
 }
+#ifdef __UCLIBC_HAVE_LFS__
+weak_alias(llseek, lseek64);
+#endif
 #endif
 
 //#define __NR_getdents         141
@@ -1221,4 +1224,111 @@ _syscall3(int, chown, const char *, path, uid_t, owner, gid_t, group);
 //#define __NR_vfork                    190
 //See sysdeps/linux/<arch>vfork.[cS] for architecture specific implementation...
 
+#ifdef __UCLIBC_HAVE_LFS__
+
+//#define __NR_truncate64         193
+#ifdef L_truncate64
+#include <unistd.h>
+_syscall2(int, truncate64, const char *, path, __off64_t, length);
+#endif
+
+//#define __NR_ftruncate64        194
+#ifdef L_ftruncate64
+#include <unistd.h>
+_syscall2(int, ftruncate64, int, fd, __off64_t, length);
+#endif
+
+
+//#define __NR_stat64             195
+#ifdef L___stat64
+#include <unistd.h>
+#include "statfix64.h"
+#define __NR___stat64	__NR_stat64
+#ifdef __STR_NR_stat64
+#define __STR_NR___stat64	__STR_NR_stat64
+#endif
+extern int __stat64(const char *file_name, struct kernel_stat64 *buf);
+_syscall2(int, __stat64, const char *, file_name, struct kernel_stat64 *, buf);
+
+int __xstat64(int version, const char * file_name, struct libc_stat64 * cstat)
+{
+	struct kernel_stat64 kstat;
+	int result = __stat64(file_name, &kstat);
+
+	if (result == 0) { 
+		statfix64(cstat, &kstat);
+	}
+	return result;
+}
+
+int stat64(const char *file_name, struct libc_stat64 *buf)
+{
+	return(__xstat64(0, file_name, buf));
+}
+#endif
+
+//#define __NR_lstat64            196
+#ifdef L___lstat64
+#include <unistd.h>
+#include "statfix64.h"
+#define __NR___lstat64	__NR_lstat64
+#ifdef __STR_NR_lstat64
+#define __STR_NR___lstat64	__STR_NR_lstat64
+#endif
+extern int __lstat64(const char *file_name, struct kernel_stat64 *buf);
+_syscall2(int, __lstat64, const char *, file_name, struct kernel_stat64 *, buf);
+
+int __lxstat64(int version, const char * file_name, struct libc_stat64 * cstat)
+{
+	struct kernel_stat64 kstat;
+	int result = __lstat64(file_name, &kstat);
+
+	if (result == 0) { 
+		statfix64(cstat, &kstat);
+	}
+	return result;
+}
+
+int lstat64(const char *file_name, struct libc_stat64 *buf)
+{
+	return(__lxstat64(0, file_name, buf));
+}
+#endif
+
+//#define __NR_fstat64            197
+#ifdef L___fstat64
+#include <unistd.h>
+#include "statfix64.h"
+#define __NR___fstat64	__NR_fstat64
+#ifdef __STR_NR_fstat64
+#define __STR_NR___fstat64	__STR_NR_fstat64
+#endif
+extern int __fstat64(int filedes, struct kernel_stat64 *buf);
+_syscall2(int, __fstat64, int, filedes, struct kernel_stat64 *, buf);
+
+int __fxstat64(int version, int fd, struct libc_stat64 * cstat)
+{
+	struct kernel_stat64 kstat;
+	int result = __fstat64(fd, &kstat);
+
+	if (result == 0) { 
+		statfix64(cstat, &kstat);
+	}
+	return result;
+}
+
+int fstat64(int filedes, struct libc_stat64 *buf)
+{
+	return(__fxstat64(0, filedes, buf));
+}
+#endif
+
+
+//#define __NR_getdents64         220
+//#define __NR_fcntl64            221
+
+
+#endif /* __UCLIBC_HAVE_LFS__ */
+
+