diff options
author | Eric Andersen <andersen@codepoet.org> | 2001-10-17 01:10:29 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2001-10-17 01:10:29 +0000 |
commit | cad937c12d93653ed1bf548eed8fc1a178f991d8 (patch) | |
tree | 596ff2c1200152a75e12fc14ba1213b8e2c57f2c | |
parent | b8fa5e71e482c61ff5accde74f5b552c6300b442 (diff) |
This commit makes large file support actually work (when enabled in
the config file). I've tested this and it works for me.
-Erik
-rw-r--r-- | Makefile | 5 | ||||
-rw-r--r-- | libc/stdio/Makefile | 14 | ||||
-rw-r--r-- | libc/stdio/stdio.c | 34 | ||||
-rw-r--r-- | libc/sysdeps/linux/common/Makefile | 2 | ||||
-rw-r--r-- | libc/sysdeps/linux/common/open64.c | 48 | ||||
-rw-r--r-- | libc/sysdeps/linux/common/statfix64.c | 51 | ||||
-rw-r--r-- | libc/sysdeps/linux/common/statfix64.h | 41 | ||||
-rw-r--r-- | libc/sysdeps/linux/common/syscalls.c | 110 |
8 files changed, 287 insertions, 18 deletions
@@ -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)) diff --git a/libc/stdio/Makefile b/libc/stdio/Makefile index 42983512e..c837ae3a1 100644 --- a/libc/stdio/Makefile +++ b/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 \ diff --git a/libc/stdio/stdio.c b/libc/stdio/stdio.c index e67408d12..f87a69416 100644 --- a/libc/stdio/stdio.c +++ b/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 + diff --git a/libc/sysdeps/linux/common/Makefile b/libc/sysdeps/linux/common/Makefile index 34e4de015..93c25e1ae 100644 --- a/libc/sysdeps/linux/common/Makefile +++ b/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 diff --git a/libc/sysdeps/linux/common/open64.c b/libc/sysdeps/linux/common/open64.c new file mode 100644 index 000000000..62deddcb4 --- /dev/null +++ b/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__ */ + diff --git a/libc/sysdeps/linux/common/statfix64.c b/libc/sysdeps/linux/common/statfix64.c new file mode 100644 index 000000000..23759d754 --- /dev/null +++ b/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__ */ + diff --git a/libc/sysdeps/linux/common/statfix64.h b/libc/sysdeps/linux/common/statfix64.h new file mode 100644 index 000000000..acf9e8440 --- /dev/null +++ b/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 + diff --git a/libc/sysdeps/linux/common/syscalls.c b/libc/sysdeps/linux/common/syscalls.c index c4a5c0135..047ec801c 100644 --- a/libc/sysdeps/linux/common/syscalls.c +++ b/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__ */ + + |