summaryrefslogtreecommitdiff
path: root/libc
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2001-10-17 01:10:29 +0000
committerEric Andersen <andersen@codepoet.org>2001-10-17 01:10:29 +0000
commitcad937c12d93653ed1bf548eed8fc1a178f991d8 (patch)
tree596ff2c1200152a75e12fc14ba1213b8e2c57f2c /libc
parentb8fa5e71e482c61ff5accde74f5b552c6300b442 (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
Diffstat (limited to 'libc')
-rw-r--r--libc/stdio/Makefile14
-rw-r--r--libc/stdio/stdio.c34
-rw-r--r--libc/sysdeps/linux/common/Makefile2
-rw-r--r--libc/sysdeps/linux/common/open64.c48
-rw-r--r--libc/sysdeps/linux/common/statfix64.c51
-rw-r--r--libc/sysdeps/linux/common/statfix64.h41
-rw-r--r--libc/sysdeps/linux/common/syscalls.c110
7 files changed, 282 insertions, 18 deletions
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__ */
+
+