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.
This commit is contained in:
Ulrich Drepper 1999-05-26 23:37:38 +00:00
parent 475e390e80
commit 958f238f36
26 changed files with 744 additions and 262 deletions

View File

@ -1,3 +1,34 @@
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.
1999-05-25 Ulrich Drepper <drepper@cygnus.com>
* sysdeps/posix/getcwd.c (__getcwd): Fix potential memory leaks.

View File

@ -77,6 +77,9 @@
# define internal_function __attribute__ ((regparm (3), stdcall))
#endif
/* Linux specific: minimum supported kernel version. */
#undef __LINUX_KERNEL_VERSION
/*
*/

452
configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -133,6 +133,13 @@ AC_ARG_ENABLE(force-install,
force_install=$enableval, force_install=yes)
AC_SUBST(force_install)
dnl On some platforms we allow dropping compatibility with all kernel
dnl versions.
AC_ARG_ENABLE(kernel,
[ --enable-kernel=VERSION compile for copmatibility with kernel not older
than VERSION],
minimum_kernel=$enableval)
AC_CANONICAL_HOST
# The way shlib-versions is used to generate soversions.mk uses a

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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>
extern int __syscall_sigaction (int, const struct old_kernel_sigaction *,
struct old_kernel_sigaction *);
extern int __syscall_rt_sigaction (int, const struct kernel_sigaction *,
struct kernel_sigaction *, size_t);
#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);
/* 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)

View File

@ -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
}

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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
}