Update to LGPL v2.1.
[kopensolaris-gnu/glibc.git] / sysdeps / unix / sysv / linux / i386 / getresuid.c
1 /* Copyright (C) 1998, 2000 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3
4    The GNU C Library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Lesser General Public
6    License as published by the Free Software Foundation; either
7    version 2.1 of the License, or (at your option) any later version.
8
9    The GNU C Library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Lesser General Public License for more details.
13
14    You should have received a copy of the GNU Lesser General Public
15    License along with the GNU C Library; if not, write to the Free
16    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17    02111-1307 USA.  */
18
19 #include <errno.h>
20 #include <unistd.h>
21 #include <sys/types.h>
22
23 #include <linux/posix_types.h>
24
25 #include <sysdep.h>
26 #include <sys/syscall.h>
27 #include <bp-checks.h>
28
29 #include "kernel-features.h"
30
31 #ifdef __NR_getresuid
32
33 extern int __syscall_getresuid (__kernel_uid_t *__unbounded ruid,
34                                 __kernel_uid_t *__unbounded euid,
35                                 __kernel_uid_t *__unbounded suid);
36
37 # ifdef __NR_getresuid32
38 extern int __syscall_getresuid32 (__kernel_uid32_t *__unbounded ruid,
39                                   __kernel_uid32_t *__unbounded euid,
40                                   __kernel_uid32_t *__unbounded suid);
41 #  if __ASSUME_32BITUIDS == 0
42 /* This variable is shared with all files that need to check for 32bit
43    uids.  */
44 extern int __libc_missing_32bit_uids;
45 #  endif
46 # endif /* __NR_getresuid32 */
47
48 int
49 getresuid (uid_t *ruid, uid_t *euid, uid_t *suid)
50 {
51 # if __ASSUME_32BITUIDS > 0
52   return INLINE_SYSCALL (getresuid32, 3, CHECK_1 (ruid),
53                          CHECK_1 (euid), CHECK_1 (suid));
54 # else
55   __kernel_uid_t k_ruid, k_euid, k_suid;
56   int result;
57 #  ifdef __NR_getresuid32
58   if (__libc_missing_32bit_uids <= 0)
59     {
60       int r;
61       int saved_errno = errno;
62
63       r = INLINE_SYSCALL (getresuid32, 3, CHECK_1 (ruid),
64                           CHECK_1 (euid), CHECK_1 (suid));
65       if (r == 0 || errno != ENOSYS)
66         return r;
67
68       __set_errno (saved_errno);
69       __libc_missing_32bit_uids = 1;
70     }
71 #  endif /* __NR_getresuid32 */
72
73   result = INLINE_SYSCALL (getresuid, 3, __ptrvalue (&k_ruid),
74                            __ptrvalue (&k_euid), __ptrvalue (&k_suid));
75
76   if (result == 0)
77     {
78       *ruid = (uid_t) k_ruid;
79       *euid = (uid_t) k_euid;
80       *suid = (uid_t) k_suid;
81     }
82
83   return result;
84 # endif
85 }
86 #else
87 # include <sysdeps/generic/getresuid.c>
88 #endif