Add INLINE_SYSCALL_RETURN/INLINE_SYSCALL_ERROR_RETURN
[glibc.git] / sysdeps / unix / sysdep.h
blobc4316db4bcb51e6a0158240c15786c861bb3c7eb
1 /* Copyright (C) 1991-2015 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
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.
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.
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, see
16 <http://www.gnu.org/licenses/>. */
18 #include <sysdeps/generic/sysdep.h>
20 #include <sys/syscall.h>
21 #define HAVE_SYSCALLS
23 /* Note that using a `PASTE' macro loses. */
24 #define SYSCALL__(name, args) PSEUDO (__##name, name, args)
25 #define SYSCALL(name, args) PSEUDO (name, name, args)
27 /* Cancellation macros. */
28 #define __SYSCALL_NARGS_X(a,b,c,d,e,f,g,n,...) n
29 #define __SYSCALL_NARGS(...) \
30 __SYSCALL_NARGS_X (__VA_ARGS__, 7, 6, 5, 4, 3, 2, 1, 0,)
32 #define SYSCALL_CANCEL(name, ...) \
33 ({ \
34 long int sc_ret; \
35 if (SINGLE_THREAD_P) \
36 sc_ret = INLINE_SYSCALL (name, __SYSCALL_NARGS(__VA_ARGS__), \
37 __VA_ARGS__); \
38 else \
39 { \
40 int sc_cancel_oldtype = LIBC_CANCEL_ASYNC (); \
41 sc_ret = INLINE_SYSCALL (name, __SYSCALL_NARGS (__VA_ARGS__), \
42 __VA_ARGS__); \
43 LIBC_CANCEL_RESET (sc_cancel_oldtype); \
44 } \
45 sc_ret; \
48 /* Machine-dependent sysdep.h files are expected to define the macro
49 PSEUDO (function_name, syscall_name) to emit assembly code to define the
50 C-callable function FUNCTION_NAME to do system call SYSCALL_NAME.
51 r0 and r1 are the system call outputs. MOVE(x, y) should be defined as
52 an instruction such that "MOVE(r1, r0)" works. ret should be defined
53 as the return instruction. */
55 #ifndef SYS_ify
56 #define SYS_ify(syscall_name) SYS_##syscall_name
57 #endif
59 /* Terminate a system call named SYM. This is used on some platforms
60 to generate correct debugging information. */
61 #ifndef PSEUDO_END
62 #define PSEUDO_END(sym)
63 #endif
64 #ifndef PSEUDO_END_NOERRNO
65 #define PSEUDO_END_NOERRNO(sym) PSEUDO_END(sym)
66 #endif
67 #ifndef PSEUDO_END_ERRVAL
68 #define PSEUDO_END_ERRVAL(sym) PSEUDO_END(sym)
69 #endif
71 /* Wrappers around system calls should normally inline the system call code.
72 But sometimes it is not possible or implemented and we use this code. */
73 #ifndef INLINE_SYSCALL
74 #define INLINE_SYSCALL(name, nr, args...) __syscall_##name (args)
75 #endif
77 /* Similar to INLINE_SYSCALL, but with return type. It should only be
78 used with function return. */
79 #ifndef INLINE_SYSCALL_RETURN
80 #define INLINE_SYSCALL_RETURN(name, nr, type, args...) \
81 INLINE_SYSCALL (name, nr, args)
82 #endif
84 /* Set error number and return value. It should only be used with
85 function return. ERR is the negative error number returned from
86 the majority of Linux kernels for which -ERR is no-op
87 with INTERNAL_SYSCALL_ERRNO. */
88 #ifndef INLINE_SYSCALL_ERROR_RETURN
89 #define INLINE_SYSCALL_ERROR_RETURN(err, type, value) \
90 ({ \
91 __set_errno (-err); \
92 (type) (value); \
94 #endif