[PATCH] support kernels without __ARCH_WANT_SYSCALL_OFF_T

Mark Salter msalter at redhat.com
Thu Apr 26 14:17:38 UTC 2012


---
 ldso/include/dl-syscall.h                   |   18 ++++++++++++++++-
 libc/sysdeps/linux/common/__syscall_fcntl.c |    8 +++++++
 libc/sysdeps/linux/common/fstatfs.c         |   27 ++++++++++++++++++++++++++
 libc/sysdeps/linux/common/ftruncate.c       |    7 ++++++
 libc/sysdeps/linux/common/stat.c            |    3 ++
 libc/sysdeps/linux/common/statfs.c          |   28 +++++++++++++++++++++++++++
 libc/sysdeps/linux/common/truncate.c        |    7 ++++++
 7 files changed, 97 insertions(+), 1 deletions(-)

diff --git a/ldso/include/dl-syscall.h b/ldso/include/dl-syscall.h
index 547dad1..7549204 100644
--- a/ldso/include/dl-syscall.h
+++ b/ldso/include/dl-syscall.h
@@ -23,7 +23,7 @@ extern int _dl_errno;
 /* 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... */
-#if defined(__sparc_v9__) && (__WORDSIZE == 64)
+#if !defined(__NR_stat) || (defined(__sparc_v9__) && (__WORDSIZE == 64))
 #define kernel_stat64 stat
 #else
 #define kernel_stat stat
@@ -35,6 +35,7 @@ extern int _dl_errno;
 #define	S_ISUID		04000	/* Set user ID on execution.  */
 #define	S_ISGID		02000	/* Set group ID on execution.  */
 
+#define AT_FDCWD	-100
 
 /* Here are the definitions for some syscalls that are used
    by the dynamic linker.  The idea is that we want to be able
@@ -64,11 +65,26 @@ static __always_inline _syscall3(unsigned long, _dl_read, int, fd,
 static __always_inline _syscall3(int, _dl_mprotect, const void *, addr,
                         unsigned long, len, int, prot)
 
+#if defined(__NR_stat)
 #define __NR__dl_stat __NR_stat
 static __always_inline _syscall2(int, _dl_stat, const char *, file_name,
                         struct stat *, buf)
+#elif defined(__NR_fstatat64)
+#define __NR__dl_fstatat64 __NR_fstatat64
+static __always_inline _syscall4(int, _dl_fstatat64, int, dirfd, const char *, fn,
+			struct stat *, stat, int, flags)
+static __always_inline int
+_dl_stat(const char *fn, struct stat *stat)
+{
+	return _dl_fstatat64(AT_FDCWD, fn, stat, 0);
+}
+#endif
 
+#if defined(__NR_fstat)
 #define __NR__dl_fstat __NR_fstat
+#elif defined(__NR_fstat64)
+#define __NR__dl_fstat __NR_fstat64
+#endif
 static __always_inline _syscall2(int, _dl_fstat, int, fd, struct stat *, buf)
 
 #define __NR__dl_munmap __NR_munmap
diff --git a/libc/sysdeps/linux/common/__syscall_fcntl.c b/libc/sysdeps/linux/common/__syscall_fcntl.c
index 6d4c339..4fcd64a 100644
--- a/libc/sysdeps/linux/common/__syscall_fcntl.c
+++ b/libc/sysdeps/linux/common/__syscall_fcntl.c
@@ -38,7 +38,11 @@ int __fcntl_nocancel (int fd, int cmd, ...)
 #  endif
 	}
 # endif
+# if defined __NR_fcntl
 	return INLINE_SYSCALL (fcntl, 3, fd, cmd, arg);
+# elif defined __NR_fcntl64
+	return INLINE_SYSCALL (fcntl64, 3, fd, cmd, arg);
+# endif
 }
 libc_hidden_def(__fcntl_nocancel)
 
@@ -81,7 +85,11 @@ int __libc_fcntl (int fd, int cmd, ...)
 #  endif
 	}
 # endif
+# if defined __NR_fcntl
 	return INLINE_SYSCALL (fcntl, 3, fd, cmd, arg);
+# elif defined __NR_fcntl64
+	return INLINE_SYSCALL (fcntl64, 3, fd, cmd, arg);
+# endif
 #endif
 }
 libc_hidden_def(__libc_fcntl)
diff --git a/libc/sysdeps/linux/common/fstatfs.c b/libc/sysdeps/linux/common/fstatfs.c
index fa0024a..79805d1 100644
--- a/libc/sysdeps/linux/common/fstatfs.c
+++ b/libc/sysdeps/linux/common/fstatfs.c
@@ -22,9 +22,36 @@ extern int __REDIRECT_NTH (fstatfs, (int __fildes, struct statfs *__buf),
 # endif
 #endif
 
+#ifdef __NR_fstatfs
 extern __typeof(fstatfs) __libc_fstatfs attribute_hidden;
 #define __NR___libc_fstatfs __NR_fstatfs
 _syscall2(int, __libc_fstatfs, int, fd, struct statfs *, buf)
+#elif defined __NR_fstatfs64
+#define __NR___syscall_fstatfs64 __NR_fstatfs64
+_syscall3(int, __syscall_fstatfs64, unsigned int, fd, size_t, sz, struct statfs64 *, buf)
+int __libc_fstatfs(int fd, struct statfs *buf)
+{
+	struct statfs64 st;
+	int err;
+
+	err = __syscall_fstatfs64(fd, sizeof(st), &st);
+	if (err)
+		return err;
+
+	buf->f_type = st.f_type;
+	buf->f_bsize = st.f_bsize;
+	buf->f_blocks = st.f_blocks;
+	buf->f_bfree = st.f_bfree;
+	buf->f_bavail = st.f_bavail;
+	buf->f_files = st.f_files;
+	buf->f_ffree = st.f_ffree;
+	buf->f_fsid = st.f_fsid;
+	buf->f_namelen = st.f_namelen;
+	buf->f_frsize = st.f_frsize;
+
+	return 0;
+}
+#endif
 
 #if defined __UCLIBC_LINUX_SPECIFIC__
 weak_alias(__libc_fstatfs,fstatfs)
diff --git a/libc/sysdeps/linux/common/ftruncate.c b/libc/sysdeps/linux/common/ftruncate.c
index 3bdef3f..a2bb016 100644
--- a/libc/sysdeps/linux/common/ftruncate.c
+++ b/libc/sysdeps/linux/common/ftruncate.c
@@ -11,5 +11,12 @@
 #include <unistd.h>
 
 
+#ifdef __NR_ftruncate
 _syscall2(int, ftruncate, int, fd, __off_t, length)
+#elif defined __NR_truncate64
+int ftruncate(int fd, __off_t length)
+{
+	return ftruncate64(fd, length);
+}
+#endif
 libc_hidden_def(ftruncate)
diff --git a/libc/sysdeps/linux/common/stat.c b/libc/sysdeps/linux/common/stat.c
index 829f35a..bf41825 100644
--- a/libc/sysdeps/linux/common/stat.c
+++ b/libc/sysdeps/linux/common/stat.c
@@ -9,6 +9,7 @@
 
 #include <sys/syscall.h>
 #include <unistd.h>
+#include <fcntl.h>
 #include <sys/stat.h>
 #include "xstatconv.h"
 
@@ -28,6 +29,8 @@ int stat(const char *file_name, struct stat *buf)
 	if (result == 0) {
 		__xstat32_conv(&kbuf, buf);
 	}
+#elif defined __NR_fstatat64
+	result = fstatat(AT_FDCWD, file_name, buf, 0);
 #else
 	struct kernel_stat kbuf;
 
diff --git a/libc/sysdeps/linux/common/statfs.c b/libc/sysdeps/linux/common/statfs.c
index d24bc9d..cae328d 100644
--- a/libc/sysdeps/linux/common/statfs.c
+++ b/libc/sysdeps/linux/common/statfs.c
@@ -12,9 +12,37 @@
 #include <sys/param.h>
 #include <sys/vfs.h>
 
+#if defined __NR_statfs
 extern __typeof(statfs) __libc_statfs attribute_hidden;
 #define __NR___libc_statfs __NR_statfs
 _syscall2(int, __libc_statfs, const char *, path, struct statfs *, buf)
+#elif defined __NR_statfs64
+#define __NR___syscall_statfs64 __NR_statfs64
+_syscall2(int, __syscall_statfs64, const char *, path, struct statfs64 *, buf)
+
+int __libc_statfs(const char *path, struct statfs *buf)
+{
+	struct statfs64 st;
+	int err;
+
+	err = __syscall_statfs64(path, &st);
+	if (err)
+		return err;
+
+	buf->f_type = st.f_type;
+	buf->f_bsize = st.f_bsize;
+	buf->f_blocks = st.f_blocks;
+	buf->f_bfree = st.f_bfree;
+	buf->f_bavail = st.f_bavail;
+	buf->f_files = st.f_files;
+	buf->f_ffree = st.f_ffree;
+	buf->f_fsid = st.f_fsid;
+	buf->f_namelen = st.f_namelen;
+	buf->f_frsize = st.f_frsize;
+
+	return 0;
+}
+#endif
 
 #if defined __UCLIBC_LINUX_SPECIFIC__ || defined __UCLIBC_HAS_THREADS_NATIVE__
 /* statfs is used by NPTL, so it must exported in case */
diff --git a/libc/sysdeps/linux/common/truncate.c b/libc/sysdeps/linux/common/truncate.c
index 2331bdd..596acb7 100644
--- a/libc/sysdeps/linux/common/truncate.c
+++ b/libc/sysdeps/linux/common/truncate.c
@@ -11,5 +11,12 @@
 #include <unistd.h>
 
 
+#ifdef __NR_truncate
 _syscall2(int, truncate, const char *, path, __off_t, length)
+#elif defined(__NR_truncate64)
+int truncate(const char *path, __off_t length)
+{
+	return truncate64(path, length);
+}
+#endif
 libc_hidden_def(truncate)
-- 
1.7.9.1



More information about the uClibc mailing list