[PATCH v2 43/46] open-wrapper: Use a wrapper for the open() symbol
Markos Chandras
markos.chandras at gmail.com
Mon Nov 26 14:24:25 UTC 2012
From: Markos Chandras <markos.chandras at imgtec.com>
Internal libc operations, gcc and other packages require for libc to
define an open() symbol. In case the arch does not have NR_open, we define
this symbol to be a wrapper to the openat syscall.
Signed-off-by: Markos Chandras <markos.chandras at imgtec.com>
---
libc/sysdeps/linux/common/Makefile.in | 2 +-
libc/sysdeps/linux/common/open-wrapper.c | 77 ++++++++++++++++++++++++++
libc/sysdeps/linux/common/open.c | 39 -------------
libpthread/linuxthreads.old/wrapsyscall.c | 3 +-
libpthread/nptl/sysdeps/unix/sysv/linux/open.S | 8 ++-
5 files changed, 87 insertions(+), 42 deletions(-)
create mode 100644 libc/sysdeps/linux/common/open-wrapper.c
delete mode 100644 libc/sysdeps/linux/common/open.c
diff --git a/libc/sysdeps/linux/common/Makefile.in b/libc/sysdeps/linux/common/Makefile.in
index 3663e91..3e947c1 100644
--- a/libc/sysdeps/linux/common/Makefile.in
+++ b/libc/sysdeps/linux/common/Makefile.in
@@ -65,7 +65,7 @@ CSRC-$(if $(findstring yy,$(UCLIBC_LINUX_SPECIFIC)$(UCLIBC_HAS_LFS)),y) += \
# NPTL needs these internally: madvise.c
CSRC-$(findstring y,$(UCLIBC_LINUX_SPECIFIC)$(UCLIBC_HAS_THREADS_NATIVE)) += madvise.c
ifeq ($(UCLIBC_HAS_THREADS_NATIVE),y)
-CSRC- += fork.c getpid.c raise.c open.c openat.c close.c read.c write.c
+CSRC- += fork.c getpid.c raise.c openat.c close.c read.c write.c
CSRC- += $(if $(findstring =arm=,=$(TARGET_ARCH)=),vfork.c)
CSRC- += $(if $(findstring =x86_64=,=$(TARGET_ARCH)=),vfork.c)
CSRC- += $(if $(findstring =mips=y=,=$(TARGET_ARCH)=$(CONFIG_MIPS_O32_ABI)=),waitpid.c)
diff --git a/libc/sysdeps/linux/common/open-wrapper.c b/libc/sysdeps/linux/common/open-wrapper.c
new file mode 100644
index 0000000..2377843
--- /dev/null
+++ b/libc/sysdeps/linux/common/open-wrapper.c
@@ -0,0 +1,77 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * open() for uClibc
+ *
+ * Copyright (C) 2000-2006 Erik Andersen <andersen at uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <sys/syscall.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <fcntl.h>
+#include <string.h>
+#include <sys/param.h>
+
+#if defined(__NR_open)
+#define __NR___syscall_open __NR_open
+static __inline__ _syscall3(int, __syscall_open, const char *, file,
+ int, flags, __kernel_mode_t, mode)
+#endif
+
+/* NPTL has its own implementation */
+#if ! defined(__UCLIBC_HAS_THREADS_NATIVE__)
+int open(const char *file, int oflag, ...)
+{
+ mode_t mode = 0;
+
+ if (oflag & O_CREAT) {
+ va_list arg;
+ va_start(arg, oflag);
+ mode = va_arg(arg, mode_t);
+ va_end(arg);
+ }
+#if defined(__NR_openat) && !defined(__NR_open)
+ return openat(AT_FDCWD, file, oflag, mode);
+#else
+ return __syscall_open(file, oflag, mode);
+#endif
+}
+
+#else
+#if defined(__NR_openat) && !defined(__NR_open)
+/*
+ * Arches that don't support the open() syscall, need to
+ * define a symbol for that so other packages that rely
+ * on it, can build and run successfully
+ */
+int open(const char *file, int oflag, ...)
+{
+ mode_t mode = 0;
+
+ va_list arg;
+ va_start(arg, oflag);
+ mode = va_arg(arg, mode_t);
+ va_end(arg);
+
+ return openat(AT_FDCWD, file, oflag, mode);
+}
+
+#else
+/*
+ * The implementation for open() is defined in the NTPL source files.
+ * We must not define it here, to avoid symbol collisions
+ */
+#endif
+
+#endif /* __UCLIBC_HAS_THREADS_NATIVE__ */
+
+#ifdef __LINUXTHREADS_NEW__
+libc_hidden_def(open)
+#elif defined(__LINUXTHREADS_OLD__) || \
+( defined(__UCLIBC_HAS_THREADS_NATIVE__) && defined(__NR_openat) \
+&& !defined(__NR_open) )
+libc_hidden_weak(open)
+strong_alias(open, __libc_open)
+#endif
diff --git a/libc/sysdeps/linux/common/open.c b/libc/sysdeps/linux/common/open.c
deleted file mode 100644
index 9fb694d..0000000
--- a/libc/sysdeps/linux/common/open.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/* vi: set sw=4 ts=4: */
-/*
- * open() for uClibc
- *
- * Copyright (C) 2000-2006 Erik Andersen <andersen at uclibc.org>
- *
- * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
- */
-
-#include <sys/syscall.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <fcntl.h>
-#include <string.h>
-#include <sys/param.h>
-
-#define __NR___syscall_open __NR_open
-static __inline__ _syscall3(int, __syscall_open, const char *, file,
- int, flags, __kernel_mode_t, mode)
-
-int open(const char *file, int oflag, ...)
-{
- mode_t mode = 0;
-
- if (oflag & O_CREAT) {
- va_list arg;
- va_start(arg, oflag);
- mode = va_arg(arg, mode_t);
- va_end(arg);
- }
-
- return __syscall_open(file, oflag, mode);
-}
-#ifndef __LINUXTHREADS_OLD__
-libc_hidden_def(open)
-#else
-libc_hidden_weak(open)
-strong_alias(open,__libc_open)
-#endif
diff --git a/libpthread/linuxthreads.old/wrapsyscall.c b/libpthread/linuxthreads.old/wrapsyscall.c
index 7424f2e..f9f5717 100644
--- a/libpthread/linuxthreads.old/wrapsyscall.c
+++ b/libpthread/linuxthreads.old/wrapsyscall.c
@@ -115,9 +115,10 @@ libpthread_hidden_def(nanosleep)
/* open(2). */
+#if !defined(__NR_openat) && defined(__NR_open)
CANCELABLE_SYSCALL_VA (int, open, (const char *pathname, int flags, ...),
(pathname, flags, va_arg (ap, mode_t)), flags)
-
+#endif
#ifdef __UCLIBC_HAS_LFS__
/* open64(3). */
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/open.S b/libpthread/nptl/sysdeps/unix/sysv/linux/open.S
index 486686a..083141e 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/open.S
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/open.S
@@ -5,6 +5,12 @@ extern int __open_nocancel (const char *, int, ...) attribute_hidden;
*/
#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
+/*
+ * override the hidden open symbol with this one when
+ * we don't have openat() defined. Otherwise we will use
+ * the common wrapper
+ */
+#if defined(__NR_open)
PSEUDO (__libc_open, open, 3)
ret
PSEUDO_END(__libc_open)
@@ -16,6 +22,6 @@ libc_hidden_weak (__open)
weak_alias (__libc_open, open)
libc_hidden_weak (open)
-
+#endif
#endif
--
1.8.0
More information about the uClibc
mailing list