aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/unix
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/unix')
-rw-r--r--sysdeps/unix/sysv/linux/Makefile2
-rw-r--r--sysdeps/unix/sysv/linux/fcntl.c60
-rw-r--r--sysdeps/unix/sysv/linux/gethostid.c7
-rw-r--r--sysdeps/unix/sysv/linux/i386/fcntl.c18
-rw-r--r--sysdeps/unix/sysv/linux/not-cancel.h4
5 files changed, 79 insertions, 12 deletions
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index f292931fb9..2d781d2f74 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -15,6 +15,8 @@ ifeq ($(subdir),misc)
sysdep_routines += sysctl clone llseek umount umount2 readahead \
setfsuid setfsgid
+CFLAGS-gethostid.c = -fexceptions
+
sysdep_headers += sys/mount.h sys/acct.h sys/sysctl.h \
sys/klog.h sys/kdaemon.h \
sys/user.h sys/procfs.h sys/prctl.h \
diff --git a/sysdeps/unix/sysv/linux/fcntl.c b/sysdeps/unix/sysv/linux/fcntl.c
new file mode 100644
index 0000000000..33651d3c10
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/fcntl.c
@@ -0,0 +1,60 @@
+/* Copyright (C) 2000, 2002, 2003 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 <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdarg.h>
+
+#include <sysdep-cancel.h>
+#include <sys/syscall.h>
+
+
+int
+__fcntl_nocancel (int fd, int cmd, void *arg)
+{
+ return INLINE_SYSCALL (fcntl, 3, fd, cmd, arg);
+}
+
+
+int
+__libc_fcntl (int fd, int cmd, ...)
+{
+ va_list ap;
+ void *arg;
+
+ va_start (ap, cmd);
+ arg = va_arg (ap, void *);
+ va_end (ap);
+
+ if (SINGLE_THREAD_P || cmd != F_SETLKW)
+ return __fcntl_nocancel (fd, cmd, arg);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ int result = __fcntl_nocancel (fd, cmd, arg);
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+}
+libc_hidden_def (__libc_fcntl)
+
+weak_alias (__libc_fcntl, __fcntl)
+libc_hidden_weak (__fcntl)
+weak_alias (__libc_fcntl, fcntl)
diff --git a/sysdeps/unix/sysv/linux/gethostid.c b/sysdeps/unix/sysv/linux/gethostid.c
index 5ef330b958..c7f894033d 100644
--- a/sysdeps/unix/sysv/linux/gethostid.c
+++ b/sysdeps/unix/sysv/linux/gethostid.c
@@ -101,11 +101,8 @@ gethostid ()
if (herr != NETDB_INTERNAL || errno != ERANGE)
return 0;
else
- {
- /* Enlarge buffer. */
- buflen *= 2;
- buffer = __alloca (buflen);
- }
+ /* Enlarge buffer. */
+ buffer = extend_alloca (buffer, buflen, 2 * buflen);
in.s_addr = 0;
memcpy (&in, hp->h_addr,
diff --git a/sysdeps/unix/sysv/linux/i386/fcntl.c b/sysdeps/unix/sysv/linux/i386/fcntl.c
index 749288d92b..c0ca1257f1 100644
--- a/sysdeps/unix/sysv/linux/i386/fcntl.c
+++ b/sysdeps/unix/sysv/linux/i386/fcntl.c
@@ -28,11 +28,13 @@
#if __ASSUME_FCNTL64 == 0
/* This variable is shared with all files that check for fcntl64. */
int __have_no_fcntl64;
+#endif
-static int
-do_fcntl (int fd, int cmd, void *arg)
+int
+__fcntl_nocancel (int fd, int cmd, void *arg)
{
+#if __ASSUME_FCNTL64 == 0
# ifdef __NR_fcntl64
if (! __have_no_fcntl64)
{
@@ -113,8 +115,10 @@ do_fcntl (int fd, int cmd, void *arg)
return INLINE_SYSCALL (fcntl, 3, fd, cmd, arg);
}
return -1;
+#else
+ return INLINE_SYSCALL (fcntl64, 3, fd, cmd, arg);
+#endif /* !__ASSUME_FCNTL64 */
}
-#endif /* __ASSUME_FCNTL64 */
int
@@ -128,19 +132,19 @@ __libc_fcntl (int fd, int cmd, ...)
va_end (ap);
#if __ASSUME_FCNTL64 > 0
- if (SINGLE_THREAD_P)
+ if (SINGLE_THREAD_P || (cmd != F_SETLKW && cmd != F_SETLKW64))
return INLINE_SYSCALL (fcntl64, 3, fd, cmd, arg);
int oldtype = LIBC_CANCEL_ASYNC ();
int result = INLINE_SYSCALL (fcntl64, 3, fd, cmd, arg);
#else
- if (SINGLE_THREAD_P)
- return do_fcntl (fd, cmd, arg);
+ if (SINGLE_THREAD_P || (cmd != F_SETLKW && cmd != F_SETLKW64))
+ return __fcntl_nocancel (fd, cmd, arg);
int oldtype = LIBC_CANCEL_ASYNC ();
- int result = do_fcntl (fd, cmd, arg);
+ int result = __fcntl_nocancel (fd, cmd, arg);
#endif
LIBC_CANCEL_RESET (oldtype);
diff --git a/sysdeps/unix/sysv/linux/not-cancel.h b/sysdeps/unix/sysv/linux/not-cancel.h
index c71641906d..9418417b45 100644
--- a/sysdeps/unix/sysv/linux/not-cancel.h
+++ b/sysdeps/unix/sysv/linux/not-cancel.h
@@ -46,6 +46,10 @@
(void) ({ INTERNAL_SYSCALL_DECL (err); \
INTERNAL_SYSCALL (writev, err, 3, (fd), (iov), (n)); })
+/* Uncancelable fcntl. */
+#define fcntl_not_cancel(fd, cmd, val) \
+ __fcntl_nocancel (fd, cmd, val)
+
/* Uncancelable waitpid. */
#ifdef __NR_waitpid
# define waitpid_not_cancel(pid, stat_loc, options) \