about summary refs log tree commit diff
path: root/sysdeps/unix/sysv/linux
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>1999-05-26 23:37:38 +0000
committerUlrich Drepper <drepper@redhat.com>1999-05-26 23:37:38 +0000
commit958f238f3619373d3dbc106d3cda3c467b3419b1 (patch)
tree9d15d47658aeaae08ee7e5e5e9d4a63d034caa49 /sysdeps/unix/sysv/linux
parent475e390e80a950a8746dc0b88341742dc99014e4 (diff)
downloadglibc-958f238f3619373d3dbc106d3cda3c467b3419b1.tar.gz
glibc-958f238f3619373d3dbc106d3cda3c467b3419b1.tar.xz
glibc-958f238f3619373d3dbc106d3cda3c467b3419b1.zip
Update.
1999-05-26  Ulrich Drepper  <drepper@cygnus.com>

	* config.h.in: Add __LINUX_KERNEL_VERSION.
	* configure.in: Recognize --enable-kernel.
	* sysdeps/unix/sysv/linux/configure.in: Check for correct kernel
	headers if --enable-kernel is given and set __LINUX_KERNEL_VERSION
	appropriately.
	* sysdeps/unix/sysv/linux/init-first.c: If minimal kernel version is
	given perform runtime test.

	* sysdeps/unix/sysv/linux/kernel-features.h: New file.
	* sysdeps/unix/sysv/linux/getcwd.c: Elide compatibility code if
	minimal supported kernel is known to have the feature.
	* sysdeps/unix/sysv/linux/poll.c: Likewise.
	* sysdeps/unix/sysv/linux/pread.c: Likewise.
	* sysdeps/unix/sysv/linux/pread64.c: Likewise.
	* sysdeps/unix/sysv/linux/pwrite.c: Likewise.
	* sysdeps/unix/sysv/linux/pwrite64.c: Likewise.
	* sysdeps/unix/sysv/linux/seteuid.c: Likewise.
	* sysdeps/unix/sysv/linux/sigaction.c: Likewise.
	* sysdeps/unix/sysv/linux/sigprocmask.c: Likewise.
	* sysdeps/unix/sysv/linux/sigsuspend.c: Likewise.
	* sysdeps/unix/sysv/linux/testrtsig.h: Likewise.
	* sysdeps/unix/sysv/linux/i386/chown.c: Likewise.
	* sysdeps/unix/sysv/linux/i386/pread.c: Likewise.
	* sysdeps/unix/sysv/linux/i386/pread64.c: Likewise.
	* sysdeps/unix/sysv/linux/i386/pwrite.c: Likewise.
	* sysdeps/unix/sysv/linux/i386/pwrite64.c: Likewise.

	* sysdeps/unix/sysv/linux/sysctl.c: Add __sysctl alias.
Diffstat (limited to 'sysdeps/unix/sysv/linux')
-rw-r--r--sysdeps/unix/sysv/linux/configure33
-rw-r--r--sysdeps/unix/sysv/linux/configure.in27
-rw-r--r--sysdeps/unix/sysv/linux/getcwd.c45
-rw-r--r--sysdeps/unix/sysv/linux/i386/chown.c14
-rw-r--r--sysdeps/unix/sysv/linux/i386/pread.c17
-rw-r--r--sysdeps/unix/sysv/linux/i386/pread64.c18
-rw-r--r--sysdeps/unix/sysv/linux/i386/pwrite.c17
-rw-r--r--sysdeps/unix/sysv/linux/i386/pwrite64.c17
-rw-r--r--sysdeps/unix/sysv/linux/init-first.c74
-rw-r--r--sysdeps/unix/sysv/linux/kernel-features.h74
-rw-r--r--sysdeps/unix/sysv/linux/poll.c16
-rw-r--r--sysdeps/unix/sysv/linux/pread.c17
-rw-r--r--sysdeps/unix/sysv/linux/pread64.c17
-rw-r--r--sysdeps/unix/sysv/linux/pwrite.c17
-rw-r--r--sysdeps/unix/sysv/linux/pwrite64.c17
-rw-r--r--sysdeps/unix/sysv/linux/seteuid.c8
-rw-r--r--sysdeps/unix/sysv/linux/sigaction.c37
-rw-r--r--sysdeps/unix/sysv/linux/sigpending.c10
-rw-r--r--sysdeps/unix/sysv/linux/sigprocmask.c11
-rw-r--r--sysdeps/unix/sysv/linux/sigsuspend.c10
-rw-r--r--sysdeps/unix/sysv/linux/sysctl.c7
-rw-r--r--sysdeps/unix/sysv/linux/testrtsig.h8
22 files changed, 440 insertions, 71 deletions
diff --git a/sysdeps/unix/sysv/linux/configure b/sysdeps/unix/sysv/linux/configure
index bf5e797d31..f5d994b1c7 100644
--- a/sysdeps/unix/sysv/linux/configure
+++ b/sysdeps/unix/sysv/linux/configure
@@ -13,7 +13,7 @@ if test -n "$sysheaders"; then
 fi
 echo $ac_n "checking installed Linux kernel header files""... $ac_c" 1>&6
 echo "configure:16: checking installed Linux kernel header files" >&5
-if eval "test \"`echo '$''{'libc_cv_linux2010'+set}'`\" = set"; then
+if eval "test \"\${libc_cv_linux2010+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
@@ -49,6 +49,35 @@ make sure that file was built correctly when installing the kernel header
 files.  To use kernel headers not from /usr/include/linux, use the
 configure option --with-headers." 1>&2; exit 1; }
 fi
+
+# If the user gave a minimal version number test whether the available
+# kernel headers are young enough.
+if test -n "$minimum_kernel"; then
+  echo $ac_n "checking for kernel header at least $minimum_kernel""... $ac_c" 1>&6
+echo "configure:58: checking for kernel header at least $minimum_kernel" >&5
+  decnum=`echo "$minimum_kernel.0.0.0" | sed 's/\([0-9]*\)\.\([0-9]*\)\.\(\([0-9]*\)\|\).*/(\1 * 65536 + \2 * 256 + \3)/'`;
+  cat > conftest.$ac_ext <<EOF
+#include <linux/version.h>
+int main() {
+#if LINUX_VERSION_CODE < $decnum
+eat flaming death
+#endif
+; return 0; }
+EOF
+  if { (eval echo configure:30: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+    cat >> confdefs.h <<EOF
+#define __LINUX_KERNEL_VERSION $decnum
+EOF
+
+    echo "$ac_t""ok" 1>&6
+  else
+    echo "$ac_t""too old!" 1>&6
+    { echo "configure: error: *** The available kernel headers are not at least as old as the requested
+*** compatible kernel version" 1>&2; exit 1; }
+  fi
+  rm -f conftest*
+fi
+
 if test -n "$sysheaders"; then
   CFLAGS=$OLD_CFLAGS
 fi
@@ -135,7 +164,7 @@ if test $host = $build; then
     ac_prefix=$ac_default_prefix
   fi
   echo $ac_n "checking for symlinks in ${ac_prefix}/include""... $ac_c" 1>&6
-echo "configure:131: checking for symlinks in ${ac_prefix}/include" >&5
+echo "configure:168: checking for symlinks in ${ac_prefix}/include" >&5
   ac_message=
   if test -L ${ac_prefix}/include/net; then
     ac_message="$ac_message
diff --git a/sysdeps/unix/sysv/linux/configure.in b/sysdeps/unix/sysv/linux/configure.in
index 2c425c5f25..021b4731eb 100644
--- a/sysdeps/unix/sysv/linux/configure.in
+++ b/sysdeps/unix/sysv/linux/configure.in
@@ -34,6 +34,33 @@ make sure that file was built correctly when installing the kernel header
 files.  To use kernel headers not from /usr/include/linux, use the
 configure option --with-headers.])
 fi
+
+# If the user gave a minimal version number test whether the available
+# kernel headers are young enough.
+if test -n "$minimum_kernel"; then
+  AC_MSG_CHECKING(for kernel header at least $minimum_kernel)
+changequote(,)dnl
+  decnum=`echo "$minimum_kernel.0.0.0" | sed 's/\([0-9]*\)\.\([0-9]*\)\.\(\([0-9]*\)\|\).*/(\1 * 65536 + \2 * 256 + \3)/'`;
+changequote([,])dnl
+  cat > conftest.$ac_ext <<EOF
+#include <linux/version.h>
+int main() {
+#if LINUX_VERSION_CODE < $decnum
+eat flaming death
+#endif
+; return 0; }
+EOF
+  if { (eval echo configure:30: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+    AC_DEFINE_UNQUOTED(__LINUX_KERNEL_VERSION, $decnum)
+    AC_MSG_RESULT(ok)
+  else
+    AC_MSG_RESULT(too old!)
+    AC_MSG_ERROR([*** The available kernel headers are not at least as old as the requested
+*** compatible kernel version])
+  fi
+  rm -f conftest*
+fi
+
 if test -n "$sysheaders"; then
   CFLAGS=$OLD_CFLAGS
 fi
diff --git a/sysdeps/unix/sysv/linux/getcwd.c b/sysdeps/unix/sysv/linux/getcwd.c
index fe28e2d894..cc7b987f9b 100644
--- a/sysdeps/unix/sysv/linux/getcwd.c
+++ b/sysdeps/unix/sysv/linux/getcwd.c
@@ -18,6 +18,7 @@
    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
+#include <assert.h>
 #include <errno.h>
 #include <limits.h>
 #include <stdlib.h>
@@ -26,7 +27,19 @@
 #include <sysdep.h>
 #include <sys/syscall.h>
 
+#include "kernel-features.h"
 
+
+#if __ASSUME_GETCWD_SYSCALL > 0
+/* Kernel 2.1.92 introduced a third way to get the current working
+   directory: a syscall.  We've got to be careful that even when
+   compiling under 2.1.92+ the libc still runs under older kernels. */
+extern int __syscall_getcwd (char *buf, unsigned long size);
+# define no_syscall_getcwd 0
+# define have_new_dcache 1
+/* This is a trick since we don't define generic_getcwd.  */
+# define generic_getcwd getcwd
+#else
 /* The "proc" filesystem provides an easy method to retrieve the value.
    For each process, the corresponding directory contains a symbolic link
    named `cwd'.  Reading the content of this link immediate gives us the
@@ -34,16 +47,17 @@
    the proc filesystem mounted.  Use the POSIX implementation in this case.  */
 static char *generic_getcwd (char *buf, size_t size) internal_function;
 
-#ifdef __NR_getcwd
+# if __NR_getcwd
 /* Kernel 2.1.92 introduced a third way to get the current working
    directory: a syscall.  We've got to be careful that even when
    compiling under 2.1.92+ the libc still runs under older kernels. */
 extern int __syscall_getcwd (char *buf, unsigned long size);
 static int no_syscall_getcwd;
 static int have_new_dcache;
-#else
-# define no_syscall_getcwd 1
+# else
+#  define no_syscall_getcwd 1
 static int have_new_dcache = 1;
+# endif
 #endif
 
 char *
@@ -80,7 +94,7 @@ __getcwd (char *buf, size_t size)
 
   save_errno = errno;
 
-#ifdef __NR_getcwd
+#if defined __NR_getcwd || __LINUX_GETCWD_SYSCALL > 0
   if (!no_syscall_getcwd)
     {
       int retval;
@@ -98,6 +112,16 @@ __getcwd (char *buf, size_t size)
 	  return buf;
 	}
 
+# if __ASSUME_GETCWD_SYSCALL
+      /* It should never happen that the `getcwd' syscall failed because
+	 the buffer is too small if we allocated the buffer outself.  */
+      assert (errno != ERANGE || buf != NULL);
+
+      if (buf == NULL)
+	free (path);
+
+      return NULL;
+# else
       if (errno == ENOSYS)
 	{
 	   no_syscall_getcwd = 1;
@@ -111,6 +135,7 @@ __getcwd (char *buf, size_t size)
 	}
 
       __set_errno (save_errno);
+# endif
     }
 #endif
 
@@ -136,14 +161,18 @@ __getcwd (char *buf, size_t size)
 	    }
 	  return buf;
 	}
+#ifndef have_new_dcache
       else
 	have_new_dcache = 0;
+#endif
     }
 
+#if __ASSUME_GETCWD_SYSCALL == 0
   /* Set to have_new_dcache only if error indicates that proc doesn't
      exist.  */
   if (errno != EACCES && errno != ENAMETOOLONG)
     have_new_dcache = 0;
+#endif
 
   /* Something went wrong.  Restore the error number and use the generic
      version.  */
@@ -165,7 +194,9 @@ __getcwd (char *buf, size_t size)
 }
 weak_alias (__getcwd, getcwd)
 
+#if __ASSUME_GETCWD_SYSCALL == 0
 /* Get the code for the generic version.  */
-#define GETCWD_RETURN_TYPE	static char * internal_function
-#define __getcwd		generic_getcwd
-#include <sysdeps/posix/getcwd.c>
+# define GETCWD_RETURN_TYPE	static char * internal_function
+# define __getcwd		generic_getcwd
+# include <sysdeps/posix/getcwd.c>
+#endif
diff --git a/sysdeps/unix/sysv/linux/i386/chown.c b/sysdeps/unix/sysv/linux/i386/chown.c
index 3776a4490c..9ab03e3a7c 100644
--- a/sysdeps/unix/sysv/linux/i386/chown.c
+++ b/sysdeps/unix/sysv/linux/i386/chown.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1998, 1999 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
@@ -22,6 +22,8 @@
 #include <sysdep.h>
 #include <sys/syscall.h>
 
+#include <kernel-features.h>
+
 /*
   In Linux 2.1.x the chown functions have been changed.  A new function lchown
   was introduced.  The new chown now follows symlinks - the old chown and the
@@ -34,14 +36,15 @@
 
 extern int __syscall_chown (const char *__file,
 			    uid_t __owner, gid_t __group);
-#ifdef __NR_lchown
+#if defined __NR_lchown || __ASSUME_LCHOWN_SYSCALL > 0
 /* Running under Linux > 2.1.80.  */
-static int __libc_old_chown;
 
 
 int
 __real_chown (const char *file, uid_t owner, gid_t group)
 {
+# if __ASSUME_LCHOWN_SYSCALL == 0
+  static int __libc_old_chown;
   int result;
 
   if (!__libc_old_chown)
@@ -57,11 +60,14 @@ __real_chown (const char *file, uid_t owner, gid_t group)
     }
 
   return __lchown (file, owner, group);
+# else
+  return INLINE_SYSCALL (chown, 3, file, owner, group);
+# endif
 }
 #endif
 
 
-#ifndef __NR_lchown
+#if !defined __NR_lchown && __ASSUME_LCHOWN_SYSCALL == 0
 /* Compiling under older kernels.  */
 int
 __chown_is_lchown (const char *file, uid_t owner, gid_t group)
diff --git a/sysdeps/unix/sysv/linux/i386/pread.c b/sysdeps/unix/sysv/linux/i386/pread.c
index 4c2f18d3f2..5745648306 100644
--- a/sysdeps/unix/sysv/linux/i386/pread.c
+++ b/sysdeps/unix/sysv/linux/i386/pread.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
@@ -23,10 +23,14 @@
 #include <sysdep.h>
 #include <sys/syscall.h>
 
-#ifdef __NR_pread
+#include <kernel-features.h>
 
+#if defined __NR_pread || __ASSUME_PREAD_SYSCALL > 0
+
+# if __ASSUME_PREAD_SYSCALL == 0
 static ssize_t __emulate_pread (int fd, void *buf, size_t count,
 				off_t offset) internal_function;
+# endif
 
 
 ssize_t
@@ -40,16 +44,21 @@ __pread (fd, buf, count, offset)
 
   /* First try the syscall.  */
   result = INLINE_SYSCALL (pread, 5, fd, buf, count, offset, 0);
+# if __ASSUME_PREAD_SYSCALL == 0
   if (result == -1 && errno == ENOSYS)
     /* No system call available.  Use the emulation.  */
     result = __emulate_pread (fd, buf, count, offset);
+# endif
 
   return result;
 }
 
 weak_alias (__pread, pread)
 
-#define __pread(fd, buf, count, offset) \
+# define __pread(fd, buf, count, offset) \
      static internal_function __emulate_pread (fd, buf, count, offset)
 #endif
-#include <sysdeps/posix/pread.c>
+
+#if __ASSUME_PREAD_SYSCALL == 0
+# include <sysdeps/posix/pread.c>
+#endif
diff --git a/sysdeps/unix/sysv/linux/i386/pread64.c b/sysdeps/unix/sysv/linux/i386/pread64.c
index 8cfb3c0a43..aa0c54d385 100644
--- a/sysdeps/unix/sysv/linux/i386/pread64.c
+++ b/sysdeps/unix/sysv/linux/i386/pread64.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
@@ -23,13 +23,14 @@
 #include <sysdep.h>
 #include <sys/syscall.h>
 
-#ifdef __NR_pread
+#include <kernel-features.h>
 
-extern ssize_t __syscall_pread64 (int fd, void *buf, size_t count,
-				  off_t offset_hi, off_t offset_lo);
+#if defined __NR_pread || __ASSUME_PREAD_SYSCALL > 0
 
+# if __ASSUME_PREAD_SYSCALL == 0
 static ssize_t __emulate_pread64 (int fd, void *buf, size_t count,
 				  off64_t offset) internal_function;
+# endif
 
 
 ssize_t
@@ -45,16 +46,21 @@ __pread64 (fd, buf, count, offset)
   result = INLINE_SYSCALL (pread, 5, fd, buf, count,
 			   (off_t) (offset & 0xffffffff),
 			   (off_t) (offset >> 32));
+# if __ASSUME_PREAD_SYSCALL == 0
   if (result == -1 && errno == ENOSYS)
     /* No system call available.  Use the emulation.  */
     result = __emulate_pread64 (fd, buf, count, offset);
+# endif
 
   return result;
 }
 
 weak_alias (__pread64, pread64)
 
-#define __pread64(fd, buf, count, offset) \
+# define __pread64(fd, buf, count, offset) \
      static internal_function __emulate_pread64 (fd, buf, count, offset)
 #endif
-#include <sysdeps/posix/pread64.c>
+
+#if __ASSUME_PREAD_SYSCALL == 0
+# include <sysdeps/posix/pread64.c>
+#endif
diff --git a/sysdeps/unix/sysv/linux/i386/pwrite.c b/sysdeps/unix/sysv/linux/i386/pwrite.c
index a1fc99f156..90eee5b4e1 100644
--- a/sysdeps/unix/sysv/linux/i386/pwrite.c
+++ b/sysdeps/unix/sysv/linux/i386/pwrite.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
@@ -23,10 +23,14 @@
 #include <sysdep.h>
 #include <sys/syscall.h>
 
-#ifdef __NR_pwrite
+#include <kernel-features.h>
 
+#if defined __NR_pwrite || __ASSUME_PWRITE_SYSCALL > 0
+
+# if __ASSUME_PWRITE_SYSCALL == 0
 static ssize_t __emulate_pwrite (int fd, const void *buf, size_t count,
 				 off_t offset) internal_function;
+# endif
 
 
 ssize_t
@@ -40,16 +44,21 @@ __pwrite (fd, buf, count, offset)
 
   /* First try the syscall.  */
   result = INLINE_SYSCALL (pwrite, 5, fd, buf, count, offset, 0);
+# if __ASSUME_PWRITE_SYSCALL == 0
   if (result == -1 && errno == ENOSYS)
     /* No system call available.  Use the emulation.  */
     result = __emulate_pwrite (fd, buf, count, offset);
+# endif
 
   return result;
 }
 
 weak_alias (__pwrite, pwrite)
 
-#define __pwrite(fd, buf, count, offset) \
+# define __pwrite(fd, buf, count, offset) \
      static internal_function __emulate_pwrite (fd, buf, count, offset)
 #endif
-#include <sysdeps/posix/pwrite.c>
+
+#if __ASSUME_PWRITE_SYSCALL == 0
+# include <sysdeps/posix/pwrite.c>
+#endif
diff --git a/sysdeps/unix/sysv/linux/i386/pwrite64.c b/sysdeps/unix/sysv/linux/i386/pwrite64.c
index 7a5d665de3..500cd7cef3 100644
--- a/sysdeps/unix/sysv/linux/i386/pwrite64.c
+++ b/sysdeps/unix/sysv/linux/i386/pwrite64.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
@@ -23,10 +23,14 @@
 #include <sysdep.h>
 #include <sys/syscall.h>
 
-#ifdef __NR_pwrite
+#include <kernel-features.h>
 
+#if defined __NR_pwrite || __ASSUME_PWRITE_SYSCALL > 0
+
+# if __ASSUME_PWRITE_SYSCALL == 0
 static ssize_t __emulate_pwrite64 (int fd, const void *buf, size_t count,
 				   off64_t offset) internal_function;
+# endif
 
 
 ssize_t
@@ -42,16 +46,21 @@ __pwrite64 (fd, buf, count, offset)
   result = INLINE_SYSCALL (pwrite, 5, fd, buf, count,
 			   (off_t) (offset & 0xffffffff),
 			   (off_t) (offset >> 32));
+# if __ASSUME_PWRITE_SYSCALL == 0
   if (result == -1 && errno == ENOSYS)
     /* No system call available.  Use the emulation.  */
     result = __emulate_pwrite64 (fd, buf, count, offset);
+# endif
 
   return result;
 }
 
 weak_alias (__pwrite64, pwrite64)
 
-#define __pwrite64(fd, buf, count, offset) \
+# define __pwrite64(fd, buf, count, offset) \
      static internal_function __emulate_pwrite64 (fd, buf, count, offset)
 #endif
-#include <sysdeps/posix/pwrite64.c>
+
+#if __ASSUME_PWRITE_SYSCALL == 0
+# include <sysdeps/posix/pwrite64.c>
+#endif
diff --git a/sysdeps/unix/sysv/linux/init-first.c b/sysdeps/unix/sysv/linux/init-first.c
index 01395baf75..b8ee2bdf14 100644
--- a/sysdeps/unix/sysv/linux/init-first.c
+++ b/sysdeps/unix/sysv/linux/init-first.c
@@ -1,5 +1,5 @@
 /* Initialization code run first thing by the ELF startup code.  Linux version.
-   Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+   Copyright (C) 1995, 1996, 1997, 1998, 1999 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
@@ -17,12 +17,17 @@
    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
+#include <stdio.h>
+#include <fcntl.h>
 #include <unistd.h>
 #include <sysdep.h>
 #include <fpu_control.h>
 #include <linux/personality.h>
 #include <init-first.h>
+#include <sys/param.h>
+#include <sys/sysctl.h>
 #include <sys/types.h>
+#include "kernel-features.h"
 
 extern void __libc_init_secure (void);
 extern void __libc_init (int, char **, char **);
@@ -31,6 +36,10 @@ extern void __libc_global_ctors (void);
 /* The function is called from assembly stubs the compiler can't see.  */
 static void init (int, char **, char **) __attribute__ ((unused));
 
+/* The function we use to get the kernel revision.  */
+extern int __sysctl (int *name, int nlen, void *oldval, size_t *oldlenp,
+		     void *newval, size_t newlen);
+
 extern int _dl_starting_up;
 weak_extern (_dl_starting_up)
 
@@ -56,6 +65,69 @@ init (int argc, char **argv, char **envp)
   /* We must not call `personality' twice.  */
   if (!__libc_multiple_libcs)
     {
+      /* Test whether the kernel is new enough.  This test is only
+         performed if the library is not compiled to run on all
+         kernels.  */
+      if (__LINUX_KERNEL_VERSION > 0)
+	{
+	  static const int sysctl_args[] = { CTL_KERN, KERN_OSRELEASE };
+	  char buf[64];
+	  size_t reslen = sizeof (buf);
+	  unsigned int version;
+	  int parts;
+	  char *cp;
+
+	  /* Try reading the number using `sysctl' first.  */
+	  if (__sysctl ((int *) sysctl_args,
+			sizeof (sysctl_args) / sizeof (sysctl_args[0]),
+			buf, &reslen, NULL, 0) < 0)
+	    {
+	      /* This was not successful.  Now try reading the /proc
+		 filesystem.  */
+	      int fd = __open ("/proc/sys/kernel/osrelease", O_RDONLY);
+	      if (fd == -1
+		  || (reslen = __read (fd, buf, sizeof (buf))) <= 0)
+		/* This also didn't work.  We give up since we cannot
+		   make sure the library can actually work.  */
+		__libc_fatal ("FATAL: cannot determine library version\n");
+
+	      __close (fd);
+	    }
+	  buf[MIN (reslen, sizeof (buf) - 1)] = '\0';
+
+	  /* Now convert it into a number.  The string consists of at most
+	     three parts.  */
+	  version = 0;
+	  parts = 0;
+	  cp = buf;
+	  while ((*cp >= '0') && (*cp <= '9'))
+	    {
+	      unsigned int here = *cp++ - '0';
+
+	      while ((*cp >= '0') && (*cp <= '9'))
+		{
+		  here *= 10;
+		  here += *cp++ - '0';
+		}
+
+	      ++parts;
+	      version <<= 8;
+	      version |= here;
+
+	      if (*cp++ != '.')
+		/* Another part following?  */
+		break;
+	    }
+
+	  if (parts < 3)
+	    version <<= 8 * (3 - parts);
+
+	  /* Now we can test with the required version.  */
+	  if (version < __LINUX_KERNEL_VERSION)
+	    /* Not sufficent.  */
+	    __libc_fatal ("FATAL: kernel too old\n");
+	}
+
       /* The `personality' system call takes one argument that chooses
 	 the "personality", i.e. the set of system calls and such.  We
 	 must make this call first thing to disable emulation of some
diff --git a/sysdeps/unix/sysv/linux/kernel-features.h b/sysdeps/unix/sysv/linux/kernel-features.h
new file mode 100644
index 0000000000..6813853ccc
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/kernel-features.h
@@ -0,0 +1,74 @@
+/* Set flags signalling availability of kernel features based on given
+   kernel version number.
+   Copyright (C) 1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/* This file must not contain any C code.  At least it must be protected
+   to allow using the file also in assembler files.  */
+
+/* XXX For testing.  */
+#define __LINUX_KERNEL_VERSION 131584
+
+#ifndef __LINUX_KERNEL_VERSION
+/* We assume the worst; all kernels should be supported.  */
+# define __LINUX_KERNEL_VERSION	0
+#endif
+
+/* We assume for __LINUX_KERNEL_VERSION the same encoding used in
+   linux/version.h.  I.e., the major, minor, and subminor all get a
+   byte with the major number being in the highest byte.  This means
+   we can do numeric comparisons.
+
+   In the following we will define certain symbols depending on
+   whether the describes kernel feature is available in the kernel
+   version given by __LINUX_KERNEL_VERSION.  We are not always exactly
+   recording the correct versions in which the features were
+   introduced.  If somebody cares these values can afterwards be
+   corrected.  Most of the numbers here are set corresponding to
+   2.2.0.  */
+
+/* `getcwd' system call.  */
+#if __LINUX_KERNEL_VERSION >= 131584
+# define __ASSUME_GETCWD_SYSCALL	1
+#endif
+
+/* Real-time signal became usable in 2.1.70.  */
+#if __LINUX_KERNEL_VERSION >= 131398
+# define __ASSUME_REALTIME_SIGNALS	1
+#endif
+
+/* When were the `pread'/`pwrite' syscalls introduced?  */
+#if __LINUX_KERNEL_VERSION >= 131584
+# define __ASSUME_PREAD_SYSCALL		1
+# define __ASSUME_PWRITE_SYSCALL	1
+#endif
+
+/* When was `poll' introduced?  */
+#if __LINUX_KERNEL_VERSION >= 131584
+# define __ASSUME_POLL_SYSCALL		1
+#endif
+
+/* The `lchown' syscall was introduced in 2.1.80.  */
+#if __LINUX_KERNEL_VERSION >= 131408
+# define __ASSUME_LCHOWN_SYSCALL	1
+#endif
+
+/* When did the `setresuid' sysall became available?  */
+#if __LINUX_KERNEL_VERSION >= 131584
+# define __ASSUME_SETRESUID_SYSCALL	1
+#endif
diff --git a/sysdeps/unix/sysv/linux/poll.c b/sysdeps/unix/sysv/linux/poll.c
index e7df3b7774..16433e53e7 100644
--- a/sysdeps/unix/sysv/linux/poll.c
+++ b/sysdeps/unix/sysv/linux/poll.c
@@ -22,13 +22,18 @@
 
 #include <sysdep.h>
 #include <sys/syscall.h>
-#ifdef __NR_poll
+
+#include "kernel-features.h"
+
+#if defined __NR_poll || __ASSUME_POLL_SYSCALL > 0
 
 extern int __syscall_poll __P ((struct pollfd *fds, unsigned int nfds,
 				int timeout));
 
+# if __ASSUME_POLL_SYSCALL == 0
 static int __emulate_poll __P ((struct pollfd *fds, unsigned long int nfds,
 				int timeout)) internal_function;
+# endif
 
 /* The real implementation.  */
 int
@@ -37,6 +42,7 @@ __poll (fds, nfds, timeout)
      unsigned long int nfds;
      int timeout;
 {
+# if __ASSUME_POLL_SYSCALL == 0
   static int must_emulate;
 
   if (!must_emulate)
@@ -52,6 +58,9 @@ __poll (fds, nfds, timeout)
     }
 
   return __emulate_poll (fds, nfds, timeout);
+# else
+  return INLINE_SYSCALL (poll, 3, fds, nfds, timeout);
+# endif
 }
 weak_alias (__poll, poll)
 
@@ -59,4 +68,7 @@ weak_alias (__poll, poll)
 # define __poll(fds, nfds, timeout) \
   static internal_function __emulate_poll (fds, nfds, timeout)
 #endif
-#include <sysdeps/unix/bsd/poll.c>
+
+#if __ASSUME_POLL_SYSCALL == 0
+# include <sysdeps/unix/bsd/poll.c>
+#endif
diff --git a/sysdeps/unix/sysv/linux/pread.c b/sysdeps/unix/sysv/linux/pread.c
index a9461cab2e..cae3d62a5d 100644
--- a/sysdeps/unix/sysv/linux/pread.c
+++ b/sysdeps/unix/sysv/linux/pread.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
@@ -23,13 +23,17 @@
 #include <sysdep.h>
 #include <sys/syscall.h>
 
-#ifdef __NR_pread
+#include "kernel-features.h"
+
+#if defined __NR_pread || __ASSUME_PREAD_SYSCALL > 0
 
 extern ssize_t __syscall_pread (int fd, void *buf, size_t count,
 				off_t offset_hi, off_t offset_lo);
 
+# if __ASSUME_PREAD_SYSCALL == 0
 static ssize_t __emulate_pread (int fd, void *buf, size_t count,
 				off_t offset) internal_function;
+# endif
 
 
 ssize_t
@@ -43,16 +47,21 @@ __pread (fd, buf, count, offset)
 
   /* First try the syscall.  */
   result = INLINE_SYSCALL (pread, 5, fd, buf, count, 0, offset);
+# if __ASSUME_PREAD_SYSCALL == 0
   if (result == -1 && errno == ENOSYS)
     /* No system call available.  Use the emulation.  */
     result = __emulate_pread (fd, buf, count, offset);
+# endif
 
   return result;
 }
 
 weak_alias (__pread, pread)
 
-#define __pread(fd, buf, count, offset) \
+# define __pread(fd, buf, count, offset) \
      static internal_function __emulate_pread (fd, buf, count, offset)
 #endif
-#include <sysdeps/posix/pread.c>
+
+#if __ASSUME_PREAD_SYSCALL == 0
+# include <sysdeps/posix/pread.c>
+#endif
diff --git a/sysdeps/unix/sysv/linux/pread64.c b/sysdeps/unix/sysv/linux/pread64.c
index b8e117770f..fc4f7f24a0 100644
--- a/sysdeps/unix/sysv/linux/pread64.c
+++ b/sysdeps/unix/sysv/linux/pread64.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
@@ -23,13 +23,17 @@
 #include <sysdep.h>
 #include <sys/syscall.h>
 
-#ifdef __NR_pread
+#include "kernel-features.h"
+
+#if defined __NR_pread || __ASSUME_PREAD_SYSCALL > 0
 
 extern ssize_t __syscall_pread (int fd, void *buf, size_t count,
 				off_t offset_hi, off_t offset_lo);
 
+# if __ASSUME_PREAD_SYSCALL == 0
 static ssize_t __emulate_pread64 (int fd, void *buf, size_t count,
 				  off64_t offset) internal_function;
+# endif
 
 
 ssize_t
@@ -44,16 +48,21 @@ __pread64 (fd, buf, count, offset)
   /* First try the syscall.  */
   result = INLINE_SYSCALL (pread, 5, fd, buf, count, (off_t) (offset >> 32),
 			   (off_t) (offset & 0xffffffff));
+# if __ASSUME_PREAD_SYSCALL == 0
   if (result == -1 && errno == ENOSYS)
     /* No system call available.  Use the emulation.  */
     result = __emulate_pread64 (fd, buf, count, offset);
+# endif
 
   return result;
 }
 
 weak_alias (__pread64, pread64)
 
-#define __pread64(fd, buf, count, offset) \
+# define __pread64(fd, buf, count, offset) \
      static internal_function __emulate_pread64 (fd, buf, count, offset)
 #endif
-#include <sysdeps/posix/pread64.c>
+
+# if __ASSUME_PREAD_SYSCALL == 0
+# include <sysdeps/posix/pread64.c>
+#endif
diff --git a/sysdeps/unix/sysv/linux/pwrite.c b/sysdeps/unix/sysv/linux/pwrite.c
index cd7b8adaa1..fd4ec8896d 100644
--- a/sysdeps/unix/sysv/linux/pwrite.c
+++ b/sysdeps/unix/sysv/linux/pwrite.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
@@ -23,13 +23,17 @@
 #include <sysdep.h>
 #include <sys/syscall.h>
 
-#ifdef __NR_pwrite
+#include "kernel-features.h"
+
+#if defined __NR_pwrite || __ASSUME_PWRITE_SYSCALL > 0
 
 extern ssize_t __syscall_pwrite (int fd, const void *buf, size_t count,
 				 off_t offset_hi, off_t offset_lo);
 
+# if __ASSUME_PWRITE_SYSCALL == 0
 static ssize_t __emulate_pwrite (int fd, const void *buf, size_t count,
 				 off_t offset) internal_function;
+# endif
 
 
 ssize_t
@@ -43,16 +47,21 @@ __pwrite (fd, buf, count, offset)
 
   /* First try the syscall.  */
   result = INLINE_SYSCALL (pwrite, 5, fd, buf, count, 0, offset);
+# if __ASSUME_PWRITE_SYSCALL == 0
   if (result == -1 && errno == ENOSYS)
     /* No system call available.  Use the emulation.  */
     result = __emulate_pwrite (fd, buf, count, offset);
+# endif
 
   return result;
 }
 
 weak_alias (__pwrite, pwrite)
 
-#define __pwrite(fd, buf, count, offset) \
+# define __pwrite(fd, buf, count, offset) \
      static internal_function __emulate_pwrite (fd, buf, count, offset)
 #endif
-#include <sysdeps/posix/pwrite.c>
+
+#if __ASSUME_PWRITE_SYSCALL == 0
+# include <sysdeps/posix/pwrite.c>
+#endif
diff --git a/sysdeps/unix/sysv/linux/pwrite64.c b/sysdeps/unix/sysv/linux/pwrite64.c
index b6ebba154b..cc92de1d76 100644
--- a/sysdeps/unix/sysv/linux/pwrite64.c
+++ b/sysdeps/unix/sysv/linux/pwrite64.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
@@ -23,13 +23,17 @@
 #include <sysdep.h>
 #include <sys/syscall.h>
 
-#ifdef __NR_pwrite
+#include "kernel-features.h"
+
+#if defined __NR_pwrite || __ASSUME_PWRITE_SYSCALL > 0
 
 extern ssize_t __syscall_pwrite64 (int fd, const void *buf, size_t count,
 				   off_t offset_hi, off_t offset_lo);
 
+# if __ASSUME_PWRITE_SYSCALL == 0
 static ssize_t __emulate_pwrite64 (int fd, const void *buf, size_t count,
 				   off64_t offset) internal_function;
+# endif
 
 
 ssize_t
@@ -44,16 +48,21 @@ __pwrite64 (fd, buf, count, offset)
   /* First try the syscall.  */
   result = INLINE_SYSCALL (pwrite, 5, fd, buf, count, (off_t) (offset >> 32),
 			   (off_t) (offset & 0xffffffff));
+# if __ASSUME_PWRITE_SYSCALL == 0
   if (result == -1 && errno == ENOSYS)
     /* No system call available.  Use the emulation.  */
     result = __emulate_pwrite64 (fd, buf, count, offset);
+# endif
 
   return result;
 }
 
 weak_alias (__pwrite64, pwrite64)
 
-#define __pwrite64(fd, buf, count, offset) \
+# define __pwrite64(fd, buf, count, offset) \
      static internal_function __emulate_pwrite64 (fd, buf, count, offset)
 #endif
-#include <sysdeps/posix/pwrite64.c>
+
+#if __ASSUME_PWRITE_SYSCALL == 0
+# include <sysdeps/posix/pwrite64.c>
+#endif
diff --git a/sysdeps/unix/sysv/linux/seteuid.c b/sysdeps/unix/sysv/linux/seteuid.c
index 20840dbfc0..15687e36e4 100644
--- a/sysdeps/unix/sysv/linux/seteuid.c
+++ b/sysdeps/unix/sysv/linux/seteuid.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1998, 1999 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
@@ -21,7 +21,9 @@
 #include <sys/types.h>
 #include <unistd.h>
 
-#ifdef __NR_setresuid
+#include "kernel-features.h"
+
+#if defined __NR_setresuid || __ASSUME_SETRESUID_SYSCALL > 0
 
 extern int __setresuid (uid_t ruid, uid_t euid, uid_t suid);
 
@@ -38,11 +40,13 @@ seteuid (uid_t uid)
 
   /* First try the syscall.  */
   result = __setresuid (-1, uid, -1);
+# if __ASSUME_SETRESUID_SYSCALL == 0
   if (result == -1 && errno == ENOSYS)
     /* No system call available.  Use emulation.  This may not work
        since `setreuid' also sets the saved user ID when UID is not
        equal to the real user ID, making it impossible to switch back.  */
     result = __setreuid (-1, uid);
+# endif
 
   return result;
 }
diff --git a/sysdeps/unix/sysv/linux/sigaction.c b/sysdeps/unix/sysv/linux/sigaction.c
index a5580cc0e6..40f9bbc252 100644
--- a/sysdeps/unix/sysv/linux/sigaction.c
+++ b/sysdeps/unix/sysv/linux/sigaction.c
@@ -23,20 +23,27 @@
 #include <sysdep.h>
 #include <sys/syscall.h>
 
+#include "kernel-features.h"
+
 /* The difference here is that the sigaction structure used in the
    kernel is not the same as we use in the libc.  Therefore we must
    translate it here.  */
 #include <kernel_sigaction.h>
 
+#if __ASSUME_REALTIME_SIGNALS == 0
+/* The variable is shared between all wrappers around signal handling
+   functions which have RT equivalents.  This is the definition.  */
+int __libc_missing_rt_sigs;
+
 extern int __syscall_sigaction (int, const struct old_kernel_sigaction *,
 				struct old_kernel_sigaction *);
+# define rtsignals_guaranteed 0
+#else
+# define rtsignals_guaranteed 1
+#endif
 extern int __syscall_rt_sigaction (int, const struct kernel_sigaction *,
 				   struct kernel_sigaction *, size_t);
 
-/* The variable is shared between all wrappers around signal handling
-   functions which have RT equivalents.  This is the definition.  */
-int __libc_missing_rt_sigs;
-
 
 /* If ACT is not NULL, change the action for SIG to *ACT.
    If OACT is not NULL, put the old action for SIG in *OACT.  */
@@ -49,12 +56,18 @@ __sigaction (sig, act, oact)
   struct old_kernel_sigaction k_sigact, k_osigact;
   int result;
 
-#ifdef __NR_rt_sigaction
+#if defiend __NR_rt_sigaction || __ASSUME_REALTIME_SIGNALS > 0
   /* First try the RT signals.  */
+# if __ASSUME_REALTIME_SIGNALS == 0
   if (!__libc_missing_rt_sigs)
+# endif
     {
       struct kernel_sigaction kact, koact;
+      /* Save the current error value for later.  We need not do this
+	 if we are guaranteed to have realtime signals.  */
+# if __ASSUME_REALTIME_SIGNALS == 0
       int saved_errno = errno;
+# endif
 
       if (act)
 	{
@@ -71,7 +84,9 @@ __sigaction (sig, act, oact)
       result = INLINE_SYSCALL (rt_sigaction, 4, sig, act ? &kact : NULL,
 			       oact ? &koact : NULL, _NSIG / 8);
 
+# if __ASSUME_REALTIME_SIGNALS == 0
       if (result >= 0 || errno != ENOSYS)
+# endif
 	{
 	  if (oact && result >= 0)
 	    {
@@ -85,19 +100,22 @@ __sigaction (sig, act, oact)
 	  return result;
 	}
 
+# if __ASSUME_REALTIME_SIGNALS == 0
       __set_errno (saved_errno);
       __libc_missing_rt_sigs = 1;
+# endif
     }
 #endif
 
+#if __ASSUME_REALTIME_SIGNALS == 0
   if (act)
     {
       k_sigact.k_sa_handler = act->sa_handler;
       k_sigact.sa_mask = act->sa_mask.__val[0];
       k_sigact.sa_flags = act->sa_flags;
-#ifdef HAVE_SA_RESTORER
+# ifdef HAVE_SA_RESTORER
       k_sigact.sa_restorer = act->sa_restorer;
-#endif
+# endif
     }
   result = INLINE_SYSCALL (sigaction, 3, sig, act ? &k_sigact : NULL,
 			   oact ? &k_osigact : NULL);
@@ -106,11 +124,12 @@ __sigaction (sig, act, oact)
       oact->sa_handler = k_osigact.k_sa_handler;
       oact->sa_mask.__val[0] = k_osigact.sa_mask;
       oact->sa_flags = k_osigact.sa_flags;
-#ifdef HAVE_SA_RESTORER
+# ifdef HAVE_SA_RESTORER
       oact->sa_restorer = k_osigact.sa_restorer;
-#endif
+# endif
     }
   return result;
+#endif
 }
 
 weak_alias (__sigaction, sigaction)
diff --git a/sysdeps/unix/sysv/linux/sigpending.c b/sysdeps/unix/sysv/linux/sigpending.c
index c41c4f266a..932314520c 100644
--- a/sysdeps/unix/sysv/linux/sigpending.c
+++ b/sysdeps/unix/sysv/linux/sigpending.c
@@ -23,6 +23,8 @@
 #include <sysdep.h>
 #include <sys/syscall.h>
 
+#include "kernel-features.h"
+
 extern int __syscall_sigpending (sigset_t *);
 extern int __syscall_rt_sigpending (sigset_t *, size_t);
 
@@ -38,7 +40,10 @@ int
 sigpending (set)
      sigset_t *set;
 {
-#ifdef __NR_rt_pending
+#if __ASSUME_REALTIME_SIGNALS > 0
+  return INLINE_SYSCALL (rt_sigpending, 2, set, _NSIG / 8);
+#else
+# ifdef __NR_rt_pending
   /* First try the RT signals.  */
   if (!__libc_missing_rt_sigs)
     {
@@ -53,7 +58,8 @@ sigpending (set)
       __set_errno (saved_errno);
       __libc_missing_rt_sigs = 1;
     }
-#endif
+# endif
 
   return INLINE_SYSCALL (sigpending, 1, set);
+#endif
 }
diff --git a/sysdeps/unix/sysv/linux/sigprocmask.c b/sysdeps/unix/sysv/linux/sigprocmask.c
index 5e72c9892d..3e0719aa7f 100644
--- a/sysdeps/unix/sysv/linux/sigprocmask.c
+++ b/sysdeps/unix/sysv/linux/sigprocmask.c
@@ -23,6 +23,9 @@
 #include <sysdep.h>
 #include <sys/syscall.h>
 
+#include "kernel-features.h"
+
+
 extern int __syscall_sigprocmask (int, const sigset_t *, sigset_t *);
 extern int __syscall_rt_sigprocmask (int, const sigset_t *, sigset_t *,
 				     size_t);
@@ -39,7 +42,10 @@ __sigprocmask (how, set, oset)
      const sigset_t *set;
      sigset_t *oset;
 {
-#ifdef __NR_rt_sigprocmask
+#if __ASSUME_REALTIME_SIGNALS > 0
+  return INLINE_SYSCALL (rt_sigprocmask, 4, how, set, oset, _NSIG / 8);
+#else
+# ifdef __NR_rt_sigprocmask
   /* First try the RT signals.  */
   if (!__libc_missing_rt_sigs)
     {
@@ -55,8 +61,9 @@ __sigprocmask (how, set, oset)
       __set_errno (saved_errno);
       __libc_missing_rt_sigs = 1;
     }
-#endif
+# endif
 
   return INLINE_SYSCALL (sigprocmask, 3, how, set, oset);
+#endif
 }
 weak_alias (__sigprocmask, sigprocmask)
diff --git a/sysdeps/unix/sysv/linux/sigsuspend.c b/sysdeps/unix/sysv/linux/sigsuspend.c
index 1d0dba0270..da743396b8 100644
--- a/sysdeps/unix/sysv/linux/sigsuspend.c
+++ b/sysdeps/unix/sysv/linux/sigsuspend.c
@@ -23,6 +23,8 @@
 #include <sysdep.h>
 #include <sys/syscall.h>
 
+#include "kernel-features.h"
+
 extern int __syscall_sigsuspend (int, unsigned long int, unsigned long int);
 extern int __syscall_rt_sigsuspend (const sigset_t *, size_t);
 
@@ -38,7 +40,10 @@ int
 __sigsuspend (set)
      const sigset_t *set;
 {
-#ifdef __NR_rt_sigsuspend
+#if __ASSUME_REALTIME_SIGNALS
+  return INLINE_SYSCALL (rt_sigsuspend, 2, set, _NSIG / 8);
+#else
+# ifdef __NR_rt_sigsuspend
   /* First try the RT signals.  */
   if (!__libc_missing_rt_sigs)
     {
@@ -53,8 +58,9 @@ __sigsuspend (set)
       __set_errno (saved_errno);
       __libc_missing_rt_sigs = 1;
     }
-#endif
+# endif
 
   return INLINE_SYSCALL (sigsuspend, 3, 0, 0, set->__val[0]);
+#endif
 }
 weak_alias (__sigsuspend, sigsuspend)
diff --git a/sysdeps/unix/sysv/linux/sysctl.c b/sysdeps/unix/sysv/linux/sysctl.c
index 1ab3c79bed..b131820a30 100644
--- a/sysdeps/unix/sysv/linux/sysctl.c
+++ b/sysdeps/unix/sysv/linux/sysctl.c
@@ -1,5 +1,5 @@
 /* Read or write system information.  Linux version.
-   Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
+   Copyright (C) 1996, 1997, 1998, 1999 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
@@ -26,8 +26,8 @@
 extern int __syscall__sysctl (struct __sysctl_args *args);
 
 int
-sysctl (int *name, int nlen, void *oldval, size_t *oldlenp,
-	void *newval, size_t newlen)
+__sysctl (int *name, int nlen, void *oldval, size_t *oldlenp,
+	  void *newval, size_t newlen)
 {
   struct __sysctl_args args =
   {
@@ -41,3 +41,4 @@ sysctl (int *name, int nlen, void *oldval, size_t *oldlenp,
 
   return INLINE_SYSCALL (_sysctl, 1, &args);
 }
+weak_alias (__sysctl, sysctl)
diff --git a/sysdeps/unix/sysv/linux/testrtsig.h b/sysdeps/unix/sysv/linux/testrtsig.h
index 7c41877e66..72d4e5a3d2 100644
--- a/sysdeps/unix/sysv/linux/testrtsig.h
+++ b/sysdeps/unix/sysv/linux/testrtsig.h
@@ -1,5 +1,5 @@
 /* Test whether RT signals are really available.
-   Copyright (C) 1997 Free Software Foundation, Inc.
+   Copyright (C) 1997, 1999 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
@@ -21,10 +21,16 @@
 #include <string.h>
 #include <sys/utsname.h>
 
+#include "kernel-features.h"
+
 static int
 kernel_has_rtsig (void)
 {
+#if __ASSUME_REALTIME_SIGNALS
+  return 1;
+#else
   struct utsname name;
 
   return uname (&name) == 0 && __strverscmp (name.release, "2.1.70") >= 0;
+#endif
 }