diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2015-08-21 04:46:39 -0700 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2015-08-21 04:46:53 -0700 |
commit | 0c5b8b5941e036dcaac69cecee9f01fdf9218e6e (patch) | |
tree | 3c147bf3d4f07169bc0812858d0c108773e575cd | |
parent | 8d9e08981e1ac5ee90209adb3042206e9fffd286 (diff) | |
download | glibc-0c5b8b5941e036dcaac69cecee9f01fdf9218e6e.tar.gz |
Add INLINE_SYSCALL_RETURN/INLINE_SYSCALL_ERROR_RETURN
For ia32 PIC, the first thing of many syscalls does is to call
__x86.get_pc_thunk.reg to load PC into reg in case there is an error,
which is required for setting errno. In most cases, there are no
errors. But we still call __x86.get_pc_thunk.reg. This patch adds
INLINE_SYSCALL_RETURN and INLINE_SYSCALL_ERROR_RETURN so that i386
can optimize setting errno by branching to the internal __syscall_error
without PLT.
INLINE_SYSCALL_ERROR_RETURN is designed to take the negative error
number returned from the majority of Linux kernels for which negating
is a no-op with INTERNAL_SYSCALL_ERRNO.
With i386 INLINE_SYSCALL_RETURN, INLINE_SYSCALL_ERROR_RETURN and
i386 syscall inlining optimization for GCC 5, for
sysdeps/unix/sysv/linux/fchmodat.c with -O2 -march=i686
-mtune=generic, GCC 5.2 now generates:
<fchmodat>:
0: push %ebx
1: mov 0x14(%esp),%eax
5: mov 0x8(%esp),%ebx
9: mov 0xc(%esp),%ecx
d: mov 0x10(%esp),%edx
11: test $0xfffffeff,%eax
16: jne 38 <fchmodat+0x38>
18: test $0x1,%ah
1b: jne 48 <fchmodat+0x48>
1d: mov $0x132,%eax
22: call *%gs:0x10
29: cmp $0xfffff000,%eax
2e: ja 58 <fchmodat+0x58>
30: pop %ebx
31: ret
32: lea 0x0(%esi),%esi
38: pop %ebx
39: mov $0xffffffea,%eax
3e: jmp 3f <fchmodat+0x3f> 3f: R_386_PC32 __syscall_error
43: nop
44: lea 0x0(%esi,%eiz,1),%esi
48: pop %ebx
49: mov $0xffffffa1,%eax
4e: jmp 4f <fchmodat+0x4f> 4f: R_386_PC32 __syscall_error
53: nop
54: lea 0x0(%esi,%eiz,1),%esi
58: pop %ebx
59: jmp 5a <fchmodat+0x5a> 5a: R_386_PC32 __syscall_error
instead of
<fchmodat>:
0: sub $0x8,%esp
3: mov 0x18(%esp),%eax
7: mov %ebx,(%esp)
a: call b <fchmodat+0xb> b: R_386_PC32 __x86.get_pc_thunk.bx
f: add $0x2,%ebx 11: R_386_GOTPC _GLOBAL_OFFSET_TABLE_
15: mov %edi,0x4(%esp)
19: test $0xfffffeff,%eax
1e: jne 70 <fchmodat+0x70>
20: test $0x1,%ah
23: jne 88 <fchmodat+0x88>
25: mov 0x14(%esp),%edx
29: mov 0x10(%esp),%ecx
2d: mov 0xc(%esp),%edi
31: xchg %ebx,%edi
33: mov $0x132,%eax
38: call *%gs:0x10
3f: xchg %edi,%ebx
41: cmp $0xfffff000,%eax
46: ja 58 <fchmodat+0x58>
48: mov (%esp),%ebx
4b: mov 0x4(%esp),%edi
4f: add $0x8,%esp
52: ret
53: nop
54: lea 0x0(%esi,%eiz,1),%esi
58: mov 0x0(%ebx),%edx 5a: R_386_TLS_GOTIE __libc_errno
5e: neg %eax
60: mov %eax,%gs:(%edx)
63: mov $0xffffffff,%eax
68: jmp 48 <fchmodat+0x48>
6a: lea 0x0(%esi),%esi
70: mov 0x0(%ebx),%eax 72: R_386_TLS_GOTIE __libc_errno
76: movl $0x16,%gs:(%eax)
7d: mov $0xffffffff,%eax
82: jmp 48 <fchmodat+0x48>
84: lea 0x0(%esi,%eiz,1),%esi
88: mov 0x0(%ebx),%eax 8a: R_386_TLS_GOTIE __libc_errno
8e: movl $0x5f,%gs:(%eax)
95: mov $0xffffffff,%eax
9a: jmp 48 <fchmodat+0x48>
* sysdeps/unix/sysdep.h (INLINE_SYSCALL_RETURN): New.
(INLINE_SYSCALL_ERROR_RETURN): Likewise.
* sysdeps/unix/sysv/linux/adjtime.c (ADJTIME): Use
INLINE_SYSCALL_RETURN and INLINE_SYSCALL_ERROR_RETURN.
* sysdeps/unix/sysv/linux/aio_sigqueue.c (__aio_sigqueue):
Likewise.
* sysdeps/unix/sysv/linux/dl-openat64.c (openat64): Likewise.
* sysdeps/unix/sysv/linux/eventfd.c (eventfd): Likewise.
* sysdeps/unix/sysv/linux/faccessat.c (faccessat): Likewise.
* sysdeps/unix/sysv/linux/fchmodat.c (fchmodat): Likewise.
* sysdeps/unix/sysv/linux/fcntl.c (do_fcntl): Likewise.
* sysdeps/unix/sysv/linux/fstatfs64.c (__fstatfs64): Likewise.
* sysdeps/unix/sysv/linux/ftruncate64.c (__ftruncate64): Likewise.
* sysdeps/unix/sysv/linux/futimens.c (futimens): Likewise.
* sysdeps/unix/sysv/linux/futimes.c (__futimes): Likewise.
* sysdeps/unix/sysv/linux/futimesat.c (futimesat): Likewise.
* sysdeps/unix/sysv/linux/fxstat.c (__fxstat): Likewise.
* sysdeps/unix/sysv/linux/fxstat64.c (___fxstat64): Likewise.
* sysdeps/unix/sysv/linux/fxstatat.c (__fxstatat): Likewise.
* sysdeps/unix/sysv/linux/fxstatat64.c (__fxstatat64): Likewise.
* sysdeps/unix/sysv/linux/gai_sigqueue.c (__gai_sigqueue):
Likewise.
* sysdeps/unix/sysv/linux/getpriority.c (__getpriority): Likewise.
* sysdeps/unix/sysv/linux/getrlimit64.c (__getrlimit64): Likewise.
* sysdeps/unix/sysv/linux/llseek.c (__llseek): Likewise.
* sysdeps/unix/sysv/linux/lutimes.c (lutimes): Likewise.
* sysdeps/unix/sysv/linux/lxstat.c (__lxstat): Likewise.
* sysdeps/unix/sysv/linux/lxstat64.c (___lxstat64): Likewise.
* sysdeps/unix/sysv/linux/mmap64.c (__mmap64): Likewise.
* sysdeps/unix/sysv/linux/mq_close.c (mq_close): Likewise.
* sysdeps/unix/sysv/linux/mq_open.c (__mq_open): Likewise.
* sysdeps/unix/sysv/linux/mq_unlink.c (mq_unlink): Likewise.
* sysdeps/unix/sysv/linux/msgget.c (msgget): Likewise.
* sysdeps/unix/sysv/linux/prlimit.c (prlimit): Likewise.
* sysdeps/unix/sysv/linux/pt-raise.c (raise): Likewise.
* sysdeps/unix/sysv/linux/raise.c (raise): Likewise.
* sysdeps/unix/sysv/linux/readahead.c (__readahead): Likewise.
* sysdeps/unix/sysv/linux/reboot.c (reboot): Likewise.
* sysdeps/unix/sysv/linux/semget.c (semget): Likewise.
* sysdeps/unix/sysv/linux/semop.c (semop): Likewise.
* sysdeps/unix/sysv/linux/semtimedop.c (semtimedop): Likewise.
* sysdeps/unix/sysv/linux/setrlimit64.c (setrlimit64): Likewise.
* sysdeps/unix/sysv/linux/shmat.c (shmat): Likewise.
* sysdeps/unix/sysv/linux/shmdt.c (shmdt): Likewise.
* sysdeps/unix/sysv/linux/shmget.c (shmget): Likewise.
* sysdeps/unix/sysv/linux/signalfd.c (signalfd): Likewise.
* sysdeps/unix/sysv/linux/sigpending.c (sigpending): Likewise.
* sysdeps/unix/sysv/linux/sigprocmask.c ( __sigprocmask): Likewise.
* sysdeps/unix/sysv/linux/sigqueue.c (__sigqueue): Likewise.
* sysdeps/unix/sysv/linux/speed.c (cfsetospeed): Likewise.
* sysdeps/unix/sysv/linux/statfs64.c (__statfs64): Likewise.
* sysdeps/unix/sysv/linux/sysctl.c (__sysctl): Likewise.
* sysdeps/unix/sysv/linux/tcsendbrk.c (tcsendbreak): Likewise.
* sysdeps/unix/sysv/linux/tcsetattr.c (tcsetattr): Likewise.
* sysdeps/unix/sysv/linux/timer_getoverr.c (timer_getoverrun):
Likewise.
* sysdeps/unix/sysv/linux/timer_gettime.c (timer_gettime):
Likewise.
* sysdeps/unix/sysv/linux/timer_settime.c (timer_settime):
Likewise.
* sysdeps/unix/sysv/linux/truncate64.c (truncate64): Likewise.
* sysdeps/unix/sysv/linux/ustat.c (ustat): Likewise.
* sysdeps/unix/sysv/linux/utimensat.c (utimensat): Likewise.
* sysdeps/unix/sysv/linux/utimes.c (__utimes): Likewise.
* sysdeps/unix/sysv/linux/xmknod.c (__xmknod): Likewise.
* sysdeps/unix/sysv/linux/xmknodat.c (__xmknodat): Likewise.
* sysdeps/unix/sysv/linux/xstat.c (__xstat): Likewise.
* sysdeps/unix/sysv/linux/xstat64.c (___xstat64): Likewise.
* sysdeps/unix/sysv/linux/xstatconv.c (__xstat_conv): Likewise.
(__xstat64_conv): Likewise.
(__xstat32_conv): Likewise.
* sysdeps/unix/sysv/linux/sched_getaffinity.c
(__sched_getaffinity_new): Add libc_hidden_proto and
libc_hidden_def. Use INLINE_SYSCALL_ERROR_RETURN.
64 files changed, 364 insertions, 292 deletions
@@ -1,3 +1,80 @@ +2015-08-21 H.J. Lu <hongjiu.lu@intel.com> + + * sysdeps/unix/sysdep.h (INLINE_SYSCALL_RETURN): New. + (INLINE_SYSCALL_ERROR_RETURN): Likewise. + * sysdeps/unix/sysv/linux/adjtime.c (ADJTIME): Use + INLINE_SYSCALL_RETURN and INLINE_SYSCALL_ERROR_RETURN. + * sysdeps/unix/sysv/linux/aio_sigqueue.c (__aio_sigqueue): + Likewise. + * sysdeps/unix/sysv/linux/dl-openat64.c (openat64): Likewise. + * sysdeps/unix/sysv/linux/eventfd.c (eventfd): Likewise. + * sysdeps/unix/sysv/linux/faccessat.c (faccessat): Likewise. + * sysdeps/unix/sysv/linux/fchmodat.c (fchmodat): Likewise. + * sysdeps/unix/sysv/linux/fcntl.c (do_fcntl): Likewise. + * sysdeps/unix/sysv/linux/fstatfs64.c (__fstatfs64): Likewise. + * sysdeps/unix/sysv/linux/ftruncate64.c (__ftruncate64): Likewise. + * sysdeps/unix/sysv/linux/futimens.c (futimens): Likewise. + * sysdeps/unix/sysv/linux/futimes.c (__futimes): Likewise. + * sysdeps/unix/sysv/linux/futimesat.c (futimesat): Likewise. + * sysdeps/unix/sysv/linux/fxstat.c (__fxstat): Likewise. + * sysdeps/unix/sysv/linux/fxstat64.c (___fxstat64): Likewise. + * sysdeps/unix/sysv/linux/fxstatat.c (__fxstatat): Likewise. + * sysdeps/unix/sysv/linux/fxstatat64.c (__fxstatat64): Likewise. + * sysdeps/unix/sysv/linux/gai_sigqueue.c (__gai_sigqueue): + Likewise. + * sysdeps/unix/sysv/linux/getpriority.c (__getpriority): Likewise. + * sysdeps/unix/sysv/linux/getrlimit64.c (__getrlimit64): Likewise. + * sysdeps/unix/sysv/linux/llseek.c (__llseek): Likewise. + * sysdeps/unix/sysv/linux/lutimes.c (lutimes): Likewise. + * sysdeps/unix/sysv/linux/lxstat.c (__lxstat): Likewise. + * sysdeps/unix/sysv/linux/lxstat64.c (___lxstat64): Likewise. + * sysdeps/unix/sysv/linux/mmap64.c (__mmap64): Likewise. + * sysdeps/unix/sysv/linux/mq_close.c (mq_close): Likewise. + * sysdeps/unix/sysv/linux/mq_open.c (__mq_open): Likewise. + * sysdeps/unix/sysv/linux/mq_unlink.c (mq_unlink): Likewise. + * sysdeps/unix/sysv/linux/msgget.c (msgget): Likewise. + * sysdeps/unix/sysv/linux/prlimit.c (prlimit): Likewise. + * sysdeps/unix/sysv/linux/pt-raise.c (raise): Likewise. + * sysdeps/unix/sysv/linux/raise.c (raise): Likewise. + * sysdeps/unix/sysv/linux/readahead.c (__readahead): Likewise. + * sysdeps/unix/sysv/linux/reboot.c (reboot): Likewise. + * sysdeps/unix/sysv/linux/semget.c (semget): Likewise. + * sysdeps/unix/sysv/linux/semop.c (semop): Likewise. + * sysdeps/unix/sysv/linux/semtimedop.c (semtimedop): Likewise. + * sysdeps/unix/sysv/linux/setrlimit64.c (setrlimit64): Likewise. + * sysdeps/unix/sysv/linux/shmat.c (shmat): Likewise. + * sysdeps/unix/sysv/linux/shmdt.c (shmdt): Likewise. + * sysdeps/unix/sysv/linux/shmget.c (shmget): Likewise. + * sysdeps/unix/sysv/linux/signalfd.c (signalfd): Likewise. + * sysdeps/unix/sysv/linux/sigpending.c (sigpending): Likewise. + * sysdeps/unix/sysv/linux/sigprocmask.c ( __sigprocmask): Likewise. + * sysdeps/unix/sysv/linux/sigqueue.c (__sigqueue): Likewise. + * sysdeps/unix/sysv/linux/speed.c (cfsetospeed): Likewise. + * sysdeps/unix/sysv/linux/statfs64.c (__statfs64): Likewise. + * sysdeps/unix/sysv/linux/sysctl.c (__sysctl): Likewise. + * sysdeps/unix/sysv/linux/tcsendbrk.c (tcsendbreak): Likewise. + * sysdeps/unix/sysv/linux/tcsetattr.c (tcsetattr): Likewise. + * sysdeps/unix/sysv/linux/timer_getoverr.c (timer_getoverrun): + Likewise. + * sysdeps/unix/sysv/linux/timer_gettime.c (timer_gettime): + Likewise. + * sysdeps/unix/sysv/linux/timer_settime.c (timer_settime): + Likewise. + * sysdeps/unix/sysv/linux/truncate64.c (truncate64): Likewise. + * sysdeps/unix/sysv/linux/ustat.c (ustat): Likewise. + * sysdeps/unix/sysv/linux/utimensat.c (utimensat): Likewise. + * sysdeps/unix/sysv/linux/utimes.c (__utimes): Likewise. + * sysdeps/unix/sysv/linux/xmknod.c (__xmknod): Likewise. + * sysdeps/unix/sysv/linux/xmknodat.c (__xmknodat): Likewise. + * sysdeps/unix/sysv/linux/xstat.c (__xstat): Likewise. + * sysdeps/unix/sysv/linux/xstat64.c (___xstat64): Likewise. + * sysdeps/unix/sysv/linux/xstatconv.c (__xstat_conv): Likewise. + (__xstat64_conv): Likewise. + (__xstat32_conv): Likewise. + * sysdeps/unix/sysv/linux/sched_getaffinity.c + (__sched_getaffinity_new): Add libc_hidden_proto and + libc_hidden_def. Use INLINE_SYSCALL_ERROR_RETURN. + 2015-08-20 Joseph Myers <joseph@codesourcery.com> * timezone/Makefile (CFLAGS-zdump.c): Remove diff --git a/sysdeps/unix/sysdep.h b/sysdeps/unix/sysdep.h index 52dad582ce..c4316db4bc 100644 --- a/sysdeps/unix/sysdep.h +++ b/sysdeps/unix/sysdep.h @@ -73,3 +73,22 @@ #ifndef INLINE_SYSCALL #define INLINE_SYSCALL(name, nr, args...) __syscall_##name (args) #endif + +/* Similar to INLINE_SYSCALL, but with return type. It should only be + used with function return. */ +#ifndef INLINE_SYSCALL_RETURN +#define INLINE_SYSCALL_RETURN(name, nr, type, args...) \ + INLINE_SYSCALL (name, nr, args) +#endif + +/* Set error number and return value. It should only be used with + function return. ERR is the negative error number returned from + the majority of Linux kernels for which -ERR is no-op + with INTERNAL_SYSCALL_ERRNO. */ +#ifndef INLINE_SYSCALL_ERROR_RETURN +#define INLINE_SYSCALL_ERROR_RETURN(err, type, value) \ + ({ \ + __set_errno (-err); \ + (type) (value); \ + }) +#endif diff --git a/sysdeps/unix/sysv/linux/adjtime.c b/sysdeps/unix/sysv/linux/adjtime.c index b6fb7cf5db..ad54cf8ff8 100644 --- a/sysdeps/unix/sysv/linux/adjtime.c +++ b/sysdeps/unix/sysv/linux/adjtime.c @@ -61,10 +61,7 @@ ADJTIME (const struct TIMEVAL *itv, struct TIMEVAL *otv) tmp.tv_sec = itv->tv_sec + itv->tv_usec / 1000000L; tmp.tv_usec = itv->tv_usec % 1000000L; if (tmp.tv_sec > MAX_SEC || tmp.tv_sec < MIN_SEC) - { - __set_errno (EINVAL); - return -1; - } + return INLINE_SYSCALL_ERROR_RETURN (-EINVAL, int, -1); tntx.offset = tmp.tv_usec + tmp.tv_sec * 1000000L; tntx.modes = ADJ_OFFSET_SINGLESHOT; } diff --git a/sysdeps/unix/sysv/linux/aio_sigqueue.c b/sysdeps/unix/sysv/linux/aio_sigqueue.c index 6a48e6251b..c56b94f911 100644 --- a/sysdeps/unix/sysv/linux/aio_sigqueue.c +++ b/sysdeps/unix/sysv/linux/aio_sigqueue.c @@ -47,7 +47,8 @@ __aio_sigqueue (sig, val, caller_pid) info.si_uid = getuid (); info.si_value = val; - return INLINE_SYSCALL (rt_sigqueueinfo, 3, info.si_pid, sig, &info); + return INLINE_SYSCALL_RETURN (rt_sigqueueinfo, 3, int, info.si_pid, + sig, &info); } #else # include <rt/aio_sigqueue.c> diff --git a/sysdeps/unix/sysv/linux/dl-openat64.c b/sysdeps/unix/sysv/linux/dl-openat64.c index 732097dd92..ffb13f3acb 100644 --- a/sysdeps/unix/sysv/linux/dl-openat64.c +++ b/sysdeps/unix/sysv/linux/dl-openat64.c @@ -31,9 +31,9 @@ openat64 (dfd, file, oflag) assert (!__OPEN_NEEDS_MODE (oflag)); #ifdef __NR_openat - return INLINE_SYSCALL (openat, 3, dfd, file, oflag | O_LARGEFILE); + return INLINE_SYSCALL_RETURN (openat, 3, int, dfd, file, + oflag | O_LARGEFILE); #else - __set_errno (ENOSYS); - return -1; + return INLINE_SYSCALL_ERROR_RETURN (-ENOSYS, int, -1); #endif } diff --git a/sysdeps/unix/sysv/linux/eventfd.c b/sysdeps/unix/sysv/linux/eventfd.c index d4ffb3cedc..1496a0e651 100644 --- a/sysdeps/unix/sysv/linux/eventfd.c +++ b/sysdeps/unix/sysv/linux/eventfd.c @@ -25,11 +25,14 @@ int eventfd (unsigned int count, int flags) { #ifdef __NR_eventfd2 - int res = INLINE_SYSCALL (eventfd2, 2, count, flags); # ifndef __ASSUME_EVENTFD2 - if (res != -1 || errno != ENOSYS) -# endif + INTERNAL_SYSCALL_DECL (err); + int res = INTERNAL_SYSCALL (eventfd2, err, 2, count, flags); + if (!__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (res, err)) + || INTERNAL_SYSCALL_ERRNO (res, err) != ENOSYS) return res; +# endif + return INLINE_SYSCALL_RETURN (eventfd2, 2, int, count, flags); #endif #ifndef __ASSUME_EVENTFD2 @@ -38,16 +41,12 @@ eventfd (unsigned int count, int flags) kernel (sys_indirect) before implementing setting flags like O_NONBLOCK etc. */ if (flags != 0) - { - __set_errno (EINVAL); - return -1; - } + return INLINE_SYSCALL_ERROR_RETURN (-EINVAL, int, -1) # ifdef __NR_eventfd - return INLINE_SYSCALL (eventfd, 1, count); + return INLINE_SYSCALL_RETURN (eventfd, 1, int, count) # else - __set_errno (ENOSYS); - return -1; + return INLINE_SYSCALL_ERROR_RETURN (-ENOSYS, int, -1) # endif #elif !defined __NR_eventfd2 # error "__ASSUME_EVENTFD2 defined but not __NR_eventfd2" diff --git a/sysdeps/unix/sysv/linux/faccessat.c b/sysdeps/unix/sysv/linux/faccessat.c index 1bb544fd4d..6a0b1b7018 100644 --- a/sysdeps/unix/sysv/linux/faccessat.c +++ b/sysdeps/unix/sysv/linux/faccessat.c @@ -35,13 +35,10 @@ faccessat (fd, file, mode, flag) int flag; { if (flag & ~(AT_SYMLINK_NOFOLLOW | AT_EACCESS)) - { - __set_errno (EINVAL); - return -1; - } + return INLINE_SYSCALL_ERROR_RETURN (-EINVAL, int, -1); if ((flag == 0 || ((flag & ~AT_EACCESS) == 0 && ! __libc_enable_secure))) - return INLINE_SYSCALL (faccessat, 3, fd, file, mode); + return INLINE_SYSCALL_RETURN (faccessat, 3, int, fd, file, mode); struct stat64 stats; if (__fxstatat64 (_STAT_VER, fd, file, &stats, flag & AT_SYMLINK_NOFOLLOW)) @@ -74,6 +71,5 @@ faccessat (fd, file, mode, flag) if (granted == mode) return 0; - __set_errno (EACCES); - return -1; + return INLINE_SYSCALL_ERROR_RETURN (-EACCES, int, -1); } diff --git a/sysdeps/unix/sysv/linux/fchmodat.c b/sysdeps/unix/sysv/linux/fchmodat.c index e278426de1..025634b278 100644 --- a/sysdeps/unix/sysv/linux/fchmodat.c +++ b/sysdeps/unix/sysv/linux/fchmodat.c @@ -34,17 +34,11 @@ fchmodat (fd, file, mode, flag) int flag; { if (flag & ~AT_SYMLINK_NOFOLLOW) - { - __set_errno (EINVAL); - return -1; - } + return INLINE_SYSCALL_ERROR_RETURN (-EINVAL, int, -1); #ifndef __NR_lchmod /* Linux so far has no lchmod syscall. */ if (flag & AT_SYMLINK_NOFOLLOW) - { - __set_errno (ENOTSUP); - return -1; - } + return INLINE_SYSCALL_ERROR_RETURN (-ENOTSUP, int, -1); #endif - return INLINE_SYSCALL (fchmodat, 3, fd, file, mode); + return INLINE_SYSCALL_RETURN (fchmodat, 3, int, fd, file, mode); } diff --git a/sysdeps/unix/sysv/linux/fcntl.c b/sysdeps/unix/sysv/linux/fcntl.c index fa184db7fe..a9a6b6548b 100644 --- a/sysdeps/unix/sysv/linux/fcntl.c +++ b/sysdeps/unix/sysv/linux/fcntl.c @@ -28,7 +28,7 @@ static int do_fcntl (int fd, int cmd, void *arg) { if (cmd != F_GETOWN) - return INLINE_SYSCALL (fcntl, 3, fd, cmd, arg); + return INLINE_SYSCALL_RETURN (fcntl, 3, int, fd, cmd, arg); INTERNAL_SYSCALL_DECL (err); struct f_owner_ex fex; @@ -36,8 +36,8 @@ do_fcntl (int fd, int cmd, void *arg) if (!INTERNAL_SYSCALL_ERROR_P (res, err)) return fex.type == F_OWNER_GID ? -fex.pid : fex.pid; - __set_errno (INTERNAL_SYSCALL_ERRNO (res, err)); - return -1; + return INLINE_SYSCALL_ERROR_RETURN (-INTERNAL_SYSCALL_ERRNO (res, err), + int, -1); } diff --git a/sysdeps/unix/sysv/linux/fstatfs64.c b/sysdeps/unix/sysv/linux/fstatfs64.c index af8383010f..bba99186b5 100644 --- a/sysdeps/unix/sysv/linux/fstatfs64.c +++ b/sysdeps/unix/sysv/linux/fstatfs64.c @@ -35,12 +35,17 @@ __fstatfs64 (int fd, struct statfs64 *buf) if (! __no_statfs64) # endif { - int result = INLINE_SYSCALL (fstatfs64, 3, fd, sizeof (*buf), buf); - # if __ASSUME_STATFS64 == 0 - if (result == 0 || errno != ENOSYS) -# endif + INTERNAL_SYSCALL_DECL (err); + int result = INTERNAL_SYSCALL (fstatfs64, err, 3, fd, + sizeof (*buf), buf); + if (!__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (result, err)) + || INTERNAL_SYSCALL_ERRNO (result, err) != ENOSYS) return result; +# else + return INLINE_SYSCALL_RETURN (fstatfs64, 3, int, fd, + sizeof (*buf), buf); +# endif # if __ASSUME_STATFS64 == 0 __no_statfs64 = 1; diff --git a/sysdeps/unix/sysv/linux/ftruncate64.c b/sysdeps/unix/sysv/linux/ftruncate64.c index cc3c43c74b..b466229aa6 100644 --- a/sysdeps/unix/sysv/linux/ftruncate64.c +++ b/sysdeps/unix/sysv/linux/ftruncate64.c @@ -29,8 +29,7 @@ __ftruncate64 (int fd, off64_t length) { unsigned int low = length & 0xffffffff; unsigned int high = length >> 32; - int result = INLINE_SYSCALL (ftruncate64, 3, fd, - __LONG_LONG_PAIR (high, low)); - return result; + return INLINE_SYSCALL_RETURN (ftruncate64, 3, int, fd, + __LONG_LONG_PAIR (high, low)); } weak_alias (__ftruncate64, ftruncate64) diff --git a/sysdeps/unix/sysv/linux/futimens.c b/sysdeps/unix/sysv/linux/futimens.c index 5f2b8a56cd..dfc21c0139 100644 --- a/sysdeps/unix/sysv/linux/futimens.c +++ b/sysdeps/unix/sysv/linux/futimens.c @@ -33,15 +33,11 @@ futimens (int fd, const struct timespec tsp[2]) { #ifdef __NR_utimensat if (fd < 0) - { - __set_errno (EBADF); - return -1; - } + return INLINE_SYSCALL_ERROR_RETURN (-EBADF, int, -1); /* Avoid implicit array coercion in syscall macros. */ - return INLINE_SYSCALL (utimensat, 4, fd, NULL, &tsp[0], 0); + return INLINE_SYSCALL_RETURN (utimensat, 4, int, fd, NULL, &tsp[0], 0); #else - __set_errno (ENOSYS); - return -1; + return INLINE_SYSCALL_ERROR_RETURN (-ENOSYS, int, -1); #endif } #ifndef __NR_utimensat diff --git a/sysdeps/unix/sysv/linux/futimes.c b/sysdeps/unix/sysv/linux/futimes.c index 69ddfe1531..72094b6f11 100644 --- a/sysdeps/unix/sysv/linux/futimes.c +++ b/sysdeps/unix/sysv/linux/futimes.c @@ -40,15 +40,13 @@ __futimes (int fd, const struct timeval tvp[2]) { if (tvp[0].tv_usec < 0 || tvp[0].tv_usec >= 1000000 || tvp[1].tv_usec < 0 || tvp[1].tv_usec >= 1000000) - { - __set_errno (EINVAL); - return -1; - } + return INLINE_SYSCALL_ERROR_RETURN (-EINVAL, int, -1); TIMEVAL_TO_TIMESPEC (&tvp[0], &ts[0]); TIMEVAL_TO_TIMESPEC (&tvp[1], &ts[1]); } - return INLINE_SYSCALL (utimensat, 4, fd, NULL, tvp ? &ts : NULL, 0); + return INLINE_SYSCALL_RETURN (utimensat, 4, int, fd, NULL, + tvp ? &ts : NULL, 0); } weak_alias (__futimes, futimes) diff --git a/sysdeps/unix/sysv/linux/futimesat.c b/sysdeps/unix/sysv/linux/futimesat.c index 27d68702e1..76ccec7a66 100644 --- a/sysdeps/unix/sysv/linux/futimesat.c +++ b/sysdeps/unix/sysv/linux/futimesat.c @@ -34,5 +34,5 @@ futimesat (int fd, const char *file, const struct timeval tvp[2]) return __futimes (fd, tvp); /* Avoid implicit array coercion in syscall macros. */ - return INLINE_SYSCALL (futimesat, 3, fd, file, &tvp[0]); + return INLINE_SYSCALL_RETURN (futimesat, 3, int, fd, file, &tvp[0]); } diff --git a/sysdeps/unix/sysv/linux/fxstat.c b/sysdeps/unix/sysv/linux/fxstat.c index 8d8c4e182a..e81dc3f2b4 100644 --- a/sysdeps/unix/sysv/linux/fxstat.c +++ b/sysdeps/unix/sysv/linux/fxstat.c @@ -36,20 +36,21 @@ int __fxstat (int vers, int fd, struct stat *buf) { if (vers == _STAT_VER_KERNEL) - return INLINE_SYSCALL (fstat, 2, fd, (struct kernel_stat *) buf); + return INLINE_SYSCALL_RETURN (fstat, 2, fd, + (struct kernel_stat *) buf); #ifdef STAT_IS_KERNEL_STAT - errno = EINVAL; - return -1; + return INLINE_SYSCALL_ERROR_RETURN (-EINVAL, int, -1); #else struct kernel_stat kbuf; - int result; - - result = INLINE_SYSCALL (fstat, 2, fd, &kbuf); - if (result == 0) - result = __xstat_conv (vers, &kbuf, buf); - - return result; + INTERNAL_SYSCALL_DECL (err); + int result = INTERNAL_SYSCALL (fstat, err, 2, fd, &kbuf); + if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (result, err))) + return INLINE_SYSCALL_ERROR_RETURN (-INTERNAL_SYSCALL_ERRNO (result, + err), + int, -1); + else + return __xstat_conv (vers, &kbuf, buf); #endif } diff --git a/sysdeps/unix/sysv/linux/fxstat64.c b/sysdeps/unix/sysv/linux/fxstat64.c index 7a0168d5b7..97b06a81f6 100644 --- a/sysdeps/unix/sysv/linux/fxstat64.c +++ b/sysdeps/unix/sysv/linux/fxstat64.c @@ -31,8 +31,12 @@ int ___fxstat64 (int vers, int fd, struct stat64 *buf) { - int result; - result = INLINE_SYSCALL (fstat64, 2, fd, buf); + INTERNAL_SYSCALL_DECL (err); + int result = INTERNAL_SYSCALL (fstat64, err, 2, fd, buf); + if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (result, err))) + return INLINE_SYSCALL_ERROR_RETURN (-INTERNAL_SYSCALL_ERRNO (result, + err), + int, -1); #if defined _HAVE_STAT64___ST_INO && __ASSUME_ST_INO_64_BIT == 0 if (__builtin_expect (!result, 1) && buf->__st_ino != (__ino_t) buf->st_ino) buf->st_ino = buf->__st_ino; diff --git a/sysdeps/unix/sysv/linux/fxstatat.c b/sysdeps/unix/sysv/linux/fxstatat.c index c88bcecbd2..5259931df4 100644 --- a/sysdeps/unix/sysv/linux/fxstatat.c +++ b/sysdeps/unix/sysv/linux/fxstatat.c @@ -45,7 +45,11 @@ __fxstatat (int vers, int fd, const char *file, struct stat *st, int flag) #endif result = INTERNAL_SYSCALL (newfstatat, err, 4, fd, file, &kst, flag); - if (!__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 1)) + if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (result, err))) + return INLINE_SYSCALL_ERROR_RETURN (-INTERNAL_SYSCALL_ERRNO (result, + err), + int, -1); + else { #ifdef STAT_IS_KERNEL_STAT return 0; @@ -53,11 +57,6 @@ __fxstatat (int vers, int fd, const char *file, struct stat *st, int flag) return __xstat_conv (vers, &kst, st); #endif } - else - { - __set_errno (INTERNAL_SYSCALL_ERRNO (result, err)); - return -1; - } } libc_hidden_def (__fxstatat) #ifdef XSTAT_IS_XSTAT64 diff --git a/sysdeps/unix/sysv/linux/fxstatat64.c b/sysdeps/unix/sysv/linux/fxstatat64.c index a55cf1d155..f4cd094eca 100644 --- a/sysdeps/unix/sysv/linux/fxstatat64.c +++ b/sysdeps/unix/sysv/linux/fxstatat64.c @@ -32,21 +32,17 @@ int __fxstatat64 (int vers, int fd, const char *file, struct stat64 *st, int flag) { if (__glibc_unlikely (vers != _STAT_VER_LINUX)) - { - __set_errno (EINVAL); - return -1; - } + return INLINE_SYSCALL_ERROR_RETURN (-EINVAL, int, -1); int result; INTERNAL_SYSCALL_DECL (err); result = INTERNAL_SYSCALL (fstatat64, err, 4, fd, file, st, flag); - if (!__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 1)) - return 0; + if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (result, err))) + return INLINE_SYSCALL_ERROR_RETURN (-INTERNAL_SYSCALL_ERRNO (result, + err), + int, -1); else - { - __set_errno (INTERNAL_SYSCALL_ERRNO (result, err)); - return -1; - } + return 0; } libc_hidden_def (__fxstatat64) diff --git a/sysdeps/unix/sysv/linux/gai_sigqueue.c b/sysdeps/unix/sysv/linux/gai_sigqueue.c index 404dd68fa9..fe4f36f37b 100644 --- a/sysdeps/unix/sysv/linux/gai_sigqueue.c +++ b/sysdeps/unix/sysv/linux/gai_sigqueue.c @@ -47,7 +47,8 @@ __gai_sigqueue (sig, val, caller_pid) info.si_uid = __getuid (); info.si_value = val; - return INLINE_SYSCALL (rt_sigqueueinfo, 3, info.si_pid, sig, &info); + return INLINE_SYSCALL_RETURN (rt_sigqueueinfo, 3, int, info.si_pid, + sig, &info); } #else # include <resolv/gai_sigqueue.c> diff --git a/sysdeps/unix/sysv/linux/getpriority.c b/sysdeps/unix/sysv/linux/getpriority.c index 9c691bb387..444995e0e3 100644 --- a/sysdeps/unix/sysv/linux/getpriority.c +++ b/sysdeps/unix/sysv/linux/getpriority.c @@ -34,12 +34,14 @@ int __getpriority (enum __priority_which which, id_t who) { - int res; - - res = INLINE_SYSCALL (getpriority, 2, (int) which, who); - if (res >= 0) - res = PZERO - res; - return res; + INTERNAL_SYSCALL_DECL (err); + int res = INTERNAL_SYSCALL (getpriority, err, 2, (int) which, who); + if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (res, err))) + return INLINE_SYSCALL_ERROR_RETURN (-INTERNAL_SYSCALL_ERRNO (res, + err), + int, -1); + else + return PZERO - res; } libc_hidden_def (__getpriority) weak_alias (__getpriority, getpriority) diff --git a/sysdeps/unix/sysv/linux/getrlimit64.c b/sysdeps/unix/sysv/linux/getrlimit64.c index 100ba623e2..b0c85337b3 100644 --- a/sysdeps/unix/sysv/linux/getrlimit64.c +++ b/sysdeps/unix/sysv/linux/getrlimit64.c @@ -27,11 +27,15 @@ int __getrlimit64 (enum __rlimit_resource resource, struct rlimit64 *rlimits) { #ifdef __ASSUME_PRLIMIT64 - return INLINE_SYSCALL (prlimit64, 4, 0, resource, NULL, rlimits); + return INLINE_SYSCALL_RETURN (prlimit64, 4, int, 0, resource, + NULL, rlimits); #else # ifdef __NR_prlimit64 - int res = INLINE_SYSCALL (prlimit64, 4, 0, resource, NULL, rlimits); - if (res == 0 || errno != ENOSYS) + INTERNAL_SYSCALL_DECL (err); + int res = INTERNAL_SYSCALL (prlimit64, err, 4, 0, resource, NULL, + rlimits); + if (!__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (res, err)) + || INTERNAL_SYSCALL_ERRNO (res, err) != ENOSYS) return res; # endif struct rlimit rlimits32; diff --git a/sysdeps/unix/sysv/linux/llseek.c b/sysdeps/unix/sysv/linux/llseek.c index 80ac5e690b..116e55b9f7 100644 --- a/sysdeps/unix/sysv/linux/llseek.c +++ b/sysdeps/unix/sysv/linux/llseek.c @@ -29,10 +29,17 @@ loff_t __llseek (int fd, loff_t offset, int whence) { loff_t retval; - - return (loff_t) (INLINE_SYSCALL (_llseek, 5, fd, (off_t) (offset >> 32), - (off_t) (offset & 0xffffffff), - &retval, whence) ?: retval); + INTERNAL_SYSCALL_DECL (err); + int result = INTERNAL_SYSCALL (_llseek, err, 5, fd, + (off_t) (offset >> 32), + (off_t) (offset & 0xffffffff), + &retval, whence); + if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (result, err))) + return INLINE_SYSCALL_ERROR_RETURN (-INTERNAL_SYSCALL_ERRNO (result, + err), + loff_t, -1); + else + return retval; } weak_alias (__llseek, llseek) strong_alias (__llseek, __libc_lseek64) diff --git a/sysdeps/unix/sysv/linux/lutimes.c b/sysdeps/unix/sysv/linux/lutimes.c index 9e51305b9b..3597c18cfc 100644 --- a/sysdeps/unix/sysv/linux/lutimes.c +++ b/sysdeps/unix/sysv/linux/lutimes.c @@ -34,20 +34,16 @@ lutimes (const char *file, const struct timeval tvp[2]) { if (tvp[0].tv_usec < 0 || tvp[0].tv_usec >= 1000000 || tvp[1].tv_usec < 0 || tvp[1].tv_usec >= 1000000) - { - __set_errno (EINVAL); - return -1; - } + return INLINE_SYSCALL_ERROR_RETURN (-EINVAL, int, -1); TIMEVAL_TO_TIMESPEC (&tvp[0], &ts[0]); TIMEVAL_TO_TIMESPEC (&tvp[1], &ts[1]); } - return INLINE_SYSCALL (utimensat, 4, AT_FDCWD, file, tvp ? ts : NULL, - AT_SYMLINK_NOFOLLOW); + return INLINE_SYSCALL_RETURN (utimensat, 4, int, AT_FDCWD, file, + tvp ? ts : NULL, AT_SYMLINK_NOFOLLOW); #else - __set_errno (ENOSYS); - return -1; + return INLINE_SYSCALL_ERROR_RETURN (-ENOSYS, int, -1); #endif } diff --git a/sysdeps/unix/sysv/linux/lxstat.c b/sysdeps/unix/sysv/linux/lxstat.c index 948665c27a..ae3f33cb7f 100644 --- a/sysdeps/unix/sysv/linux/lxstat.c +++ b/sysdeps/unix/sysv/linux/lxstat.c @@ -35,20 +35,21 @@ int __lxstat (int vers, const char *name, struct stat *buf) { if (vers == _STAT_VER_KERNEL) - return INLINE_SYSCALL (lstat, 2, name, (struct kernel_stat *) buf); + return INLINE_SYSCALL_ERROR_RETURN (lstat, 2, int, name, + (struct kernel_stat *) buf); #ifdef STAT_IS_KERNEL_STAT - errno = EINVAL; - return -1; + return INLINE_SYSCALL_ERROR_RETURN (-EINVAL, int, -1) #else struct kernel_stat kbuf; - int result; - - result = INLINE_SYSCALL (lstat, 2, name, &kbuf); - if (result == 0) - result = __xstat_conv (vers, &kbuf, buf); - - return result; + INTERNAL_SYSCALL_DECL (err); + int result = INTERNAL_SYSCALL (lstat, err, 2, name, &kbuf); + if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (result, err))) + return INLINE_SYSCALL_ERROR_RETURN (-INTERNAL_SYSCALL_ERRNO (result, + err), + int, -1) + else + return __xstat_conv (vers, &kbuf, buf); #endif } diff --git a/sysdeps/unix/sysv/linux/lxstat64.c b/sysdeps/unix/sysv/linux/lxstat64.c index 5d0c051aa1..5b4d806731 100644 --- a/sysdeps/unix/sysv/linux/lxstat64.c +++ b/sysdeps/unix/sysv/linux/lxstat64.c @@ -30,8 +30,12 @@ int ___lxstat64 (int vers, const char *name, struct stat64 *buf) { - int result; - result = INLINE_SYSCALL (lstat64, 2, name, buf); + INTERNAL_SYSCALL_DECL (err); + int result = INTERNAL_SYSCALL (lstat64, err, 2, name, buf); + if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (result, err))) + return INLINE_SYSCALL_ERROR_RETURN (-INTERNAL_SYSCALL_ERRNO (result, + err), + int, -1); #if defined _HAVE_STAT64___ST_INO && __ASSUME_ST_INO_64_BIT == 0 if (__builtin_expect (!result, 1) && buf->__st_ino != (__ino_t) buf->st_ino) buf->st_ino = buf->__st_ino; diff --git a/sysdeps/unix/sysv/linux/mmap64.c b/sysdeps/unix/sysv/linux/mmap64.c index 0b160b6f6b..4dbe28b9c4 100644 --- a/sysdeps/unix/sysv/linux/mmap64.c +++ b/sysdeps/unix/sysv/linux/mmap64.c @@ -46,15 +46,9 @@ __mmap64 (void *addr, size_t len, int prot, int flags, int fd, off64_t offset) } #endif if (offset & ((1 << page_shift) - 1)) - { - __set_errno (EINVAL); - return MAP_FAILED; - } - void *result; - result = (void *) - INLINE_SYSCALL (mmap2, 6, addr, - len, prot, flags, fd, - (off_t) (offset >> page_shift)); - return result; + return INLINE_SYSCALL_ERROR_RETURN (-EINVAL, void *, MAP_FAILED); + return INLINE_SYSCALL_RETURN (mmap2, 6, void *, addr, + len, prot, flags, fd, + (off_t) (offset >> page_shift)); } weak_alias (__mmap64, mmap64) diff --git a/sysdeps/unix/sysv/linux/mq_close.c b/sysdeps/unix/sysv/linux/mq_close.c index 58d5aea699..1d5b664b3a 100644 --- a/sysdeps/unix/sysv/linux/mq_close.c +++ b/sysdeps/unix/sysv/linux/mq_close.c @@ -26,7 +26,7 @@ int mq_close (mqd_t mqdes) { - return INLINE_SYSCALL (close, 1, mqdes); + return INLINE_SYSCALL_RETURN (close, 1, int, mqdes); } #else diff --git a/sysdeps/unix/sysv/linux/mq_open.c b/sysdeps/unix/sysv/linux/mq_open.c index 46c0cc871c..ecadd08544 100644 --- a/sysdeps/unix/sysv/linux/mq_open.c +++ b/sysdeps/unix/sysv/linux/mq_open.c @@ -35,10 +35,7 @@ mqd_t __mq_open (const char *name, int oflag, ...) { if (name[0] != '/') - { - __set_errno (EINVAL); - return -1; - } + return INLINE_SYSCALL_ERROR_RETURN (-EINVAL, int, -1); mode_t mode = 0; struct mq_attr *attr = NULL; @@ -52,7 +49,8 @@ __mq_open (const char *name, int oflag, ...) va_end (ap); } - return INLINE_SYSCALL (mq_open, 4, name + 1, oflag, mode, attr); + return INLINE_SYSCALL_RETURN (mq_open, 4, int, name + 1, oflag, mode, + attr); } strong_alias (__mq_open, mq_open); diff --git a/sysdeps/unix/sysv/linux/mq_unlink.c b/sysdeps/unix/sysv/linux/mq_unlink.c index a876c3c3ca..0b133d1425 100644 --- a/sysdeps/unix/sysv/linux/mq_unlink.c +++ b/sysdeps/unix/sysv/linux/mq_unlink.c @@ -26,10 +26,7 @@ int mq_unlink (const char *name) { if (name[0] != '/') - { - __set_errno (EINVAL); - return -1; - } + return INLINE_SYSCALL_ERROR_RETURN (-EINVAL, int, -1); INTERNAL_SYSCALL_DECL (err); int ret = INTERNAL_SYSCALL (mq_unlink, err, 1, name + 1); @@ -41,8 +38,7 @@ mq_unlink (const char *name) ret = INTERNAL_SYSCALL_ERRNO (ret, err); if (ret == EPERM) ret = EACCES; - __set_errno (ret); - ret = -1; + return INLINE_SYSCALL_ERROR_RETURN (-ret, int, -1); } return ret; diff --git a/sysdeps/unix/sysv/linux/msgget.c b/sysdeps/unix/sysv/linux/msgget.c index ca8932ca8a..fdc4796361 100644 --- a/sysdeps/unix/sysv/linux/msgget.c +++ b/sysdeps/unix/sysv/linux/msgget.c @@ -32,5 +32,6 @@ msgget (key, msgflg) key_t key; int msgflg; { - return INLINE_SYSCALL (ipc, 5, IPCOP_msgget, key, msgflg, 0, NULL); + return INLINE_SYSCALL_RETURN (ipc, 5, int, IPCOP_msgget, key, msgflg, + 0, NULL); } diff --git a/sysdeps/unix/sysv/linux/prlimit.c b/sysdeps/unix/sysv/linux/prlimit.c index db88ba893c..ad164c4b2c 100644 --- a/sysdeps/unix/sysv/linux/prlimit.c +++ b/sysdeps/unix/sysv/linux/prlimit.c @@ -44,10 +44,15 @@ prlimit (__pid_t pid, enum __rlimit_resource resource, new_rlimit64 = &new_rlimit64_mem; } - int res = INLINE_SYSCALL (prlimit64, 4, pid, resource, new_rlimit64, - old_rlimit64); + INTERNAL_SYSCALL_DECL (err); + int res = INTERNAL_SYSCALL (prlimit64, err, 4, pid, resource, + new_rlimit64, old_rlimit64); - if (res == 0 && old_rlimit != NULL) + if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (res, err))) + return INLINE_SYSCALL_ERROR_RETURN (-INTERNAL_SYSCALL_ERRNO (res, + err), + int, -1); + else if (old_rlimit != NULL) { /* The prlimit64 syscall is ill-designed for 32-bit machines. We have to provide a 32-bit variant since otherwise the LFS @@ -59,20 +64,14 @@ prlimit (__pid_t pid, enum __rlimit_resource resource, if (old_rlimit->rlim_cur != old_rlimit64_mem.rlim_cur) { if (new_rlimit == NULL) - { - __set_errno (EOVERFLOW); - return -1; - } + return INLINE_SYSCALL_ERROR_RETURN (-EOVERFLOW, int, -1); old_rlimit->rlim_cur = RLIM_INFINITY; } old_rlimit->rlim_max = old_rlimit64_mem.rlim_max; if (old_rlimit->rlim_max != old_rlimit64_mem.rlim_max) { if (new_rlimit == NULL) - { - __set_errno (EOVERFLOW); - return -1; - } + return INLINE_SYSCALL_ERROR_RETURN (-EOVERFLOW, int, -1); old_rlimit->rlim_max = RLIM_INFINITY; } } @@ -84,8 +83,7 @@ int prlimit (__pid_t pid, enum __rlimit_resource resource, const struct rlimit *new_rlimit, struct rlimit *old_rlimit) { - __set_errno (ENOSYS); - return -1; + return INLINE_SYSCALL_ERROR_RETURN (-ENOSYS, int, -1); } stub_warning (prlimit) #endif diff --git a/sysdeps/unix/sysv/linux/pt-raise.c b/sysdeps/unix/sysv/linux/pt-raise.c index 307b9dca08..1e1443918b 100644 --- a/sysdeps/unix/sysv/linux/pt-raise.c +++ b/sysdeps/unix/sysv/linux/pt-raise.c @@ -33,6 +33,6 @@ raise (sig) if (__glibc_unlikely (pid < 0)) pid = -pid; - return INLINE_SYSCALL (tgkill, 3, pid, THREAD_GETMEM (THREAD_SELF, tid), - sig); + return INLINE_SYSCALL_RETURN (tgkill, 3, int, pid, + THREAD_GETMEM (THREAD_SELF, tid), sig); } diff --git a/sysdeps/unix/sysv/linux/raise.c b/sysdeps/unix/sysv/linux/raise.c index e2810634d6..2e6bb6b46a 100644 --- a/sysdeps/unix/sysv/linux/raise.c +++ b/sysdeps/unix/sysv/linux/raise.c @@ -52,7 +52,7 @@ raise (sig) if (__glibc_unlikely (pid <= 0)) pid = (pid & INT_MAX) == 0 ? selftid : -pid; - return INLINE_SYSCALL (tgkill, 3, pid, selftid, sig); + return INLINE_SYSCALL_RETURN (tgkill, 3, int, pid, selftid, sig); } libc_hidden_def (raise) weak_alias (raise, gsignal) diff --git a/sysdeps/unix/sysv/linux/readahead.c b/sysdeps/unix/sysv/linux/readahead.c index c47df0d5de..0c3e58574b 100644 --- a/sysdeps/unix/sysv/linux/readahead.c +++ b/sysdeps/unix/sysv/linux/readahead.c @@ -29,17 +29,16 @@ ssize_t __readahead (int fd, off64_t offset, size_t count) { - return INLINE_SYSCALL (readahead, 4, fd, - __LONG_LONG_PAIR ((off_t) (offset >> 32), - (off_t) (offset & 0xffffffff)), - count); + return INLINE_SYSCALL_RETURN (readahead, 4, int, fd, + __LONG_LONG_PAIR ((off_t) (offset >> 32), + (off_t) (offset & 0xffffffff)), + count); } #else ssize_t __readahead (int fd, off64_t offset, size_t count) { - __set_errno (ENOSYS); - return -1; + return INLINE_SYSCALL_ERROR_RETURN (-ENOSYS, int, -1); } stub_warning (readahead) #endif diff --git a/sysdeps/unix/sysv/linux/reboot.c b/sysdeps/unix/sysv/linux/reboot.c index a016321ee7..e5252456ab 100644 --- a/sysdeps/unix/sysv/linux/reboot.c +++ b/sysdeps/unix/sysv/linux/reboot.c @@ -25,5 +25,6 @@ int reboot (int howto) { - return INLINE_SYSCALL (reboot, 3, (int) 0xfee1dead, 672274793, howto); + return INLINE_SYSCALL_RETURN (reboot, 3, int, (int) 0xfee1dead, + 672274793, howto); } diff --git a/sysdeps/unix/sysv/linux/sched_getaffinity.c b/sysdeps/unix/sysv/linux/sched_getaffinity.c index 9850806298..d66b6faa55 100644 --- a/sysdeps/unix/sysv/linux/sched_getaffinity.c +++ b/sysdeps/unix/sysv/linux/sched_getaffinity.c @@ -25,12 +25,22 @@ #ifdef __NR_sched_getaffinity +# if SHLIB_COMPAT (libc, GLIBC_2_3_3, GLIBC_2_3_4) +extern int __sched_getaffinity_new (pid_t, size_t, cpu_set_t *); +libc_hidden_proto (__sched_getaffinity_new) +# endif + int __sched_getaffinity_new (pid_t pid, size_t cpusetsize, cpu_set_t *cpuset) { - int res = INLINE_SYSCALL (sched_getaffinity, 3, pid, - MIN (INT_MAX, cpusetsize), cpuset); - if (res != -1) + INTERNAL_SYSCALL_DECL (err); + int res = INTERNAL_SYSCALL (sched_getaffinity, err, 3, pid, + MIN (INT_MAX, cpusetsize), cpuset); + if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (res, err))) + return INLINE_SYSCALL_ERROR_RETURN (-INTERNAL_SYSCALL_ERRNO (res, + err), + int, -1); + else { /* Clean the rest of the memory the kernel didn't do. */ memset ((char *) cpuset + res, '\0', cpusetsize - res); @@ -44,6 +54,8 @@ versioned_symbol (libc, __sched_getaffinity_new, sched_getaffinity, # if SHLIB_COMPAT (libc, GLIBC_2_3_3, GLIBC_2_3_4) +libc_hidden_def (__sched_getaffinity_new) + int attribute_compat_text_section __sched_getaffinity_old (pid_t pid, cpu_set_t *cpuset) diff --git a/sysdeps/unix/sysv/linux/semget.c b/sysdeps/unix/sysv/linux/semget.c index 7221ff22d8..c75835df15 100644 --- a/sysdeps/unix/sysv/linux/semget.c +++ b/sysdeps/unix/sysv/linux/semget.c @@ -33,5 +33,6 @@ semget (key, nsems, semflg) int nsems; int semflg; { - return INLINE_SYSCALL (ipc, 5, IPCOP_semget, key, nsems, semflg, NULL); + return INLINE_SYSCALL_RETURN (ipc, 5, int, IPCOP_semget, key, nsems, + semflg, NULL); } diff --git a/sysdeps/unix/sysv/linux/semop.c b/sysdeps/unix/sysv/linux/semop.c index dc936be856..b40014c897 100644 --- a/sysdeps/unix/sysv/linux/semop.c +++ b/sysdeps/unix/sysv/linux/semop.c @@ -31,5 +31,6 @@ semop (semid, sops, nsops) struct sembuf *sops; size_t nsops; { - return INLINE_SYSCALL (ipc, 5, IPCOP_semop, semid, (int) nsops, 0, sops); + return INLINE_SYSCALL_RETURN (ipc, 5, int, IPCOP_semop, semid, + (int) nsops, 0, sops); } diff --git a/sysdeps/unix/sysv/linux/semtimedop.c b/sysdeps/unix/sysv/linux/semtimedop.c index 02df07e704..57e7485946 100644 --- a/sysdeps/unix/sysv/linux/semtimedop.c +++ b/sysdeps/unix/sysv/linux/semtimedop.c @@ -32,7 +32,6 @@ semtimedop (semid, sops, nsops, timeout) size_t nsops; const struct timespec *timeout; { - return INLINE_SYSCALL (ipc, 6, IPCOP_semtimedop, - semid, (int) nsops, 0, sops, - timeout); + return INLINE_SYSCALL_RETURN (ipc, 6, int, IPCOP_semtimedop, semid, + (int) nsops, 0, sops, timeout); } diff --git a/sysdeps/unix/sysv/linux/setrlimit64.c b/sysdeps/unix/sysv/linux/setrlimit64.c index 17f95cbdfc..1989af6fd5 100644 --- a/sysdeps/unix/sysv/linux/setrlimit64.c +++ b/sysdeps/unix/sysv/linux/setrlimit64.c @@ -30,11 +30,15 @@ setrlimit64 (resource, rlimits) const struct rlimit64 *rlimits; { #ifdef __ASSUME_PRLIMIT64 - return INLINE_SYSCALL (prlimit64, 4, 0, resource, rlimits, NULL); + return INLINE_SYSCALL_RETURN (prlimit64, 4, int, 0, resource, + rlimits, NULL); #else # ifdef __NR_prlimit64 - int res = INLINE_SYSCALL (prlimit64, 4, 0, resource, rlimits, NULL); - if (res == 0 || errno != ENOSYS) + INTERNAL_SYSCALL_DECL (err); + int res = INTERNAL_SYSCALL (prlimit64, err, 4, 0, resource, rlimits, + NULL); + if (!__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (res, err)) + || INTERNAL_SYSCALL_ERRNO (res, err) != ENOSYS) return res; # endif struct rlimit rlimits32; diff --git a/sysdeps/unix/sysv/linux/shmat.c b/sysdeps/unix/sysv/linux/shmat.c index 94d18d3f66..45ebd1177c 100644 --- a/sysdeps/unix/sysv/linux/shmat.c +++ b/sysdeps/unix/sysv/linux/shmat.c @@ -42,11 +42,10 @@ shmat (shmid, shmaddr, shmflg) shmid, shmflg, (long int) &raddr, (void *) shmaddr); - if (INTERNAL_SYSCALL_ERROR_P (resultvar, err)) - { - __set_errno (INTERNAL_SYSCALL_ERRNO (resultvar, err)); - return (void *) -1l; - } - - return raddr; + if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (resultvar, err))) + return INLINE_SYSCALL_ERROR_RETURN (-INTERNAL_SYSCALL_ERRNO (resultvar, + err), + void *, -1l); + else + return raddr; } diff --git a/sysdeps/unix/sysv/linux/shmdt.c b/sysdeps/unix/sysv/linux/shmdt.c index 51bad719c0..0bb637081b 100644 --- a/sysdeps/unix/sysv/linux/shmdt.c +++ b/sysdeps/unix/sysv/linux/shmdt.c @@ -30,5 +30,6 @@ int shmdt (shmaddr) const void *shmaddr; { - return INLINE_SYSCALL (ipc, 5, IPCOP_shmdt, 0, 0, 0, (void *) shmaddr); + return INLINE_SYSCALL_RETURN (ipc, 5, int, IPCOP_shmdt, 0, 0, 0, + (void *) shmaddr); } diff --git a/sysdeps/unix/sysv/linux/shmget.c b/sysdeps/unix/sysv/linux/shmget.c index b3d74e69e5..c9720f4c4b 100644 --- a/sysdeps/unix/sysv/linux/shmget.c +++ b/sysdeps/unix/sysv/linux/shmget.c @@ -33,5 +33,6 @@ shmget (key, size, shmflg) size_t size; int shmflg; { - return INLINE_SYSCALL (ipc, 5, IPCOP_shmget, key, size, shmflg, NULL); + return INLINE_SYSCALL_RETURN (ipc, 5, int, IPCOP_shmget, key, size, + shmflg, NULL); } diff --git a/sysdeps/unix/sysv/linux/signalfd.c b/sysdeps/unix/sysv/linux/signalfd.c index f3ae8c1947..e07b56cf06 100644 --- a/sysdeps/unix/sysv/linux/signalfd.c +++ b/sysdeps/unix/sysv/linux/signalfd.c @@ -26,11 +26,17 @@ int signalfd (int fd, const sigset_t *mask, int flags) { #ifdef __NR_signalfd4 - int res = INLINE_SYSCALL (signalfd4, 4, fd, mask, _NSIG / 8, flags); # ifndef __ASSUME_SIGNALFD4 - if (res != -1 || errno != ENOSYS) -# endif + INTERNAL_SYSCALL_DECL (err); + int res = INTERNAL_SYSCALL (signalfd4, err, 4, fd, mask, _NSIG / 8, + flags); + if (!__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (res, err)) + || INTERNAL_SYSCALL_ERRNO (res, err) != ENOSYS) return res; +# else + return INLINE_SYSCALL_RETURN (signalfd4, 4, int, fd, mask, _NSIG / 8, + flags); +# endif #endif #ifndef __ASSUME_SIGNALFD4 @@ -39,16 +45,12 @@ signalfd (int fd, const sigset_t *mask, int flags) kernel (sys_indirect) before implementing setting flags like O_NONBLOCK etc. */ if (flags != 0) - { - __set_errno (EINVAL); - return -1; - } + return INLINE_SYSCALL_ERROR_RETURN (-EINVAL, int, -1); # ifdef __NR_signalfd - return INLINE_SYSCALL (signalfd, 3, fd, mask, _NSIG / 8); + return INLINE_SYSCALL_RETURN (signalfd, 3, int, fd, mask, _NSIG / 8); # else - __set_errno (ENOSYS); - return -1; + return INLINE_SYSCALL_ERROR_RETURN (-ENOSYS, int, -1); # endif #elif !defined __NR_signalfd4 # error "__ASSUME_SIGNALFD4 defined but not __NR_signalfd4" diff --git a/sysdeps/unix/sysv/linux/sigpending.c b/sysdeps/unix/sysv/linux/sigpending.c index c8f3a8e395..4ad098295a 100644 --- a/sysdeps/unix/sysv/linux/sigpending.c +++ b/sysdeps/unix/sysv/linux/sigpending.c @@ -29,5 +29,5 @@ int sigpending (set) sigset_t *set; { - return INLINE_SYSCALL (rt_sigpending, 2, set, _NSIG / 8); + return INLINE_SYSCALL_RETURN (rt_sigpending, 2, int, set, _NSIG / 8); } diff --git a/sysdeps/unix/sysv/linux/sigprocmask.c b/sysdeps/unix/sysv/linux/sigprocmask.c index 574f0d2232..452f8a168d 100644 --- a/sysdeps/unix/sysv/linux/sigprocmask.c +++ b/sysdeps/unix/sysv/linux/sigprocmask.c @@ -54,6 +54,7 @@ __sigprocmask (how, set, oset) } #endif - return INLINE_SYSCALL (rt_sigprocmask, 4, how, set, oset, _NSIG / 8); + return INLINE_SYSCALL_RETURN (rt_sigprocmask, 4, int, how, set, oset, + _NSIG / 8); } weak_alias (__sigprocmask, sigprocmask) diff --git a/sysdeps/unix/sysv/linux/sigqueue.c b/sysdeps/unix/sysv/linux/sigqueue.c index 7970a7c997..9009174ed6 100644 --- a/sysdeps/unix/sysv/linux/sigqueue.c +++ b/sysdeps/unix/sysv/linux/sigqueue.c @@ -43,7 +43,7 @@ __sigqueue (pid, sig, val) info.si_uid = __getuid (); info.si_value = val; - return INLINE_SYSCALL (rt_sigqueueinfo, 3, pid, sig, &info); + return INLINE_SYSCALL_RETURN (rt_sigqueueinfo, 3, int, pid, sig, &info); } weak_alias (__sigqueue, sigqueue) #else diff --git a/sysdeps/unix/sysv/linux/speed.c b/sysdeps/unix/sysv/linux/speed.c index 3ac0640b65..2ed9f15da3 100644 --- a/sysdeps/unix/sysv/linux/speed.c +++ b/sysdeps/unix/sysv/linux/speed.c @@ -60,10 +60,7 @@ cfsetospeed (termios_p, speed) { if ((speed & ~CBAUD) != 0 && (speed < B57600 || speed > __MAX_BAUD)) - { - __set_errno (EINVAL); - return -1; - } + return INLINE_SYSCALL_ERROR_RETURN (-EINVAL, int, -1); #ifdef _HAVE_STRUCT_TERMIOS_C_OSPEED termios_p->c_ospeed = speed; @@ -87,10 +84,7 @@ cfsetispeed (termios_p, speed) { if ((speed & ~CBAUD) != 0 && (speed < B57600 || speed > __MAX_BAUD)) - { - __set_errno (EINVAL); - return -1; - } + return INLINE_SYSCALL_ERROR_RETURN (-EINVAL, int, -1); #ifdef _HAVE_STRUCT_TERMIOS_C_ISPEED termios_p->c_ispeed = speed; diff --git a/sysdeps/unix/sysv/linux/statfs64.c b/sysdeps/unix/sysv/linux/statfs64.c index ac5c33fbf0..0d9e16c7bc 100644 --- a/sysdeps/unix/sysv/linux/statfs64.c +++ b/sysdeps/unix/sysv/linux/statfs64.c @@ -37,12 +37,18 @@ __statfs64 (const char *file, struct statfs64 *buf) if (! __no_statfs64) # endif { - int result = INLINE_SYSCALL (statfs64, 3, file, sizeof (*buf), buf); - # if __ASSUME_STATFS64 == 0 - if (result == 0 || errno != ENOSYS) -# endif + INTERNAL_SYSCALL_DECL (err); + int result = INTERNAL_SYSCALL (statfs64, err, 3, file, + sizeof (*buf), buf); + + if (!__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (result, err)) + || INTERNAL_SYSCALL_ERRNO (result, err) != ENOSYS) return result; +# else + return INLINE_SYSCALL_RETURN (statfs64, 3, int, file, + sizeof (*buf), buf); +# endif # if __ASSUME_STATFS64 == 0 __no_statfs64 = 1; diff --git a/sysdeps/unix/sysv/linux/sysctl.c b/sysdeps/unix/sysv/linux/sysctl.c index 2d4eb1dd85..d0fe55c76c 100644 --- a/sysdeps/unix/sysv/linux/sysctl.c +++ b/sysdeps/unix/sysv/linux/sysctl.c @@ -37,7 +37,7 @@ __sysctl (int *name, int nlen, void *oldval, size_t *oldlenp, .newlen = newlen }; - return INLINE_SYSCALL (_sysctl, 1, &args); + return INLINE_SYSCALL_RETURN (_sysctl, 1, int, &args); } libc_hidden_def (__sysctl) weak_alias (__sysctl, sysctl) diff --git a/sysdeps/unix/sysv/linux/tcsendbrk.c b/sysdeps/unix/sysv/linux/tcsendbrk.c index 4a43209a0e..508efbbaab 100644 --- a/sysdeps/unix/sysv/linux/tcsendbrk.c +++ b/sysdeps/unix/sysv/linux/tcsendbrk.c @@ -39,7 +39,6 @@ tcsendbreak (int fd, int duration) /* ioctl can't send a break of any other duration for us. This could be changed to use trickery (e.g. lower speed and send a '\0') to send the break, but for now just return an error. */ - __set_errno (EINVAL); - return -1; + return INLINE_SYSCALL_ERROR_RETURN (-EINVAL, int, -1); #endif } diff --git a/sysdeps/unix/sysv/linux/tcsetattr.c b/sysdeps/unix/sysv/linux/tcsetattr.c index d7afc636a0..96f728790b 100644 --- a/sysdeps/unix/sysv/linux/tcsetattr.c +++ b/sysdeps/unix/sysv/linux/tcsetattr.c @@ -61,8 +61,7 @@ tcsetattr (fd, optional_actions, termios_p) cmd = TCSETSF; break; default: - __set_errno (EINVAL); - return -1; + return INLINE_SYSCALL_ERROR_RETURN (-EINVAL, int, -1); } k_termios.c_iflag = termios_p->c_iflag & ~IBAUD0; @@ -79,6 +78,6 @@ tcsetattr (fd, optional_actions, termios_p) memcpy (&k_termios.c_cc[0], &termios_p->c_cc[0], __KERNEL_NCCS * sizeof (cc_t)); - return INLINE_SYSCALL (ioctl, 3, fd, cmd, &k_termios); + return INLINE_SYSCALL_RETURN (ioctl, 3, int, fd, cmd, &k_termios); } libc_hidden_def (tcsetattr) diff --git a/sysdeps/unix/sysv/linux/timer_getoverr.c b/sysdeps/unix/sysv/linux/timer_getoverr.c index 8f00192287..2bcac7993d 100644 --- a/sysdeps/unix/sysv/linux/timer_getoverr.c +++ b/sysdeps/unix/sysv/linux/timer_getoverr.c @@ -35,7 +35,5 @@ timer_getoverrun (timerid) struct timer *kt = (struct timer *) timerid; /* Get the information from the kernel. */ - int res = INLINE_SYSCALL (timer_getoverrun, 1, kt->ktimerid); - - return res; + return INLINE_SYSCALL_RETURN (timer_getoverrun, 1, int, kt->ktimerid); } diff --git a/sysdeps/unix/sysv/linux/timer_gettime.c b/sysdeps/unix/sysv/linux/timer_gettime.c index 79705cf5e8..e9ca59a47e 100644 --- a/sysdeps/unix/sysv/linux/timer_gettime.c +++ b/sysdeps/unix/sysv/linux/timer_gettime.c @@ -37,7 +37,6 @@ timer_gettime (timerid, value) struct timer *kt = (struct timer *) timerid; /* Delete the kernel timer object. */ - int res = INLINE_SYSCALL (timer_gettime, 2, kt->ktimerid, value); - - return res; + return INLINE_SYSCALL_RETURN (timer_gettime, 2, int, kt->ktimerid, + value); } diff --git a/sysdeps/unix/sysv/linux/timer_settime.c b/sysdeps/unix/sysv/linux/timer_settime.c index 87c65194ea..d8687fdd9f 100644 --- a/sysdeps/unix/sysv/linux/timer_settime.c +++ b/sysdeps/unix/sysv/linux/timer_settime.c @@ -39,8 +39,6 @@ timer_settime (timerid, flags, value, ovalue) struct timer *kt = (struct timer *) timerid; /* Delete the kernel timer object. */ - int res = INLINE_SYSCALL (timer_settime, 4, kt->ktimerid, flags, - value, ovalue); - - return res; + return INLINE_SYSCALL_RETURN (timer_settime, 4, int, kt->ktimerid, + flags, value, ovalue); } diff --git a/sysdeps/unix/sysv/linux/truncate64.c b/sysdeps/unix/sysv/linux/truncate64.c index 0002247142..d4500b1c17 100644 --- a/sysdeps/unix/sysv/linux/truncate64.c +++ b/sysdeps/unix/sysv/linux/truncate64.c @@ -29,7 +29,6 @@ truncate64 (const char *path, off64_t length) { unsigned int low = length & 0xffffffff; unsigned int high = length >> 32; - int result = INLINE_SYSCALL (truncate64, 3, path, - __LONG_LONG_PAIR (high, low)); - return result; + return INLINE_SYSCALL_RETURN (truncate64, 3, int, path, + __LONG_LONG_PAIR (high, low)); } diff --git a/sysdeps/unix/sysv/linux/ustat.c b/sysdeps/unix/sysv/linux/ustat.c index 8d495ca8ce..1d78c20a29 100644 --- a/sysdeps/unix/sysv/linux/ustat.c +++ b/sysdeps/unix/sysv/linux/ustat.c @@ -31,10 +31,8 @@ ustat (dev_t dev, struct ustat *ubuf) /* We must convert the value to dev_t type used by the kernel. */ k_dev = dev & ((1ULL << 32) - 1); if (k_dev != dev) - { - __set_errno (EINVAL); - return -1; - } + return INLINE_SYSCALL_ERROR_RETURN (-EINVAL, int, -1); - return INLINE_SYSCALL (ustat, 2, (unsigned int) k_dev, ubuf); + return INLINE_SYSCALL_RETURN (ustat, 2, int, (unsigned int) k_dev, + ubuf); } diff --git a/sysdeps/unix/sysv/linux/utimensat.c b/sysdeps/unix/sysv/linux/utimensat.c index 81b565f2ea..9b645a10e6 100644 --- a/sysdeps/unix/sysv/linux/utimensat.c +++ b/sysdeps/unix/sysv/linux/utimensat.c @@ -30,16 +30,13 @@ utimensat (int fd, const char *file, const struct timespec tsp[2], int flags) { if (file == NULL) - { - __set_errno (EINVAL); - return -1; - } + return INLINE_SYSCALL_ERROR_RETURN (-EINVAL, int, -1); #ifdef __NR_utimensat /* Avoid implicit array coercion in syscall macros. */ - return INLINE_SYSCALL (utimensat, 4, fd, file, &tsp[0], flags); + return INLINE_SYSCALL_RETURN (utimensat, 4, int, fd, file, &tsp[0], + flags); #else - __set_errno (ENOSYS); - return -1; + return INLINE_SYSCALL_ERROR_RETURN (-ENOSYS, int, -1); #endif } #ifndef __NR_utimensat diff --git a/sysdeps/unix/sysv/linux/utimes.c b/sysdeps/unix/sysv/linux/utimes.c index 2a1f2f90a1..10b5593d79 100644 --- a/sysdeps/unix/sysv/linux/utimes.c +++ b/sysdeps/unix/sysv/linux/utimes.c @@ -30,7 +30,7 @@ int __utimes (const char *file, const struct timeval tvp[2]) { /* Avoid implicit array coercion in syscall macros. */ - return INLINE_SYSCALL (utimes, 2, file, &tvp[0]); + return INLINE_SYSCALL_RETURN (utimes, 2, int, file, &tvp[0]); } weak_alias (__utimes, utimes) diff --git a/sysdeps/unix/sysv/linux/xmknod.c b/sysdeps/unix/sysv/linux/xmknod.c index b940273058..92f714d5b1 100644 --- a/sysdeps/unix/sysv/linux/xmknod.c +++ b/sysdeps/unix/sysv/linux/xmknod.c @@ -33,20 +33,15 @@ __xmknod (int vers, const char *path, mode_t mode, dev_t *dev) unsigned long long int k_dev; if (vers != _MKNOD_VER) - { - __set_errno (EINVAL); - return -1; - } + return INLINE_SYSCALL_ERROR_RETURN (-EINVAL, int, -1); /* We must convert the value to dev_t type used by the kernel. */ k_dev = (*dev) & ((1ULL << 32) - 1); if (k_dev != *dev) - { - __set_errno (EINVAL); - return -1; - } + return INLINE_SYSCALL_ERROR_RETURN (-EINVAL, int, -1); - return INLINE_SYSCALL (mknod, 3, path, mode, (unsigned int) k_dev); + return INLINE_SYSCALL_RETURN (mknod, 3, int, path, mode, + (unsigned int) k_dev); } weak_alias (__xmknod, _xmknod) diff --git a/sysdeps/unix/sysv/linux/xmknodat.c b/sysdeps/unix/sysv/linux/xmknodat.c index f30b9b3072..04ad458b1b 100644 --- a/sysdeps/unix/sysv/linux/xmknodat.c +++ b/sysdeps/unix/sysv/linux/xmknodat.c @@ -34,20 +34,15 @@ int __xmknodat (int vers, int fd, const char *file, mode_t mode, dev_t *dev) { if (vers != _MKNOD_VER) - { - __set_errno (EINVAL); - return -1; - } + return INLINE_SYSCALL_ERROR_RETURN (-EINVAL, int, -1); /* We must convert the value to dev_t type used by the kernel. */ unsigned long long int k_dev = (*dev) & ((1ULL << 32) - 1); if (k_dev != *dev) - { - __set_errno (EINVAL); - return -1; - } + return INLINE_SYSCALL_ERROR_RETURN (-EINVAL, int, -1); - return INLINE_SYSCALL (mknodat, 4, fd, file, mode, (unsigned int) k_dev); + return INLINE_SYSCALL_RETURN (mknodat, 4, int, fd, file, mode, + (unsigned int) k_dev); } libc_hidden_def (__xmknodat) diff --git a/sysdeps/unix/sysv/linux/xstat.c b/sysdeps/unix/sysv/linux/xstat.c index 6218963766..8734e0b933 100644 --- a/sysdeps/unix/sysv/linux/xstat.c +++ b/sysdeps/unix/sysv/linux/xstat.c @@ -35,20 +35,22 @@ int __xstat (int vers, const char *name, struct stat *buf) { if (vers == _STAT_VER_KERNEL) - return INLINE_SYSCALL (stat, 2, name, (struct kernel_stat *) buf); + return INLINE_SYSCALL_RETURN (stat, 2, int, name, + (struct kernel_stat *) buf); #ifdef STAT_IS_KERNEL_STAT errno = EINVAL; return -1; #else struct kernel_stat kbuf; - int result; - - result = INLINE_SYSCALL (stat, 2, name, &kbuf); - if (result == 0) - result = __xstat_conv (vers, &kbuf, buf); - - return result; + INTERNAL_SYSCALL_DECL (err); + int result = INTERNAL_SYSCALL (stat, err, 2, name, &kbuf); + if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (result, err))) + return INLINE_SYSCALL_ERROR_RETURN (-INTERNAL_SYSCALL_ERRNO (result, + err), + int, -1); + else + return __xstat_conv (vers, &kbuf, buf); #endif } hidden_def (__xstat) diff --git a/sysdeps/unix/sysv/linux/xstat64.c b/sysdeps/unix/sysv/linux/xstat64.c index c909b5672c..55ff8a1c63 100644 --- a/sysdeps/unix/sysv/linux/xstat64.c +++ b/sysdeps/unix/sysv/linux/xstat64.c @@ -31,8 +31,12 @@ int ___xstat64 (int vers, const char *name, struct stat64 *buf) { - int result; - result = INLINE_SYSCALL (stat64, 2, name, buf); + INTERNAL_SYSCALL_DECL (err); + int result = INTERNAL_SYSCALL (stat64, err, 2, name, buf); + if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (result, err))) + return INLINE_SYSCALL_ERROR_RETURN (-INTERNAL_SYSCALL_ERRNO (result, + err), + int, -1); #if defined _HAVE_STAT64___ST_INO && __ASSUME_ST_INO_64_BIT == 0 if (__builtin_expect (!result, 1) && buf->__st_ino != (__ino_t) buf->st_ino) buf->st_ino = buf->__st_ino; diff --git a/sysdeps/unix/sysv/linux/xstatconv.c b/sysdeps/unix/sysv/linux/xstatconv.c index 6504414e1e..5aae78e0d5 100644 --- a/sysdeps/unix/sysv/linux/xstatconv.c +++ b/sysdeps/unix/sysv/linux/xstatconv.c @@ -96,8 +96,7 @@ __xstat_conv (int vers, struct kernel_stat *kbuf, void *ubuf) break; default: - __set_errno (EINVAL); - return -1; + return INLINE_SYSCALL_ERROR_RETURN (-EINVAL, int, -1); } return 0; @@ -170,8 +169,7 @@ __xstat64_conv (int vers, struct kernel_stat *kbuf, void *ubuf) _STAT_VER_KERNEL does not make sense. */ case _STAT_VER_KERNEL: default: - __set_errno (EINVAL); - return -1; + return INLINE_SYSCALL_ERROR_RETURN (-EINVAL, int, -1); } return 0; @@ -201,19 +199,13 @@ __xstat32_conv (int vers, struct stat64 *kbuf, struct stat *buf) buf->st_ino = kbuf->st_ino; if (sizeof (buf->st_ino) != sizeof (kbuf->st_ino) && buf->st_ino != kbuf->st_ino) - { - __set_errno (EOVERFLOW); - return -1; - } + return INLINE_SYSCALL_ERROR_RETURN (-EOVERFLOW, int, -1); } #else buf->st_ino = kbuf->st_ino; if (sizeof (buf->st_ino) != sizeof (kbuf->st_ino) && buf->st_ino != kbuf->st_ino) - { - __set_errno (EOVERFLOW); - return -1; - } + return INLINE_SYSCALL_ERROR_RETURN (-EOVERFLOW, int, -1); #endif buf->st_mode = kbuf->st_mode; buf->st_nlink = kbuf->st_nlink; @@ -227,19 +219,13 @@ __xstat32_conv (int vers, struct stat64 *kbuf, struct stat *buf) /* Check for overflow. */ if (sizeof (buf->st_size) != sizeof (kbuf->st_size) && buf->st_size != kbuf->st_size) - { - __set_errno (EOVERFLOW); - return -1; - } + return INLINE_SYSCALL_ERROR_RETURN (-EOVERFLOW, int, -1); buf->st_blksize = kbuf->st_blksize; buf->st_blocks = kbuf->st_blocks; /* Check for overflow. */ if (sizeof (buf->st_blocks) != sizeof (kbuf->st_blocks) && buf->st_blocks != kbuf->st_blocks) - { - __set_errno (EOVERFLOW); - return -1; - } + return INLINE_SYSCALL_ERROR_RETURN (-EOVERFLOW, int, -1); #ifdef _HAVE_STAT_NSEC buf->st_atim.tv_sec = kbuf->st_atim.tv_sec; buf->st_atim.tv_nsec = kbuf->st_atim.tv_nsec; @@ -275,8 +261,7 @@ __xstat32_conv (int vers, struct stat64 *kbuf, struct stat *buf) _STAT_VER_KERNEL does not make sense. */ case _STAT_VER_KERNEL: default: - __set_errno (EINVAL); - return -1; + return INLINE_SYSCALL_ERROR_RETURN (-EINVAL, int, -1); } return 0; |