diff options
Diffstat (limited to 'libc/sysdeps/linux/common/__syscall_fcntl.c')
-rw-r--r-- | libc/sysdeps/linux/common/__syscall_fcntl.c | 96 |
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) |