summaryrefslogtreecommitdiff
path: root/sysdeps
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2004-09-20 00:16:11 +0000
committerUlrich Drepper <drepper@redhat.com>2004-09-20 00:16:11 +0000
commit2edb61e3f955bfcc9dd3cb6b3b1acfe4806234a6 (patch)
treeeb3ba83120d92a0ea9955520f2df4e00a22bc884 /sysdeps
parent29e11320c90722aec6335a5f8d8af84d12ba3c6b (diff)
Update.
* sysdeps/unix/sysv/linux/setegid.c [HAVE_PTR__NPTL_SETXID]: Call callback to set IDs in all other threads as well. * sysdeps/unix/sysv/linux/seteuid.c: Likewise. * sysdeps/unix/sysv/linux/i386/setegid.c: Likewise. * sysdeps/unix/sysv/linux/i386/seteuid.c: Likewise. * sysdeps/unix/sysv/linux/i386/setgid.c: Likewise. * sysdeps/unix/sysv/linux/i386/setuid.c: Likewise. * sysdeps/unix/sysv/linux/i386/setreuid.c: Likewise. * sysdeps/unix/sysv/linux/i386/setreuid.c: Likewise. * sysdeps/unix/sysv/linux/i386/setresuid.c: Likewise. * sysdeps/unix/sysv/linux/i386/setresuid.c: Likewise. * sysdeps/unix/sysv/linux/setuid.c: New file. * sysdeps/unix/sysv/linux/setgid.c: New file. * sysdeps/unix/sysv/linux/setreuid.c: New file. * sysdeps/unix/sysv/linux/setregid.c: New file. * sysdeps/unix/sysv/linux/setresuid.c: New file. * sysdeps/unix/sysv/linux/setresgid.c: New file. * sysdeps/unix/sysv/linux/i386/sysdep.h: Define INTERNAL_SYSCALL_NCS. * sysdeps/unix/sysv/linux/ia64/sysdep.h: Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h: Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h: Likewise. * sysdeps/unix/sysv/linux/x86_64/sysdep.h: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc32/setegid.c: Use x86 version. * sysdeps/unix/sysv/linux/sparc/sparc32/seteuid.c: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc32/setresgid.c: New file. * sysdeps/unix/sysv/linux/sparc/sparc32/setresuid.c: New file. * sysdeps/unix/sysv/linux/sparc/sparc32/syscalls.list: Remove setresgid and setresuid. * nscd/aicache.c: Use pthread_seteuid_np instead of seteuid. * nscd/grpcache.c: Likewise. * nscd/hstcache.c: Likewise. * nscd/pwdcache.c: Likewise.
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/unix/sysv/linux/i386/setegid.c28
-rw-r--r--sysdeps/unix/sysv/linux/i386/seteuid.c28
-rw-r--r--sysdeps/unix/sysv/linux/i386/setgid.c33
-rw-r--r--sysdeps/unix/sysv/linux/i386/setregid.c32
-rw-r--r--sysdeps/unix/sysv/linux/i386/setresgid.c34
-rw-r--r--sysdeps/unix/sysv/linux/i386/setresuid.c34
-rw-r--r--sysdeps/unix/sysv/linux/i386/setreuid.c32
-rw-r--r--sysdeps/unix/sysv/linux/i386/setuid.c33
-rw-r--r--sysdeps/unix/sysv/linux/i386/sysdep.h42
-rw-r--r--sysdeps/unix/sysv/linux/ia64/sysdep.h46
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h30
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h30
-rw-r--r--sysdeps/unix/sysv/linux/setegid.c28
-rw-r--r--sysdeps/unix/sysv/linux/seteuid.c30
-rw-r--r--sysdeps/unix/sysv/linux/setgid.c53
-rw-r--r--sysdeps/unix/sysv/linux/setregid.c53
-rw-r--r--sysdeps/unix/sysv/linux/setresgid.c54
-rw-r--r--sysdeps/unix/sysv/linux/setresuid.c54
-rw-r--r--sysdeps/unix/sysv/linux/setreuid.c53
-rw-r--r--sysdeps/unix/sysv/linux/setuid.c52
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/setegid.c55
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/seteuid.c57
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/setresgid.c1
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/setresuid.c1
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/syscalls.list2
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/sysdep.h9
26 files changed, 689 insertions, 215 deletions
diff --git a/sysdeps/unix/sysv/linux/i386/setegid.c b/sysdeps/unix/sysv/linux/i386/setegid.c
index fcd6cf1827..b8682e3681 100644
--- a/sysdeps/unix/sysv/linux/i386/setegid.c
+++ b/sysdeps/unix/sysv/linux/i386/setegid.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995-1998, 2000, 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 1995-1998,2000,2002,2003,2004 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,7 @@
#include <sysdep.h>
#include "kernel-features.h"
+#include <pthread-functions.h>
#ifdef __NR_setresgid
@@ -32,10 +33,17 @@ int
setegid (gid)
gid_t gid;
{
+ int result;
+
+ if (gid == (gid_t) ~0)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
#if __ASSUME_32BITUIDS > 0
- return INLINE_SYSCALL (setresgid32, 3, -1, gid, -1);
+ result = INLINE_SYSCALL (setresgid32, 3, -1, gid, -1);
#else
- int result;
/* First try the syscall. */
# ifdef __NR_setresgid
result = __setresgid (-1, gid, -1);
@@ -49,8 +57,20 @@ setegid (gid)
equal to the real user ID, making it impossible to switch back. */
# endif
result = __setregid (-1, gid);
+#endif
- return result;
+#if defined HAVE_PTR__NPTL_SETXID && !defined SINGLE_THREAD
+ if (result == 0 && __libc_pthread_functions.ptr__nptl_setxid != NULL)
+ {
+ struct xid_command cmd;
+ cmd.syscall_no = __NR_setresgid32;
+ cmd.id[0] = -1;
+ cmd.id[1] = gid;
+ cmd.id[2] = -1;
+ __libc_pthread_functions.ptr__nptl_setxid (&cmd);
+ }
#endif
+
+ return result;
}
libc_hidden_def (setegid)
diff --git a/sysdeps/unix/sysv/linux/i386/seteuid.c b/sysdeps/unix/sysv/linux/i386/seteuid.c
index 87e348a646..0abdac832f 100644
--- a/sysdeps/unix/sysv/linux/i386/seteuid.c
+++ b/sysdeps/unix/sysv/linux/i386/seteuid.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998, 2000, 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 1998, 2000, 2002, 2003, 2004 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,7 @@
#include <sysdep.h>
#include "kernel-features.h"
+#include <pthread-functions.h>
#ifdef __NR_setresuid
@@ -31,10 +32,17 @@ extern int __setresuid (uid_t ruid, uid_t euid, uid_t suid);
int
seteuid (uid_t uid)
{
+ int result;
+
+ if (uid == (uid_t) ~0)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
#if __ASSUME_32BITUIDS > 0
- return INLINE_SYSCALL (setresuid32, 3, -1, uid, -1);
+ result = INLINE_SYSCALL (setresuid32, 3, -1, uid, -1);
#else
- int result;
/* First try the syscall. */
# ifdef __NR_setresuid
result = __setresuid (-1, uid, -1);
@@ -48,8 +56,20 @@ seteuid (uid_t uid)
equal to the real user ID, making it impossible to switch back. */
# endif
result = __setreuid (-1, uid);
+#endif
- return result;
+#if defined HAVE_PTR__NPTL_SETXID && !defined SINGLE_THREAD
+ if (result == 0 && __libc_pthread_functions.ptr__nptl_setxid != NULL)
+ {
+ struct xid_command cmd;
+ cmd.syscall_no = __NR_setresuid32;
+ cmd.id[0] = -1;
+ cmd.id[1] = uid;
+ cmd.id[2] = -1;
+ __libc_pthread_functions.ptr__nptl_setxid (&cmd);
+ }
#endif
+
+ return result;
}
libc_hidden_def (seteuid)
diff --git a/sysdeps/unix/sysv/linux/i386/setgid.c b/sysdeps/unix/sysv/linux/i386/setgid.c
index 1fdca94064..17bfc3e58a 100644
--- a/sysdeps/unix/sysv/linux/i386/setgid.c
+++ b/sysdeps/unix/sysv/linux/i386/setgid.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1998, 2000, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 1998, 2000, 2003, 2004
+ 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,6 +27,8 @@
#include <linux/posix_types.h>
#include "kernel-features.h"
+#include <pthread-functions.h>
+
#ifdef __NR_setgid32
# if __ASSUME_32BITUIDS == 0
@@ -38,18 +41,21 @@ extern int __libc_missing_32bit_uids;
int
__setgid (gid_t gid)
{
+ int result;
+
#if __ASSUME_32BITUIDS > 0
- return INLINE_SYSCALL (setgid32, 1, gid);
+ result = INLINE_SYSCALL (setgid32, 1, gid);
#else
# ifdef __NR_setgid32
if (__libc_missing_32bit_uids <= 0)
{
- int result;
int saved_errno = errno;
result = INLINE_SYSCALL (setgid32, 1, gid);
- if (result == 0 || errno != ENOSYS)
+ if (result == 0)
+ goto out;
+ if (errno != ENOSYS)
return result;
__set_errno (saved_errno);
@@ -64,7 +70,24 @@ __setgid (gid_t gid)
return -1;
}
- return INLINE_SYSCALL (setgid, 1, gid);
+ result = INLINE_SYSCALL (setgid, 1, gid);
+# ifdef __NR_setgid32
+ out:
+# endif
+#endif
+
+#if defined HAVE_PTR__NPTL_SETXID && !defined SINGLE_THREAD
+ if (result == 0 && __libc_pthread_functions.ptr__nptl_setxid != NULL)
+ {
+ struct xid_command cmd;
+ cmd.syscall_no = __NR_setgid32;
+ cmd.id[0] = gid;
+ __libc_pthread_functions.ptr__nptl_setxid (&cmd);
+ }
#endif
+
+ return result;
}
+#ifndef __setgid
weak_alias (__setgid, setgid)
+#endif
diff --git a/sysdeps/unix/sysv/linux/i386/setregid.c b/sysdeps/unix/sysv/linux/i386/setregid.c
index be1d73cb99..f883497fae 100644
--- a/sysdeps/unix/sysv/linux/i386/setregid.c
+++ b/sysdeps/unix/sysv/linux/i386/setregid.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998, 2000, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 1998, 2000, 2003, 2004 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
@@ -25,6 +25,7 @@
#include <linux/posix_types.h>
#include "kernel-features.h"
+#include <pthread-functions.h>
#ifdef __NR_setregid32
@@ -38,18 +39,21 @@ extern int __libc_missing_32bit_uids;
int
__setregid (gid_t rgid, gid_t egid)
{
+ int result;
+
#if __ASSUME_32BITUIDS > 0
- return INLINE_SYSCALL (setregid32, 2, rgid, egid);
+ result = INLINE_SYSCALL (setregid32, 2, rgid, egid);
#else
# ifdef __NR_setregid32
if (__libc_missing_32bit_uids <= 0)
{
- int result;
int saved_errno = errno;
result = INLINE_SYSCALL (setregid32, 2, rgid, egid);
- if (result == 0 || errno != ENOSYS)
+ if (result == 0)
+ goto out;
+ if (errno != ENOSYS)
return result;
__set_errno (saved_errno);
@@ -63,7 +67,25 @@ __setregid (gid_t rgid, gid_t egid)
return -1;
}
- return INLINE_SYSCALL (setregid, 2, rgid, egid);
+ result = INLINE_SYSCALL (setregid, 2, rgid, egid);
+# ifdef __NR_setregid32
+ out:
+# endif
#endif
+
+#if defined HAVE_PTR__NPTL_SETXID && !defined SINGLE_THREAD
+ if (result == 0 && __libc_pthread_functions.ptr__nptl_setxid != NULL)
+ {
+ struct xid_command cmd;
+ cmd.syscall_no = __NR_setregid32;
+ cmd.id[0] = rgid;
+ cmd.id[1] = egid;
+ __libc_pthread_functions.ptr__nptl_setxid (&cmd);
+ }
+#endif
+
+ return result;
}
+#ifndef __setregid
weak_alias (__setregid, setregid)
+#endif
diff --git a/sysdeps/unix/sysv/linux/i386/setresgid.c b/sysdeps/unix/sysv/linux/i386/setresgid.c
index 414a58b07e..ee782e49f3 100644
--- a/sysdeps/unix/sysv/linux/i386/setresgid.c
+++ b/sysdeps/unix/sysv/linux/i386/setresgid.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998, 2000, 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 1998, 2000, 2002, 2003, 2004 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
@@ -25,6 +25,8 @@
#include <sysdep.h>
#include <sys/syscall.h>
#include "kernel-features.h"
+#include <pthread-functions.h>
+
#ifdef __NR_setresgid
@@ -39,17 +41,20 @@ extern int __libc_missing_32bit_uids;
int
__setresgid (gid_t rgid, gid_t egid, gid_t sgid)
{
+ int result;
+
# if __ASSUME_32BITUIDS > 0
- return INLINE_SYSCALL (setresgid32, 3, rgid, egid, sgid);
+ result = INLINE_SYSCALL (setresgid32, 3, rgid, egid, sgid);
# else
# ifdef __NR_setresgid32
if (__libc_missing_32bit_uids <= 0)
{
- int result;
int saved_errno = errno;
result = INLINE_SYSCALL (setresgid32, 3, rgid, egid, sgid);
- if (result == 0 || errno != ENOSYS)
+ if (result == 0)
+ goto out;
+ if (errno != ENOSYS)
return result;
__set_errno (saved_errno);
@@ -65,11 +70,30 @@ __setresgid (gid_t rgid, gid_t egid, gid_t sgid)
return -1;
}
- return INLINE_SYSCALL (setresgid, 3, rgid, egid, sgid);
+ result = INLINE_SYSCALL (setresgid, 3, rgid, egid, sgid);
+# ifdef __NR_setresgid32
+ out:
+# endif
# endif
+
+#if defined HAVE_PTR__NPTL_SETXID && !defined SINGLE_THREAD
+ if (result == 0 && __libc_pthread_functions.ptr__nptl_setxid != NULL)
+ {
+ struct xid_command cmd;
+ cmd.syscall_no = __NR_setresgid32;
+ cmd.id[0] = rgid;
+ cmd.id[1] = egid;
+ cmd.id[2] = sgid;
+ __libc_pthread_functions.ptr__nptl_setxid (&cmd);
+ }
+#endif
+
+ return result;
}
libc_hidden_def (__setresgid)
+#ifndef __setresgid
weak_alias (__setresgid, setresgid)
+#endif
#else
diff --git a/sysdeps/unix/sysv/linux/i386/setresuid.c b/sysdeps/unix/sysv/linux/i386/setresuid.c
index 537fb7995b..66e5a1c0c1 100644
--- a/sysdeps/unix/sysv/linux/i386/setresuid.c
+++ b/sysdeps/unix/sysv/linux/i386/setresuid.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998, 2000, 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 1998, 2000, 2002, 2003, 2004 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
@@ -25,6 +25,8 @@
#include <sysdep.h>
#include <sys/syscall.h>
#include "kernel-features.h"
+#include <pthread-functions.h>
+
#ifdef __NR_setresuid
@@ -39,17 +41,20 @@ extern int __libc_missing_32bit_uids;
int
__setresuid (uid_t ruid, uid_t euid, uid_t suid)
{
+ int result;
+
# if __ASSUME_32BITUIDS > 0
- return INLINE_SYSCALL (setresuid32, 3, ruid, euid, suid);
+ result = INLINE_SYSCALL (setresuid32, 3, ruid, euid, suid);
# else
# ifdef __NR_setresuid32
if (__libc_missing_32bit_uids <= 0)
{
- int result;
int saved_errno = errno;
result = INLINE_SYSCALL (setresuid32, 3, ruid, euid, suid);
- if (result == 0 || errno != ENOSYS)
+ if (result == 0)
+ goto out;
+ if (errno != ENOSYS)
return result;
__set_errno (saved_errno);
@@ -65,11 +70,30 @@ __setresuid (uid_t ruid, uid_t euid, uid_t suid)
return -1;
}
- return INLINE_SYSCALL (setresuid, 3, ruid, euid, suid);
+ result = INLINE_SYSCALL (setresuid, 3, ruid, euid, suid);
+# ifdef __NR_setresuid32
+ out:
+# endif
# endif
+
+#if defined HAVE_PTR__NPTL_SETXID && !defined SINGLE_THREAD
+ if (result == 0 && __libc_pthread_functions.ptr__nptl_setxid != NULL)
+ {
+ struct xid_command cmd;
+ cmd.syscall_no = __NR_setresuid32;
+ cmd.id[0] = ruid;
+ cmd.id[1] = euid;
+ cmd.id[2] = suid;
+ __libc_pthread_functions.ptr__nptl_setxid (&cmd);
+ }
+#endif
+
+ return result;
}
libc_hidden_def (__setresuid)
+#ifndef __setresuid
weak_alias (__setresuid, setresuid)
+#endif
#else
diff --git a/sysdeps/unix/sysv/linux/i386/setreuid.c b/sysdeps/unix/sysv/linux/i386/setreuid.c
index 2aadf7437f..1e1bfcf0d4 100644
--- a/sysdeps/unix/sysv/linux/i386/setreuid.c
+++ b/sysdeps/unix/sysv/linux/i386/setreuid.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998, 2000, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 1998, 2000, 2003, 2004 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
@@ -25,6 +25,7 @@
#include <linux/posix_types.h>
#include "kernel-features.h"
+#include <pthread-functions.h>
#ifdef __NR_setreuid32
@@ -38,18 +39,21 @@ extern int __libc_missing_32bit_uids;
int
__setreuid (uid_t ruid, uid_t euid)
{
+ int result;
+
#if __ASSUME_32BITUIDS > 0
- return INLINE_SYSCALL (setreuid32, 2, ruid, euid);
+ result = INLINE_SYSCALL (setreuid32, 2, ruid, euid);
#else
# ifdef __NR_setreuid32
if (__libc_missing_32bit_uids <= 0)
{
- int result;
int saved_errno = errno;
result = INLINE_SYSCALL (setreuid32, 2, ruid, euid);
- if (result == 0 || errno != ENOSYS)
+ if (result == 0)
+ goto out;
+ if (errno != ENOSYS)
return result;
__set_errno (saved_errno);
@@ -63,7 +67,25 @@ __setreuid (uid_t ruid, uid_t euid)
return -1;
}
- return INLINE_SYSCALL (setreuid, 2, ruid, euid);
+ result = INLINE_SYSCALL (setreuid, 2, ruid, euid);
+# ifdef __NR_setreuid32
+ out:
+# endif
#endif
+
+#if defined HAVE_PTR__NPTL_SETXID && !defined SINGLE_THREAD
+ if (result == 0 && __libc_pthread_functions.ptr__nptl_setxid != NULL)
+ {
+ struct xid_command cmd;
+ cmd.syscall_no = __NR_setreuid32;
+ cmd.id[0] = ruid;
+ cmd.id[1] = euid;
+ __libc_pthread_functions.ptr__nptl_setxid (&cmd);
+ }
+#endif
+
+ return result;
}
+#ifndef __setreuid
weak_alias (__setreuid, setreuid)
+#endif
diff --git a/sysdeps/unix/sysv/linux/i386/setuid.c b/sysdeps/unix/sysv/linux/i386/setuid.c
index 69bf42596f..a11fb7f60c 100644
--- a/sysdeps/unix/sysv/linux/i386/setuid.c
+++ b/sysdeps/unix/sysv/linux/i386/setuid.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998, 2000, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 1998, 2000, 2003, 2004 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
@@ -25,6 +25,8 @@
#include <linux/posix_types.h>
#include "kernel-features.h"
+#include <pthread-functions.h>
+
#ifdef __NR_setuid32
# if __ASSUME_32BITUIDS == 0
@@ -37,8 +39,10 @@ extern int __libc_missing_32bit_uids;
int
__setuid (uid_t uid)
{
-#if __ASSUME_32BITUIDS > 0
- return INLINE_SYSCALL (setuid32, 1, uid);
+ int result;
+
+#if __ASSUME_32BITUIDS > 0 && defined __NR_setuid32
+ result = INLINE_SYSCALL (setuid32, 1, uid);
#else
# ifdef __NR_setuid32
if (__libc_missing_32bit_uids <= 0)
@@ -47,7 +51,9 @@ __setuid (uid_t uid)
int saved_errno = errno;
result = INLINE_SYSCALL (setuid32, 1, uid);
- if (result == 0 || errno != ENOSYS)
+ if (result == 0)
+ goto out;
+ if (errno != ENOSYS)
return result;
__set_errno (saved_errno);
@@ -62,7 +68,24 @@ __setuid (uid_t uid)
return -1;
}
- return INLINE_SYSCALL (setuid, 1, uid);
+ result = INLINE_SYSCALL (setuid, 1, uid);
+# ifdef __NR_setuid32
+ out:
+# endif
+#endif
+
+#if defined HAVE_PTR__NPTL_SETXID && !defined SINGLE_THREAD
+ if (result == 0 && __libc_pthread_functions.ptr__nptl_setxid != NULL)
+ {
+ struct xid_command cmd;
+ cmd.syscall_no = __NR_setuid32;
+ cmd.id[0] = uid;
+ __libc_pthread_functions.ptr__nptl_setxid (&cmd);
+ }
#endif
+
+ return result;
}
+#ifndef __setuid
weak_alias (__setuid, setuid)
+#endif
diff --git a/sysdeps/unix/sysv/linux/i386/sysdep.h b/sysdeps/unix/sysv/linux/i386/sysdep.h
index 79ad72abff..8845e46157 100644
--- a/sysdeps/unix/sysv/linux/i386/sysdep.h
+++ b/sysdeps/unix/sysv/linux/i386/sysdep.h
@@ -1,4 +1,5 @@
-/* Copyright (C) 1992,1993,1995-2000,2002,2003 Free Software Foundation, Inc.
+/* Copyright (C) 1992,1993,1995-2000,2002,2003,2004
+ Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper, <drepper@gnu.org>, August 1995.
@@ -343,7 +344,10 @@ asm (".L__X'%ebx = 1\n\t"
/* Define a macro which expands inline into the wrapper code for a system
call. This use is for internal calls that do not need to handle errors
normally. It will never touch errno. This returns just what the kernel
- gave back. */
+ gave back.
+
+ The _NCS variant allows non-constant syscall numbers but it is not
+ possible to use more than four parameters. */
#undef INTERNAL_SYSCALL
#ifdef I386_USE_SYSENTER
# ifdef SHARED
@@ -360,6 +364,18 @@ asm (".L__X'%ebx = 1\n\t"
: "i" (__NR_##name), "i" (offsetof (tcbhead_t, sysinfo)) \
ASMFMT_##nr(args) : "memory", "cc"); \
(int) resultvar; })
+# define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
+ ({ \
+ register unsigned int resultvar; \
+ EXTRAVAR_##nr \
+ asm volatile ( \
+ LOADARGS_##nr \
+ "call *%%gs:%P2\n\t" \
+ RESTOREARGS_##nr \
+ : "=a" (resultvar) \
+ : "0" (name), "i" (offsetof (tcbhead_t, sysinfo)) \
+ ASMFMT_##nr(args) : "memory", "cc"); \
+ (int) resultvar; })
# else
# define INTERNAL_SYSCALL(name, err, nr, args...) \
({ \
@@ -373,6 +389,17 @@ asm (".L__X'%ebx = 1\n\t"
: "=a" (resultvar) \
: "i" (__NR_##name) ASMFMT_##nr(args) : "memory", "cc"); \
(int) resultvar; })
+# define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
+ ({ \
+ register unsigned int resultvar; \
+ EXTRAVAR_##nr \
+ asm volatile ( \
+ LOADARGS_##nr \
+ "call *_dl_sysinfo\n\t" \
+ RESTOREARGS_##nr \
+ : "=a" (resultvar) \
+ : "0" (name) ASMFMT_##nr(args) : "memory", "cc"); \
+ (int) resultvar; })
# endif
#else
# define INTERNAL_SYSCALL(name, err, nr, args...) \
@@ -387,6 +414,17 @@ asm (".L__X'%ebx = 1\n\t"
: "=a" (resultvar) \
: "i" (__NR_##name) ASMFMT_##nr(args) : "memory", "cc"); \
(int) resultvar; })
+# define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
+ ({ \
+ register unsigned int resultvar; \
+ EXTRAVAR_##nr \
+ asm volatile ( \
+ LOADARGS_##nr \
+ "int $0x80\n\t" \
+ RESTOREARGS_##nr \
+ : "=a" (resultvar) \
+ : "0" (name) ASMFMT_##nr(args) : "memory", "cc"); \
+ (int) resultvar; })
#endif
#undef INTERNAL_SYSCALL_DECL
diff --git a/sysdeps/unix/sysv/linux/ia64/sysdep.h b/sysdeps/unix/sysv/linux/ia64/sysdep.h
index 0868ad50ef..0ebfc56fdd 100644
--- a/sysdeps/unix/sysv/linux/ia64/sysdep.h
+++ b/sysdeps/unix/sysv/linux/ia64/sysdep.h
@@ -199,33 +199,33 @@
#ifdef IA64_USE_NEW_STUB
-#define DO_INLINE_SYSCALL(name, nr, args...) \
- LOAD_ARGS_##nr (args) \
- register long _r8 __asm ("r8"); \
- register long _r10 __asm ("r10"); \
- register long _r15 __asm ("r15") = __NR_##name; \
- register void *_b7 __asm ("b7") = ((tcbhead_t *) __thread_self)->private; \
- long _retval; \
- LOAD_REGS_##nr \
- /* \
- * Don't specify any unwind info here. We mark ar.pfs as \
- * clobbered. This will force the compiler to save ar.pfs \
- * somewhere and emit appropriate unwind info for that save. \
- */ \
- __asm __volatile ("br.call.sptk.many b6=%0;;\n" \
- : "=b"(_b7), "=r" (_r8), "=r" (_r10), "=r" (_r15) \
- ASM_OUTARGS_##nr \
- : "0" (_b7), "3" (_r15) ASM_ARGS_##nr \
- : "memory", "ar.pfs" ASM_CLOBBERS_##nr); \
+# define DO_INLINE_SYSCALL(name, nr, args...) \
+ LOAD_ARGS_##nr (args) \
+ register long _r8 __asm ("r8"); \
+ register long _r10 __asm ("r10"); \
+ register long _r15 __asm ("r15") = name; \
+ register void *_b7 __asm ("b7") = ((tcbhead_t *) __thread_self)->private; \
+ long _retval; \
+ LOAD_REGS_##nr \
+ /* \
+ * Don't specify any unwind info here. We mark ar.pfs as \
+ * clobbered. This will force the compiler to save ar.pfs \
+ * somewhere and emit appropriate unwind info for that save. \
+ */ \
+ __asm __volatile ("br.call.sptk.many b6=%0;;\n" \
+ : "=b"(_b7), "=r" (_r8), "=r" (_r10), "=r" (_r15) \
+ ASM_OUTARGS_##nr \
+ : "0" (_b7), "3" (_r15) ASM_ARGS_##nr \
+ : "memory", "ar.pfs" ASM_CLOBBERS_##nr); \
_retval = _r8;
#else /* !IA64_USE_NEW_STUB */
-#define DO_INLINE_SYSCALL(name, nr, args...) \
+# define DO_INLINE_SYSCALL(name, nr, args...) \
LOAD_ARGS_##nr (args) \
register long _r8 asm ("r8"); \
register long _r10 asm ("r10"); \
- register long _r15 asm ("r15") = __NR_##name; \
+ register long _r15 asm ("r15") = name; \
long _retval; \
LOAD_REGS_##nr \
__asm __volatile (BREAK_INSN (__BREAK_SYSCALL) \
@@ -240,7 +240,7 @@
#undef INLINE_SYSCALL
#define INLINE_SYSCALL(name, nr, args...) \
({ \
- DO_INLINE_SYSCALL(name, nr, args) \
+ DO_INLINE_SYSCALL(__NR_##name, nr, args) \
if (_r10 == -1) \
{ \
__set_errno (_retval); \
@@ -252,11 +252,13 @@
#define INTERNAL_SYSCALL_DECL(err) long int err
#undef INTERNAL_SYSCALL
-#define INTERNAL_SYSCALL(name, err, nr, args...) \
+#define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
({ \
DO_INLINE_SYSCALL(name, nr, args) \
err = _r10; \
_retval; })
+#define INTERNAL_SYSCALL(name, err, nr, args...) \
+ INTERNAL_SYSCALL_NCS (__NR_##name, err, nr, ##args)
#undef INTERNAL_SYSCALL_ERROR_P
#define INTERNAL_SYSCALL_ERROR_P(val, err) (err == -1)
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h b/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h
index 269b4dd531..2ee3e60229 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h
@@ -79,7 +79,7 @@
# define INTERNAL_SYSCALL_DECL(err) long int err
# undef INTERNAL_SYSCALL
-# define INTERNAL_SYSCALL(name, err, nr, args...) \
+# define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
({ \
register long int r0 __asm__ ("r0"); \
register long int r3 __asm__ ("r3"); \
@@ -104,6 +104,8 @@
err = r0; \
(int) r3; \
})
+# define INTERNAL_SYSCALL(name, err, nr, args...) \
+ INTERNAL_SYSCALL_NCS (__NR_##name, err, nr, ##args)
# undef INTERNAL_SYSCALL_ERROR_P
# define INTERNAL_SYSCALL_ERROR_P(val, err) \
@@ -113,48 +115,48 @@
# define INTERNAL_SYSCALL_ERRNO(val, err) (val)
# define LOADARGS_0(name, dummy) \
- r0 = __NR_##name
+ r0 = name
# define LOADARGS_1(name, __arg1) \
long int arg1 = (long int) (__arg1); \
LOADARGS_0(name, 0); \
- extern void __illegally_sized_syscall_##name##_arg1 (void); \
+ extern void __illegally_sized_syscall_arg1 (void); \
if (__builtin_classify_type (__arg1) != 5 && sizeof (__arg1) > 4) \
- __illegally_sized_syscall_##name##_arg1 (); \
+ __illegally_sized_syscall_arg1 (); \
r3 = arg1
# define LOADARGS_2(name, __arg1, __arg2) \
long int arg2 = (long int) (__arg2); \
LOADARGS_1(name, __arg1); \
- extern void __illegally_sized_syscall_##name##_arg2 (void); \
+ extern void __illegally_sized_syscall_arg2 (void); \
if (__builtin_classify_type (__arg2) != 5 && sizeof (__arg2) > 4) \
- __illegally_sized_syscall_##name##_arg2 (); \
+ __illegally_sized_syscall_arg2 (); \
r4 = arg2
# define LOADARGS_3(name, __arg1, __arg2, __arg3) \
long int arg3 = (long int) (__arg3); \
LOADARGS_2(name, __arg1, __arg2); \
- extern void __illegally_sized_syscall_##name##_arg3 (void); \
+ extern void __illegally_sized_syscall_arg3 (void); \
if (__builtin_classify_type (__arg3) != 5 && sizeof (__arg3) > 4) \
- __illegally_sized_syscall_##name##_arg3 (); \
+ __illegally_sized_syscall_arg3 (); \
r5 = arg3
# define LOADARGS_4(name, __arg1, __arg2, __arg3, __arg4) \
long int arg4 = (long int) (__arg4); \
LOADARGS_3(name, __arg1, __arg2, __arg3); \
- extern void __illegally_sized_syscall_##name##_arg4 (void); \
+ extern void __illegally_sized_syscall_arg4 (void); \
if (__builtin_classify_type (__arg4) != 5 && sizeof (__arg4) > 4) \
- __illegally_sized_syscall_##name##_arg4 (); \
+ __illegally_sized_syscall_arg4 (); \
r6 = arg4
# define LOADARGS_5(name, __arg1, __arg2, __arg3, __arg4, __arg5) \
long int arg5 = (long int) (__arg5); \
LOADARGS_4(name, __arg1, __arg2, __arg3, __arg4); \
- extern void __illegally_sized_syscall_##name##_arg5 (void); \
+ extern void __illegally_sized_syscall_arg5 (void); \
if (__builtin_classify_type (__arg5) != 5 && sizeof (__arg5) > 4) \
- __illegally_sized_syscall_##name##_arg5 (); \
+ __illegally_sized_syscall_arg5 (); \
r7 = arg5
# define LOADARGS_6(name, __arg1, __arg2, __arg3, __arg4, __arg5, __arg6) \
long int arg6 = (long int) (__arg6); \
LOADARGS_5(name, __arg1, __arg2, __arg3, __arg4, __arg5); \
- extern void __illegally_sized_syscall_##name##_arg6 (void); \
+ extern void __illegally_sized_syscall_arg6 (void); \
if (__builtin_classify_type (__arg6) != 5 && sizeof (__arg6) > 4) \
- __illegally_sized_syscall_##name##_arg6 (); \
+ __illegally_sized_syscall_arg6 (); \
r8 = arg6
# define ASM_INPUT_0 "0" (r0)
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h b/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h
index 2e1adccd5d..38a376fa90 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h
@@ -91,7 +91,7 @@
the negation of the return value in the kernel gets reverted. */
#undef INTERNAL_SYSCALL
-#define INTERNAL_SYSCALL(name, err, nr, args...) \
+#define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
({ \
register long int r0 __asm__ ("r0"); \
register long int r3 __asm__ ("r3"); \
@@ -114,6 +114,8 @@
err = r0; \
(int) r3; \
})
+#define INTERNAL_SYSCALL(name, err, nr, args...) \
+ INTERNAL_SYSCALL_NCS (__NR_##name, err, nr, ##args)
#undef INTERNAL_SYSCALL_DECL
#define INTERNAL_SYSCALL_DECL(err) long int err
@@ -126,48 +128,48 @@
#define INTERNAL_SYSCALL_ERRNO(val, err) (val)
#define LOADARGS_0(name, dummy) \
- r0 = __NR_##name
+ r0 = name
#define LOADARGS_1(name, __arg1) \
long int arg1 = (long int) (__arg1); \
LOADARGS_0(name, 0); \
- extern void __illegally_sized_syscall_##name##_arg1 (void); \
+ extern void __illegally_sized_syscall_arg1 (void); \
if (__builtin_classify_type (__arg1) != 5 && sizeof (__arg1) > 8) \
- __illegally_sized_syscall_##name##_arg1 (); \
+ __illegally_sized_syscall_arg1 (); \
r3 = arg1
#define LOADARGS_2(name, __arg1, __arg2) \
long int arg2 = (long int) (__arg2); \
LOADARGS_1(name, __arg1); \
- extern void __illegally_sized_syscall_##name##_arg2 (void); \
+ extern void __illegally_sized_syscall_arg2 (void); \
if (__builtin_classify_type (__arg2) != 5 && sizeof (__arg2) > 8) \
- __illegally_sized_syscall_##name##_arg2 (); \
+ __illegally_sized_syscall_arg2 (); \
r4 = arg2
#define LOADARGS_3(name, __arg1, __arg2, __arg3) \
long int arg3 = (long int) (__arg3); \
LOADARGS_2(name, __arg1, __arg2); \
- extern void __illegally_sized_syscall_##name##_arg3 (void); \
+ extern void __illegally_sized_syscall_arg3 (void); \
if (__builtin_classify_type (__arg3) != 5 && sizeof (__arg3) > 8) \
- __illegally_sized_syscall_##name##_arg3 (); \
+ __illegally_sized_syscall_arg3 (); \
r5 = arg3
#define LOADARGS_4(name, __arg1, __arg2, __arg3, __arg4) \
long int arg4 = (long int) (__arg4); \
LOADARGS_3(name, __arg1, __arg2, __arg3); \
- extern void __illegally_sized_syscall_##name##_arg4 (void); \
+ extern void __illegally_sized_syscall_arg4 (void); \
if (__builtin_classify_type (__arg4) != 5 && sizeof (__arg4) > 8) \
- __illegally_sized_syscall_##name##_arg4 (); \
+ __illegally_sized_syscall_arg4 (); \
r6 = arg4
#define LOADARGS_5(name, __arg1, __arg2, __arg3, __arg4, __arg5) \
long int arg5 = (long int) (__arg5); \
LOADARGS_4(name, __arg1, __arg2, __arg3, __arg4); \
- extern void __illegally_sized_syscall_##name##_arg5 (void); \
+ extern void __illegally_sized_syscall_arg5 (void); \
if (__builtin_classify_type (__arg5) != 5 && sizeof (__arg5) > 8) \
- __illegally_sized_syscall_##name##_arg5 (); \
+ __illegally_sized_syscall_arg5 (); \
r7 = arg5
#define LOADARGS_6(name, __arg1, __arg2, __arg3, __arg4, __arg5, __arg6) \
long int arg6 = (long int) (__arg6); \
LOADARGS_5(name, __arg1, __arg2, __arg3, __arg4, __arg5); \
- extern void __illegally_sized_syscall_##name##_arg6 (void); \
+ extern void __illegally_sized_syscall_arg6 (void); \
if (__builtin_classify_type (__arg6) != 5 && sizeof (__arg6) > 8) \
- __illegally_sized_syscall_##name##_arg6 (); \
+ __illegally_sized_syscall_arg6 (); \
r8 = arg6
#define ASM_INPUT_0 "0" (r0)
diff --git a/sysdeps/unix/sysv/linux/setegid.c b/sysdeps/unix/sysv/linux/setegid.c
index 34e64a3dee..33e91c773a 100644
--- a/sysdeps/unix/sysv/linux/setegid.c
+++ b/sysdeps/unix/sysv/linux/setegid.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998, 2000, 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 1998, 2000, 2002, 2003, 2004 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
@@ -23,6 +23,8 @@
#include <sysdep.h>
#include "kernel-features.h"
+#include <pthread-functions.h>
+
#if defined __NR_setresgid || __ASSUME_SETRESGID_SYSCALL > 0
@@ -40,10 +42,10 @@ setegid (gid_t gid)
}
# if __ASSUME_32BITUIDS > 0 && defined __NR_setresgid32
- return INLINE_SYSCALL (setresgid32, 3, -1, gid, -1);
+ result = INLINE_SYSCALL (setresgid32, 3, -1, gid, -1);
# else
/* First try the syscall. */
- result = __setresgid (-1, gid, -1);
+ result = INLINE_SYSCALL (setresgid, 3, -1, gid, -1);
# if __ASSUME_SETRESGID_SYSCALL == 0
if (result == -1 && errno == ENOSYS)
/* No system call available. Use emulation. This may not work
@@ -51,11 +53,29 @@ setegid (gid_t gid)
equal to the real group ID, making it impossible to switch back. */
result = __setregid (-1, gid);
# endif
+# endif
- return result;
+#if defined HAVE_PTR__NPTL_SETXID && !defined SINGLE_THREAD
+ if (result == 0 && __libc_pthread_functions.ptr__nptl_setxid != NULL)
+ {
+ struct xid_command cmd;
+# ifdef __NR_setresgid32
+ cmd.syscall_no = __NR_setresgid32;
+# else
+ cmd.syscall_no = __NR_setresgid;
# endif
+ cmd.id[0] = -1;
+ cmd.id[1] = gid;
+ cmd.id[2] = -1;
+ __libc_pthread_functions.ptr__nptl_setxid (&cmd);
+ }
+#endif
+
+ return result;
}
+#ifndef setegid
libc_hidden_def (setegid)
+#endif
#else
# include <sysdeps/unix/bsd/setegid.c>
#endif
diff --git a/sysdeps/unix/sysv/linux/seteuid.c b/sysdeps/unix/sysv/linux/seteuid.c
index a1832d64bc..da03a1e6ef 100644
--- a/sysdeps/unix/sysv/linux/seteuid.c
+++ b/sysdeps/unix/sysv/linux/seteuid.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998, 1999, 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 1998, 1999, 2002, 2003, 2004 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
@@ -23,6 +23,8 @@
#include <sysdep.h>
#include "kernel-features.h"
+#include <pthread-functions.h>
+
#if defined __NR_setresuid || __ASSUME_SETRESUID_SYSCALL > 0
@@ -40,22 +42,40 @@ seteuid (uid_t uid)
}
# if __ASSUME_32BITUIDS > 0 && defined __NR_setresuid32
- return INLINE_SYSCALL (setresuid32, 3, -1, uid, -1);
+ result = INLINE_SYSCALL (setresuid32, 3, -1, uid, -1);
# else
/* First try the syscall. */
- result = __setresuid (-1, uid, -1);
-# if __ASSUME_SETRESUID_SYSCALL == 0
+ result = INLINE_SYSCALL (setresuid, 3, -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
# endif
- return result;
+#if defined HAVE_PTR__NPTL_SETXID && !defined SINGLE_THREAD
+ if (result == 0 && __libc_pthread_functions.ptr__nptl_setxid != NULL)
+ {
+ struct xid_command cmd;
+# ifdef __NR_setresuid32
+ cmd.syscall_no = __NR_setresuid32;
+# else
+ cmd.syscall_no = __NR_setresuid;
# endif
+ cmd.id[0] = -1;
+ cmd.id[1] = uid;
+ cmd.id[2] = -1;
+ __libc_pthread_functions.ptr__nptl_setxid (&cmd);
+ }
+#endif
+
+ return result;
}
+#ifndef seteuid
libc_hidden_def (seteuid)
+#endif
#else
# include <sysdeps/unix/bsd/seteuid.c>
#endif
diff --git a/sysdeps/unix/sysv/linux/setgid.c b/sysdeps/unix/sysv/linux/setgid.c
new file mode 100644
index 0000000000..dae642abb5
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/setgid.c
@@ -0,0 +1,53 @@
+/* Copyright (C) 1998, 2000, 2003, 2004 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 <errno.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+
+#include <linux/posix_types.h>
+#include "kernel-features.h"
+#include <pthread-functions.h>
+
+
+
+int
+__setgid (gid_t gid)
+{
+ int result;
+
+ result = INLINE_SYSCALL (setgid, 1, gid);
+
+#if defined HAVE_PTR__NPTL_SETXID && !defined SINGLE_THREAD
+ if (result == 0 && __libc_pthread_functions.ptr__nptl_setxid != NULL)
+ {
+ struct xid_command cmd;
+ cmd.syscall_no = __NR_setgid;
+ cmd.id[0] = gid;
+ __libc_pthread_functions.ptr__nptl_setxid (&cmd);
+ }
+#endif
+
+ return result;
+}
+#ifndef __setgid
+weak_alias (__setgid, setgid)
+#endif
diff --git a/sysdeps/unix/sysv/linux/setregid.c b/sysdeps/unix/sysv/linux/setregid.c
new file mode 100644
index 0000000000..1d539260ed
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/setregid.c
@@ -0,0 +1,53 @@
+/* Copyright (C) 1998, 2000, 2003, 2004 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 <errno.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+
+#include <linux/posix_types.h>
+#include "kernel-features.h"
+#include <pthread-functions.h>
+
+
+int
+__setregid (gid_t rgid, gid_t egid)
+{
+ int result;
+
+ result = INLINE_SYSCALL (setregid, 2, rgid, egid);
+
+#if defined HAVE_PTR__NPTL_SETXID && !defined SINGLE_THREAD
+ if (result == 0 && __libc_pthread_functions.ptr__nptl_setxid != NULL)
+ {
+ struct xid_command cmd;
+ cmd.syscall_no = __NR_setregid;
+ cmd.id[0] = rgid;
+ cmd.id[1] = egid;
+ __libc_pthread_functions.ptr__nptl_setxid (&cmd);
+ }
+#endif
+
+ return result;
+}
+#ifndef __setregid
+weak_alias (__setregid, setregid)
+#endif
diff --git a/sysdeps/unix/sysv/linux/setresgid.c b/sysdeps/unix/sysv/linux/setresgid.c
new file mode 100644
index 0000000000..ae61d42e6b
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/setresgid.c
@@ -0,0 +1,54 @@
+/* Copyright (C) 1998, 2000, 2003, 2004 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 <errno.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+
+#include <linux/posix_types.h>
+#include "kernel-features.h"
+#include <pthread-functions.h>
+
+
+int
+__setresgid (gid_t rgid, gid_t egid, gid_t sgid)
+{
+ int result;
+
+ result = INLINE_SYSCALL (setresgid, 3, rgid, egid, sgid);
+
+#if defined HAVE_PTR__NPTL_SETXID && !defined SINGLE_THREAD
+ if (result == 0 && __libc_pthread_functions.ptr__nptl_setxid != NULL)
+ {
+ struct xid_command cmd;
+ cmd.syscall_no = __NR_setresgid;
+ cmd.id[0] = rgid;
+ cmd.id[1] = egid;
+ cmd.id[2] = sgid;
+ __libc_pthread_functions.ptr__nptl_setxid (&cmd);
+ }
+#endif
+
+ return result;
+}
+#ifndef __setresgid
+weak_alias (__setresgid, setresgid)
+#endif
diff --git a/sysdeps/unix/sysv/linux/setresuid.c b/sysdeps/unix/sysv/linux/setresuid.c
new file mode 100644
index 0000000000..962d944aa4
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/setresuid.c
@@ -0,0 +1,54 @@
+/* Copyright (C) 1998, 2000, 2003, 2004 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 <errno.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+
+#include <linux/posix_types.h>
+#include "kernel-features.h"
+#include <pthread-functions.h>
+
+
+int
+__setresuid (uid_t ruid, uid_t euid, uid_t suid)
+{
+ int result;
+
+ result = INLINE_SYSCALL (setresuid, 3, ruid, euid, suid);
+
+#if defined HAVE_PTR__NPTL_SETXID && !defined SINGLE_THREAD
+ if (result == 0 && __libc_pthread_functions.ptr__nptl_setxid != NULL)
+ {
+ struct xid_command cmd;
+ cmd.syscall_no = __NR_setresuid;
+ cmd.id[0] = ruid;
+ cmd.id[1] = euid;
+ cmd.id[2] = suid;
+ __libc_pthread_functions.ptr__nptl_setxid (&cmd);
+ }
+#endif
+
+ return result;
+}
+#ifndef __setresuid
+weak_alias (__setresuid, setresuid)
+#endif
diff --git a/sysdeps/unix/sysv/linux/setreuid.c b/sysdeps/unix/sysv/linux/setreuid.c
new file mode 100644
index 0000000000..c9d841eca0
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/setreuid.c
@@ -0,0 +1,53 @@
+/* Copyright (C) 1998, 2000, 2003, 2004 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 <errno.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+
+#include <linux/posix_types.h>
+#include "kernel-features.h"
+#include <pthread-functions.h>
+
+
+int
+__setreuid (uid_t ruid, uid_t euid)
+{
+ int result;
+
+ result = INLINE_SYSCALL (setreuid, 2, ruid, euid);
+
+#if defined HAVE_PTR__NPTL_SETXID && !defined SINGLE_THREAD
+ if (result == 0 && __libc_pthread_functions.ptr__nptl_setxid != NULL)
+ {
+ struct xid_command cmd;
+ cmd.syscall_no = __NR_setreuid;
+ cmd.id[0] = ruid;
+ cmd.id[1] = euid;
+ __libc_pthread_functions.ptr__nptl_setxid (&cmd);
+ }
+#endif
+
+ return result;
+}
+#ifndef __setreuid
+weak_alias (__setreuid, setreuid)
+#endif
diff --git a/sysdeps/unix/sysv/linux/setuid.c b/sysdeps/unix/sysv/linux/setuid.c
new file mode 100644
index 0000000000..84f35176a1
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/setuid.c
@@ -0,0 +1,52 @@
+/* Copyright (C) 1998, 2000, 2003, 2004 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 <errno.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+
+#include <linux/posix_types.h>
+#include "kernel-features.h"
+#include <pthread-functions.h>
+
+
+int
+__setuid (uid_t uid)
+{
+ int result;
+
+ result = INLINE_SYSCALL (setuid, 1, uid);
+
+#if defined HAVE_PTR__NPTL_SETXID && !defined SINGLE_THREAD
+ if (result == 0 && __libc_pthread_functions.ptr__nptl_setxid != NULL)
+ {
+ struct xid_command cmd;
+ cmd.syscall_no = __NR_setuid;
+ cmd.id[0] = uid;
+ __libc_pthread_functions.ptr__nptl_setxid (&cmd);
+ }
+#endif
+
+ return result;
+}
+#ifndef __setuid
+weak_alias (__setuid, setuid)
+#endif
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/setegid.c b/sysdeps/unix/sysv/linux/sparc/sparc32/setegid.c
index 96f807484d..2e3a54c893 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/setegid.c
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/setegid.c
@@ -1,54 +1 @@
-/* Copyright (C) 1998, 2000, 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 <errno.h>
-#include <sys/syscall.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#ifdef __NR_setresgid32
-
-extern int __setresgid (gid_t rgid, gid_t egid, gid_t sgid);
-
-int
-setegid (gid_t gid)
-{
- int result;
-
- if (gid == (gid_t) ~0)
- {
- __set_errno (EINVAL);
- return -1;
- }
-
- /* First try the syscall. */
- result = __setresgid (-1, gid, -1);
-# if __ASSUME_SETRESGID_SYSCALL == 0
- if (result == -1 && errno == ENOSYS)
- /* No system call available. Use emulation. This may not work
- since `setregid' also sets the saved group ID when GID is not
- equal to the real group ID, making it impossible to switch back. */
- result = __setregid (-1, gid);
-# endif
-
- return result;
-}
-libc_hidden_def (setegid)
-#else
-# include <sysdeps/unix/bsd/setegid.c>
-#endif
+#include <sysdeps/unix/sysv/linux/i386/setegid.c>
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/seteuid.c b/sysdeps/unix/sysv/linux/sparc/sparc32/seteuid.c
index 34638ce4be..18e41d08c1 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/seteuid.c
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/seteuid.c
@@ -1,56 +1 @@
-/* Copyright (C) 1998, 1999, 2000, 2002 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 <errno.h>
-#include <sys/syscall.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include "kernel-features.h"
-
-#if defined __NR_setresuid32 || __ASSUME_SETRESUID_SYSCALL > 0
-
-extern int __setresuid (uid_t ruid, uid_t euid, uid_t suid);
-
-int
-seteuid (uid_t uid)
-{
- int result;
-
- if (uid == (uid_t) ~0)
- {
- __set_errno (EINVAL);
- return -1;
- }
-
- /* 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;
-}
-libc_hidden_def (seteuid)
-#else
-# include <sysdeps/unix/bsd/seteuid.c>
-#endif
+#include <sysdeps/unix/sysv/linux/i386/seteuid.c>
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/setresgid.c b/sysdeps/unix/sysv/linux/sparc/sparc32/setresgid.c
new file mode 100644
index 0000000000..daca1a4833
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/setresgid.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/setresgid.c>
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/setresuid.c b/sysdeps/unix/sysv/linux/sparc/sparc32/setresuid.c
new file mode 100644
index 0000000000..3aeabe9ad7
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/setresuid.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/setresuid.c>
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/syscalls.list b/sysdeps/unix/sysv/linux/sparc/sparc32/syscalls.list
index 6d8e32f9f7..2bfe376a3b 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/syscalls.list
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/syscalls.list
@@ -2,7 +2,5 @@
setrlimit - setrlimit 2 __setrlimit setrlimit
getrlimit - getrlimit 2 __getrlimit getrlimit
-setresuid - setresuid32 3 __setresuid setresuid
-setresgid - setresgid32 3 __setresgid setresgid
getresuid - getresuid32 3 getresuid
getresgid - getresgid32 3 getresgid
diff --git a/sysdeps/unix/sysv/linux/x86_64/sysdep.h b/sysdeps/unix/sysv/linux/x86_64/sysdep.h
index 09f8492cc6..56e4422a73 100644
--- a/sysdeps/unix/sysv/linux/x86_64/sysdep.h
+++ b/sysdeps/unix/sysv/linux/x86_64/sysdep.h
@@ -236,18 +236,19 @@
#undef INTERNAL_SYSCALL_DECL
#define INTERNAL_SYSCALL_DECL(err) do { } while (0)
-#undef INTERNAL_SYSCALL
-#define INTERNAL_SYSCALL(name, err, nr, args...) \
+#define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
({ \
unsigned long resultvar; \
LOAD_ARGS_##nr (args) \
LOAD_REGS_##nr \
asm volatile ( \
- "movq %1, %%rax\n\t" \
"syscall\n\t" \
: "=a" (resultvar) \
- : "i" (__NR_##name) ASM_ARGS_##nr : "memory", "cc", "r11", "cx"); \
+ : "0" (name) ASM_ARGS_##nr : "memory", "cc", "r11", "cx"); \
(long) resultvar; })
+#undef INTERNAL_SYSCALL
+#define INTERNAL_SYSCALL(name, err, nr, args...) \
+ INTERNAL_SYSCALL_NCS (__NR_##name, err, nr, ##args)
#undef INTERNAL_SYSCALL_ERROR_P
#define INTERNAL_SYSCALL_ERROR_P(val, err) \