This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
RFC: [PATCH] Add INLINE_SYSCALL_ERROR_RETURN
- From: "H.J. Lu" <hongjiu dot lu at intel dot com>
- To: GNU C Library <libc-alpha at sourceware dot org>
- Date: Fri, 21 Aug 2015 15:38:58 -0700
- Subject: RFC: [PATCH] Add INLINE_SYSCALL_ERROR_RETURN
- Authentication-results: sourceware.org; auth=none
- Reply-to: "H.J. Lu" <hjl dot tools at gmail dot com>
If it is OK, I can add
#include <sysdeps/unix/sysv/linux/sysdep.h>
to other sysdep.h files.
Thanks.
H.J.
---
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_ERROR_RETURN so that i386 can optimize setting errno by
branching to the internal __syscall_error without PLT.
With i386 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/sysv/linux/adjtime.c (ADJTIME): Use
INLINE_SYSCALL_ERROR_RETURN.
* 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/futimens.c (futimens): Likewise.
* sysdeps/unix/sysv/linux/futimes.c (__futimes): Likewise.
* sysdeps/unix/sysv/linux/fxstat.c (__fxstat): Likewise.
* sysdeps/unix/sysv/linux/fxstatat.c (__fxstatat): Likewise.
* sysdeps/unix/sysv/linux/fxstatat64.c (__fxstatat64): 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_open.c (__mq_open): Likewise.
* sysdeps/unix/sysv/linux/mq_unlink.c (mq_unlink): Likewise.
* sysdeps/unix/sysv/linux/prlimit.c (prlimit): Likewise.
* sysdeps/unix/sysv/linux/readahead.c (__readahead): Likewise.
* sysdeps/unix/sysv/linux/shmat.c (shmat): Likewise.
* sysdeps/unix/sysv/linux/signalfd.c (signalfd): Likewise.
* sysdeps/unix/sysv/linux/speed.c (cfsetospeed): Likewise.
* sysdeps/unix/sysv/linux/tcsetattr.c (tcsetattr): Likewise.
* sysdeps/unix/sysv/linux/ustat.c (ustat): Likewise.
* sysdeps/unix/sysv/linux/utimensat.c (utimensat): 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/xstatconv.c (__xstat_conv): Likewise.
(__xstat64_conv): Likewise.
(__xstat32_conv): Likewise.
* sysdeps/unix/sysv/linux/sysdep.h: New file.
* sysdeps/unix/sysv/linux/i386/sysdep.h: Include
<sysdeps/unix/sysv/linux/sysdep.h>.
* sysdeps/unix/sysv/linux/x86_64/sysdep.h: Likewise.
---
sysdeps/unix/sysv/linux/adjtime.c | 5 +----
sysdeps/unix/sysv/linux/dl-openat64.c | 3 +--
sysdeps/unix/sysv/linux/eventfd.c | 8 ++------
sysdeps/unix/sysv/linux/faccessat.c | 8 ++------
sysdeps/unix/sysv/linux/fchmodat.c | 10 ++--------
sysdeps/unix/sysv/linux/fcntl.c | 3 +--
sysdeps/unix/sysv/linux/futimens.c | 8 ++------
sysdeps/unix/sysv/linux/futimes.c | 5 +----
sysdeps/unix/sysv/linux/fxstat.c | 3 +--
sysdeps/unix/sysv/linux/fxstatat.c | 5 +----
sysdeps/unix/sysv/linux/fxstatat64.c | 10 ++--------
sysdeps/unix/sysv/linux/i386/sysdep.h | 1 +
sysdeps/unix/sysv/linux/lutimes.c | 8 ++------
sysdeps/unix/sysv/linux/lxstat.c | 3 +--
sysdeps/unix/sysv/linux/mmap64.c | 5 +----
sysdeps/unix/sysv/linux/mq_open.c | 5 +----
sysdeps/unix/sysv/linux/mq_unlink.c | 8 ++------
sysdeps/unix/sysv/linux/prlimit.c | 13 +++----------
sysdeps/unix/sysv/linux/readahead.c | 3 +--
sysdeps/unix/sysv/linux/shmat.c | 6 ++----
sysdeps/unix/sysv/linux/signalfd.c | 8 ++------
sysdeps/unix/sysv/linux/speed.c | 10 ++--------
sysdeps/unix/sysv/linux/sysdep.h | 24 ++++++++++++++++++++++++
sysdeps/unix/sysv/linux/tcsendbrk.c | 3 +--
sysdeps/unix/sysv/linux/tcsetattr.c | 3 +--
sysdeps/unix/sysv/linux/ustat.c | 5 +----
sysdeps/unix/sysv/linux/utimensat.c | 8 ++------
sysdeps/unix/sysv/linux/x86_64/sysdep.h | 1 +
sysdeps/unix/sysv/linux/xmknod.c | 10 ++--------
sysdeps/unix/sysv/linux/xmknodat.c | 10 ++--------
sysdeps/unix/sysv/linux/xstat.c | 3 +--
sysdeps/unix/sysv/linux/xstatconv.c | 29 +++++++----------------------
32 files changed, 76 insertions(+), 158 deletions(-)
create mode 100644 sysdeps/unix/sysv/linux/sysdep.h
diff --git a/sysdeps/unix/sysv/linux/adjtime.c b/sysdeps/unix/sysv/linux/adjtime.c
index b6fb7cf..ded0d02 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);
tntx.offset = tmp.tv_usec + tmp.tv_sec * 1000000L;
tntx.modes = ADJ_OFFSET_SINGLESHOT;
}
diff --git a/sysdeps/unix/sysv/linux/dl-openat64.c b/sysdeps/unix/sysv/linux/dl-openat64.c
index 732097d..b2dbd5c 100644
--- a/sysdeps/unix/sysv/linux/dl-openat64.c
+++ b/sysdeps/unix/sysv/linux/dl-openat64.c
@@ -33,7 +33,6 @@ openat64 (dfd, file, oflag)
#ifdef __NR_openat
return INLINE_SYSCALL (openat, 3, dfd, file, oflag | O_LARGEFILE);
#else
- __set_errno (ENOSYS);
- return -1;
+ return INLINE_SYSCALL_ERROR_RETURN (ENOSYS);
#endif
}
diff --git a/sysdeps/unix/sysv/linux/eventfd.c b/sysdeps/unix/sysv/linux/eventfd.c
index d4ffb3c..55406bb 100644
--- a/sysdeps/unix/sysv/linux/eventfd.c
+++ b/sysdeps/unix/sysv/linux/eventfd.c
@@ -38,16 +38,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);
# ifdef __NR_eventfd
return INLINE_SYSCALL (eventfd, 1, count);
# else
- __set_errno (ENOSYS);
- return -1;
+ return INLINE_SYSCALL_ERROR_RETURN (ENOSYS);
# 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 1bb544f..eaca319 100644
--- a/sysdeps/unix/sysv/linux/faccessat.c
+++ b/sysdeps/unix/sysv/linux/faccessat.c
@@ -35,10 +35,7 @@ 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);
if ((flag == 0 || ((flag & ~AT_EACCESS) == 0 && ! __libc_enable_secure)))
return INLINE_SYSCALL (faccessat, 3, fd, file, mode);
@@ -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);
}
diff --git a/sysdeps/unix/sysv/linux/fchmodat.c b/sysdeps/unix/sysv/linux/fchmodat.c
index e278426..720b26b 100644
--- a/sysdeps/unix/sysv/linux/fchmodat.c
+++ b/sysdeps/unix/sysv/linux/fchmodat.c
@@ -34,16 +34,10 @@ fchmodat (fd, file, mode, flag)
int flag;
{
if (flag & ~AT_SYMLINK_NOFOLLOW)
- {
- __set_errno (EINVAL);
- return -1;
- }
+ return INLINE_SYSCALL_ERROR_RETURN (EINVAL);
#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);
#endif
return INLINE_SYSCALL (fchmodat, 3, fd, file, mode);
diff --git a/sysdeps/unix/sysv/linux/fcntl.c b/sysdeps/unix/sysv/linux/fcntl.c
index fa184db..4c891d6 100644
--- a/sysdeps/unix/sysv/linux/fcntl.c
+++ b/sysdeps/unix/sysv/linux/fcntl.c
@@ -36,8 +36,7 @@ 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));
}
diff --git a/sysdeps/unix/sysv/linux/futimens.c b/sysdeps/unix/sysv/linux/futimens.c
index 5f2b8a5..6f9181d 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);
/* Avoid implicit array coercion in syscall macros. */
return INLINE_SYSCALL (utimensat, 4, fd, NULL, &tsp[0], 0);
#else
- __set_errno (ENOSYS);
- return -1;
+ return INLINE_SYSCALL_ERROR_RETURN (ENOSYS);
#endif
}
#ifndef __NR_utimensat
diff --git a/sysdeps/unix/sysv/linux/futimes.c b/sysdeps/unix/sysv/linux/futimes.c
index 69ddfe1..afc8d2c 100644
--- a/sysdeps/unix/sysv/linux/futimes.c
+++ b/sysdeps/unix/sysv/linux/futimes.c
@@ -40,10 +40,7 @@ __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);
TIMEVAL_TO_TIMESPEC (&tvp[0], &ts[0]);
TIMEVAL_TO_TIMESPEC (&tvp[1], &ts[1]);
diff --git a/sysdeps/unix/sysv/linux/fxstat.c b/sysdeps/unix/sysv/linux/fxstat.c
index 8d8c4e1..72f4517 100644
--- a/sysdeps/unix/sysv/linux/fxstat.c
+++ b/sysdeps/unix/sysv/linux/fxstat.c
@@ -39,8 +39,7 @@ __fxstat (int vers, int fd, struct stat *buf)
return INLINE_SYSCALL (fstat, 2, fd, (struct kernel_stat *) buf);
#ifdef STAT_IS_KERNEL_STAT
- errno = EINVAL;
- return -1;
+ return INLINE_SYSCALL_ERROR_RETURN (EINVAL);
#else
struct kernel_stat kbuf;
int result;
diff --git a/sysdeps/unix/sysv/linux/fxstatat.c b/sysdeps/unix/sysv/linux/fxstatat.c
index c88bcec..298493b 100644
--- a/sysdeps/unix/sysv/linux/fxstatat.c
+++ b/sysdeps/unix/sysv/linux/fxstatat.c
@@ -54,10 +54,7 @@ __fxstatat (int vers, int fd, const char *file, struct stat *st, int flag)
#endif
}
else
- {
- __set_errno (INTERNAL_SYSCALL_ERRNO (result, err));
- return -1;
- }
+ return INLINE_SYSCALL_ERROR_RETURN (INTERNAL_SYSCALL_ERRNO (result, err));
}
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 a55cf1d..be97ccd 100644
--- a/sysdeps/unix/sysv/linux/fxstatat64.c
+++ b/sysdeps/unix/sysv/linux/fxstatat64.c
@@ -32,10 +32,7 @@ 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 result;
INTERNAL_SYSCALL_DECL (err);
@@ -44,9 +41,6 @@ __fxstatat64 (int vers, int fd, const char *file, struct stat64 *st, int flag)
if (!__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 1))
return 0;
else
- {
- __set_errno (INTERNAL_SYSCALL_ERRNO (result, err));
- return -1;
- }
+ return INLINE_SYSCALL_ERROR_RETURN (INTERNAL_SYSCALL_ERRNO (result, err));
}
libc_hidden_def (__fxstatat64)
diff --git a/sysdeps/unix/sysv/linux/i386/sysdep.h b/sysdeps/unix/sysv/linux/i386/sysdep.h
index d76aca5..aac3e7b 100644
--- a/sysdeps/unix/sysv/linux/i386/sysdep.h
+++ b/sysdeps/unix/sysv/linux/i386/sysdep.h
@@ -20,6 +20,7 @@
#define _LINUX_I386_SYSDEP_H 1
/* There is some commonality. */
+#include <sysdeps/unix/sysv/linux/sysdep.h>
#include <sysdeps/unix/i386/sysdep.h>
/* Defines RTLD_PRIVATE_ERRNO and USE_DL_SYSINFO. */
#include <dl-sysdep.h>
diff --git a/sysdeps/unix/sysv/linux/lutimes.c b/sysdeps/unix/sysv/linux/lutimes.c
index 9e51305..b1cc54a 100644
--- a/sysdeps/unix/sysv/linux/lutimes.c
+++ b/sysdeps/unix/sysv/linux/lutimes.c
@@ -34,10 +34,7 @@ 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);
TIMEVAL_TO_TIMESPEC (&tvp[0], &ts[0]);
TIMEVAL_TO_TIMESPEC (&tvp[1], &ts[1]);
@@ -46,8 +43,7 @@ lutimes (const char *file, const struct timeval tvp[2])
return INLINE_SYSCALL (utimensat, 4, AT_FDCWD, file, tvp ? ts : NULL,
AT_SYMLINK_NOFOLLOW);
#else
- __set_errno (ENOSYS);
- return -1;
+ return INLINE_SYSCALL_ERROR_RETURN (ENOSYS);
#endif
}
diff --git a/sysdeps/unix/sysv/linux/lxstat.c b/sysdeps/unix/sysv/linux/lxstat.c
index 948665c..b859f93 100644
--- a/sysdeps/unix/sysv/linux/lxstat.c
+++ b/sysdeps/unix/sysv/linux/lxstat.c
@@ -38,8 +38,7 @@ __lxstat (int vers, const char *name, struct stat *buf)
return INLINE_SYSCALL (lstat, 2, name, (struct kernel_stat *) buf);
#ifdef STAT_IS_KERNEL_STAT
- errno = EINVAL;
- return -1;
+ return INLINE_SYSCALL_ERROR_RETURN (EINVAL);
#else
struct kernel_stat kbuf;
int result;
diff --git a/sysdeps/unix/sysv/linux/mmap64.c b/sysdeps/unix/sysv/linux/mmap64.c
index 0b160b6..1c9d3c1 100644
--- a/sysdeps/unix/sysv/linux/mmap64.c
+++ b/sysdeps/unix/sysv/linux/mmap64.c
@@ -46,10 +46,7 @@ __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;
- }
+ return (void *) INLINE_SYSCALL_ERROR_RETURN (EINVAL);
void *result;
result = (void *)
INLINE_SYSCALL (mmap2, 6, addr,
diff --git a/sysdeps/unix/sysv/linux/mq_open.c b/sysdeps/unix/sysv/linux/mq_open.c
index 46c0cc8..6ca78cd 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);
mode_t mode = 0;
struct mq_attr *attr = NULL;
diff --git a/sysdeps/unix/sysv/linux/mq_unlink.c b/sysdeps/unix/sysv/linux/mq_unlink.c
index a876c3c..51eb481 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);
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);
}
return ret;
diff --git a/sysdeps/unix/sysv/linux/prlimit.c b/sysdeps/unix/sysv/linux/prlimit.c
index db88ba8..0337940 100644
--- a/sysdeps/unix/sysv/linux/prlimit.c
+++ b/sysdeps/unix/sysv/linux/prlimit.c
@@ -59,20 +59,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);
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);
old_rlimit->rlim_max = RLIM_INFINITY;
}
}
@@ -84,8 +78,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);
}
stub_warning (prlimit)
#endif
diff --git a/sysdeps/unix/sysv/linux/readahead.c b/sysdeps/unix/sysv/linux/readahead.c
index c47df0d..0cae417 100644
--- a/sysdeps/unix/sysv/linux/readahead.c
+++ b/sysdeps/unix/sysv/linux/readahead.c
@@ -38,8 +38,7 @@ __readahead (int fd, off64_t offset, size_t count)
ssize_t
__readahead (int fd, off64_t offset, size_t count)
{
- __set_errno (ENOSYS);
- return -1;
+ return INLINE_SYSCALL_ERROR_RETURN (ENOSYS);
}
stub_warning (readahead)
#endif
diff --git a/sysdeps/unix/sysv/linux/shmat.c b/sysdeps/unix/sysv/linux/shmat.c
index 94d18d3..3f6388b 100644
--- a/sysdeps/unix/sysv/linux/shmat.c
+++ b/sysdeps/unix/sysv/linux/shmat.c
@@ -43,10 +43,8 @@ shmat (shmid, shmaddr, shmflg)
(long int) &raddr,
(void *) shmaddr);
if (INTERNAL_SYSCALL_ERROR_P (resultvar, err))
- {
- __set_errno (INTERNAL_SYSCALL_ERRNO (resultvar, err));
- return (void *) -1l;
- }
+ return (void *) INLINE_SYSCALL_ERROR_RETURN (INTERNAL_SYSCALL_ERRNO (resultvar,
+ err));
return raddr;
}
diff --git a/sysdeps/unix/sysv/linux/signalfd.c b/sysdeps/unix/sysv/linux/signalfd.c
index f3ae8c1..1e242a4 100644
--- a/sysdeps/unix/sysv/linux/signalfd.c
+++ b/sysdeps/unix/sysv/linux/signalfd.c
@@ -39,16 +39,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);
# ifdef __NR_signalfd
return INLINE_SYSCALL (signalfd, 3, fd, mask, _NSIG / 8);
# else
- __set_errno (ENOSYS);
- return -1;
+ return INLINE_SYSCALL_ERROR_RETURN (ENOSYS);
# endif
#elif !defined __NR_signalfd4
# error "__ASSUME_SIGNALFD4 defined but not __NR_signalfd4"
diff --git a/sysdeps/unix/sysv/linux/speed.c b/sysdeps/unix/sysv/linux/speed.c
index 3ac0640..8b5b7ac 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);
#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);
#ifdef _HAVE_STRUCT_TERMIOS_C_ISPEED
termios_p->c_ispeed = speed;
diff --git a/sysdeps/unix/sysv/linux/sysdep.h b/sysdeps/unix/sysv/linux/sysdep.h
new file mode 100644
index 0000000..fe2ce54
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sysdep.h
@@ -0,0 +1,24 @@
+/* Copyright (C) 2015 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, see
+ <http://www.gnu.org/licenses/>. */
+
+/* Set error number and return -1. A target may choose to return the
+ internal function, __syscall_error, which sets errno and returns -1. */
+#define INLINE_SYSCALL_ERROR_RETURN(err) \
+ ({ \
+ __set_errno (err); \
+ -1; \
+ })
diff --git a/sysdeps/unix/sysv/linux/tcsendbrk.c b/sysdeps/unix/sysv/linux/tcsendbrk.c
index 4a43209..c6599c5 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);
#endif
}
diff --git a/sysdeps/unix/sysv/linux/tcsetattr.c b/sysdeps/unix/sysv/linux/tcsetattr.c
index d7afc63..7dd1368 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);
}
k_termios.c_iflag = termios_p->c_iflag & ~IBAUD0;
diff --git a/sysdeps/unix/sysv/linux/ustat.c b/sysdeps/unix/sysv/linux/ustat.c
index 8d495ca..b18d131 100644
--- a/sysdeps/unix/sysv/linux/ustat.c
+++ b/sysdeps/unix/sysv/linux/ustat.c
@@ -31,10 +31,7 @@ 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);
return INLINE_SYSCALL (ustat, 2, (unsigned int) k_dev, ubuf);
}
diff --git a/sysdeps/unix/sysv/linux/utimensat.c b/sysdeps/unix/sysv/linux/utimensat.c
index 81b565f..df7c2a2 100644
--- a/sysdeps/unix/sysv/linux/utimensat.c
+++ b/sysdeps/unix/sysv/linux/utimensat.c
@@ -30,16 +30,12 @@ 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);
#ifdef __NR_utimensat
/* Avoid implicit array coercion in syscall macros. */
return INLINE_SYSCALL (utimensat, 4, fd, file, &tsp[0], flags);
#else
- __set_errno (ENOSYS);
- return -1;
+ return INLINE_SYSCALL_ERROR_RETURN (ENOSYS);
#endif
}
#ifndef __NR_utimensat
diff --git a/sysdeps/unix/sysv/linux/x86_64/sysdep.h b/sysdeps/unix/sysv/linux/x86_64/sysdep.h
index 5a62cce..fc132f6 100644
--- a/sysdeps/unix/sysv/linux/x86_64/sysdep.h
+++ b/sysdeps/unix/sysv/linux/x86_64/sysdep.h
@@ -19,6 +19,7 @@
#define _LINUX_X86_64_SYSDEP_H 1
/* There is some commonality. */
+#include <sysdeps/unix/sysv/linux/sysdep.h>
#include <sysdeps/unix/x86_64/sysdep.h>
#include <tls.h>
diff --git a/sysdeps/unix/sysv/linux/xmknod.c b/sysdeps/unix/sysv/linux/xmknod.c
index b940273..daf71f8 100644
--- a/sysdeps/unix/sysv/linux/xmknod.c
+++ b/sysdeps/unix/sysv/linux/xmknod.c
@@ -33,18 +33,12 @@ __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);
/* 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);
return INLINE_SYSCALL (mknod, 3, path, mode, (unsigned int) k_dev);
}
diff --git a/sysdeps/unix/sysv/linux/xmknodat.c b/sysdeps/unix/sysv/linux/xmknodat.c
index f30b9b3..66c8652 100644
--- a/sysdeps/unix/sysv/linux/xmknodat.c
+++ b/sysdeps/unix/sysv/linux/xmknodat.c
@@ -34,18 +34,12 @@ 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);
/* 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);
return INLINE_SYSCALL (mknodat, 4, fd, file, mode, (unsigned int) k_dev);
}
diff --git a/sysdeps/unix/sysv/linux/xstat.c b/sysdeps/unix/sysv/linux/xstat.c
index 6218963..d45e37a 100644
--- a/sysdeps/unix/sysv/linux/xstat.c
+++ b/sysdeps/unix/sysv/linux/xstat.c
@@ -38,8 +38,7 @@ __xstat (int vers, const char *name, struct stat *buf)
return INLINE_SYSCALL (stat, 2, name, (struct kernel_stat *) buf);
#ifdef STAT_IS_KERNEL_STAT
- errno = EINVAL;
- return -1;
+ return INLINE_SYSCALL_ERROR_RETURN (EINVAL);
#else
struct kernel_stat kbuf;
int result;
diff --git a/sysdeps/unix/sysv/linux/xstatconv.c b/sysdeps/unix/sysv/linux/xstatconv.c
index 6504414..1c448fc 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);
}
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);
}
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);
}
#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);
#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);
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);
#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);
}
return 0;
--
2.4.3