summaryrefslogtreecommitdiffstats
path: root/libc/sysdeps/linux/common/__syscall_fcntl.c
diff options
context:
space:
mode:
Diffstat (limited to 'libc/sysdeps/linux/common/__syscall_fcntl.c')
-rw-r--r--libc/sysdeps/linux/common/__syscall_fcntl.c96
1 files changed, 69 insertions, 27 deletions
diff --git a/libc/sysdeps/linux/common/__syscall_fcntl.c b/libc/sysdeps/linux/common/__syscall_fcntl.c
index ca9aff5e7..56a282a6a 100644
--- a/libc/sysdeps/linux/common/__syscall_fcntl.c
+++ b/libc/sysdeps/linux/common/__syscall_fcntl.c
@@ -2,49 +2,91 @@
/*
* __syscall_fcntl() for uClibc
*
- * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+ * Copyright (C) 2006 Steven J. Hill <sjhill@realitydiluted.com>
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
*
* Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
*/
#include "syscalls.h"
#include <stdarg.h>
+#ifdef __UCLIBC_HAS_THREADS_NATIVE__
+#include <sysdep-cancel.h> /* Must come before <fcntl.h>. */
+#endif
#include <fcntl.h>
+#include <bits/wordsize.h>
-#undef __fcntl
+extern __typeof(fcntl) __libc_fcntl;
+libc_hidden_proto(__libc_fcntl)
-#if defined __UCLIBC_HAS_LFS__ && defined __NR_fcntl64
-extern int __fcntl64(int fd, int cmd, ...) attribute_hidden;
-#endif
+#ifdef __UCLIBC_HAS_THREADS_NATIVE__
+int __fcntl_nocancel (int fd, int cmd, ...)
+{
+ va_list ap;
+ void *arg;
+
+ va_start (ap, cmd);
+ arg = va_arg (ap, void *);
+ va_end (ap);
-#undef fcntl
-#define __NR___syscall_fcntl __NR_fcntl
-static inline
-_syscall3(int, __syscall_fcntl, int, fd, int, cmd, long, arg);
+# if __WORDSIZE == 32
+ if (cmd == F_GETLK64 || cmd == F_SETLK64 || cmd == F_SETLKW64) {
+# if defined __UCLIBC_HAS_LFS__ && defined __NR_fcntl64
+ return INLINE_SYSCALL (fcntl64, 3, fd, cmd, arg);
+# else
+ __set_errno(ENOSYS);
+ return -1;
+# endif
+ }
+# endif
+ return INLINE_SYSCALL (fcntl, 3, fd, cmd, arg);
+}
+#endif
-int attribute_hidden __fcntl(int fd, int cmd, ...)
+int __libc_fcntl (int fd, int cmd, ...)
{
- long arg;
- va_list list;
+ va_list ap;
+ void *arg;
- va_start(list, cmd);
- arg = va_arg(list, long);
- va_end(list);
+ va_start (ap, cmd);
+ arg = va_arg (ap, void *);
+ va_end (ap);
- if (cmd == F_GETLK64 || cmd == F_SETLK64 || cmd == F_SETLKW64) {
-#if defined __UCLIBC_HAS_LFS__ && defined __NR_fcntl64
- return __fcntl64(fd, cmd, arg);
+#ifdef __UCLIBC_HAS_THREADS_NATIVE__
+ if (SINGLE_THREAD_P || (cmd != F_SETLKW && cmd != F_SETLKW64))
+# if defined __UCLIBC_HAS_LFS__ && defined __NR_fcntl64
+ return INLINE_SYSCALL (fcntl64, 3, fd, cmd, arg);
+# else
+ return INLINE_SYSCALL (fcntl, 3, fd, cmd, arg);
+# endif
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+# if defined __UCLIBC_HAS_LFS__ && defined __NR_fcntl64
+ int result = INLINE_SYSCALL (fcntl64, 3, fd, cmd, arg);
+# else
+ int result = INLINE_SYSCALL (fcntl, 3, fd, cmd, arg);
+# endif
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
#else
+# if __WORDSIZE == 32
+ if (cmd == F_GETLK64 || cmd == F_SETLK64 || cmd == F_SETLKW64) {
+# if defined __UCLIBC_HAS_LFS__ && defined __NR_fcntl64
+ return INLINE_SYSCALL (fcntl64, 3, fd, cmd, arg);
+# else
__set_errno(ENOSYS);
return -1;
-#endif
+# endif
}
- return (__syscall_fcntl(fd, cmd, arg));
-}
-strong_alias(__fcntl,fcntl)
-weak_alias(__fcntl,__libc_fcntl)
-#if ! defined __NR_fcntl64 && defined __UCLIBC_HAS_LFS__
-hidden_strong_alias(__fcntl,__fcntl64)
-weak_alias(__fcntl,fcntl64)
-weak_alias(__fcntl,__libc_fcntl64)
+# endif
+ return INLINE_SYSCALL (fcntl, 3, fd, cmd, arg);
#endif
+}
+libc_hidden_def(__libc_fcntl)
+
+libc_hidden_proto(fcntl)
+weak_alias(__libc_fcntl,fcntl)
+libc_hidden_weak(fcntl)