diff mbox series

[uclibc-ng-devel] Defined INLINE_SYSCALL_NOERR_NCS in mips/bits/syscalls.h

Message ID 20181123001955.4846-1-boyko.cxx@gmail.com
State Accepted
Headers show
Series [uclibc-ng-devel] Defined INLINE_SYSCALL_NOERR_NCS in mips/bits/syscalls.h | expand

Commit Message

Volodymyr Boyko Nov. 23, 2018, 12:19 a.m. UTC
On Linux/MIPS (O32 ABI) for system call we have two result registers - v0 and a3.
v0 contains actual syscall result on success or error number on fail, a3 set to 0/1
for indicating syscall success/fail. (if a3 == 1, v0 contains errno).
Now as we can see from definition of handle_sys (arch/mips/kernel/scall32-o32.S),
handler treats returned by syscall function (let's call "original") values in
range [-EMAXERRNO; 0[ as -errno, a3 is set to 1 and final returned (to userspace)
value is (-original).

INLINE_SYSCALL_NOERR_NCS defined in mips/bits/syscalls.h will handle
this behaviour.

Signed-off-by: Volodymyr Boyko <boyko.cxx@gmail.com>
---
 libc/sysdeps/linux/mips/bits/syscalls.h | 10 ++++++++++
 1 file changed, 10 insertions(+)
diff mbox series

Patch

diff --git a/libc/sysdeps/linux/mips/bits/syscalls.h b/libc/sysdeps/linux/mips/bits/syscalls.h
index 787bb7d..b8f8059 100644
--- a/libc/sysdeps/linux/mips/bits/syscalls.h
+++ b/libc/sysdeps/linux/mips/bits/syscalls.h
@@ -29,6 +29,16 @@ 
        }								\
      result_var; })
 
+#define INLINE_SYSCALL_NOERR_NCS(name, nr, args...)			\
+({									\
+	INTERNAL_SYSCALL_DECL(err);					\
+	long res = INTERNAL_SYSCALL_NCS(name, err, nr, args);		\
+	if (unlikely(INTERNAL_SYSCALL_ERROR_P(res, err))) {		\
+	    res = -res;							\
+	}								\
+        res;								\
+})
+
 #define INTERNAL_SYSCALL_DECL(err) long err attribute_unused
 
 #define INTERNAL_SYSCALL_ERROR_P(val, err)   ((long) (err))