Re: [PATCH] linux: Inline syscall cancellation to keep wrapper frames observable (BZ 34338)

"Andreas K. Huettel" <[email protected]>
Newsgroups gmane.comp.lib.glibc.alpha
Organization Gentoo Linux
Message-ID <[email protected]>
Am Mittwoch, 1. Juli 2026, 04:09:25 Japanische Normalzeit schrieb Adhemerval Zanella:
> The cancellable syscall wrappers end with a tail call to __syscall_cancel,
> ithe wrapper frame is then elided, so when the syscall executes the wrapper
> is no longer present on the stack.  Tools that unwind from CFI alone, such
> as valgrind, perf and sampling profilers, cannot observe it. On gdb, it
> only recovers it from DWARF call site information, which reduced-debuginfo
> libc builds usually omit.

Let's postpone this now please. It's not critical and can be backported.

> 
> The behaviour is target dependent: for a shared (PIC) the tail call is
> emitted on aarch64, arc, loongarch and riscv.  It is not emitte on i386,
> x86_64, arm, s390x, sparc and alpha, where the seventh argument is passed
> on the stack or fewer argument registers are available, nor on powerpc
> and mips, where the TOC/GOT pointer must be restored after the call.
> This is why the problem was originally reported as aarch64 specific while
> x86_64 was unaffected.
> 
> Rather than only inhibiting the tail call [1] (which keeps the wrapper frame
> but still leaves the __syscall_cancel and __internal_syscall_cancel
> frames), move the cancellation logic back into the wrappers.  In the
> single-threaded case the syscall is now issued directly from the wrapper;
> only the multi-threaded path still calls the out-of-line __syscall_cancel_arch.
> 
> This keeps the wrapper observable and removes the extra frames, mimicking
> how cancellation was handled before 89b53077d2a58f00e7debdfe58afabe953dac60d.
> 
> The result is a small libc.so .text increase (size, first column):
> 
>   ABI            master      patched      diff    increase
>   aarch64       1635880     1647424      11544      0.71%
>   x86_64        1981081     1992257      11176      0.56%
>   powerpc64le   2364336     2376964      12628      0.53%
>   riscv64       1368386     1376704       8318      0.61%
>   loongarch64   1741385     1755601      14216      0.82%
> 
> The tst-backtrace5 was suppose to track this issue, but due wrong
> loop variable check it does take this in account.  This patch also fixes it.
> 
> Checked on aarch64-linux-gnu, x86_64-linux-gnu, i686-linux-gnu,
> arm-linux-gnueabihf, and powerpc64le-linux-gnu.
> 
> [1] https://sourceware.org/pipermail/libc-alpha/2025-March/165395.html
> ---
>  debug/tst-backtrace5.c                  | 32 ++++++----
>  elf/Makefile                            |  4 +-
>  nptl/cancellation.c                     | 60 ------------------
>  nptl/futex-internal.c                   |  2 +-
>  nptl/sem_waitcommon.c                   |  2 +-
>  sysdeps/unix/sysdep.h                   | 81 +++++++++++--------------
>  sysdeps/unix/sysv/linux/epoll_pwait2.c  |  2 +-
>  sysdeps/unix/sysv/linux/recvmmsg.c      |  2 +-
>  sysdeps/unix/sysv/linux/sigtimedwait.c  |  2 +-
>  sysdeps/unix/sysv/linux/sysdep-cancel.h | 61 +++++++++++++++++++
>  10 files changed, 125 insertions(+), 123 deletions(-)
> 
> diff --git a/debug/tst-backtrace5.c b/debug/tst-backtrace5.c
> index 4c5784c060a..6538da9ab59 100644
> --- a/debug/tst-backtrace5.c
> +++ b/debug/tst-backtrace5.c
> @@ -36,10 +36,15 @@
>     trampoline, read, 3 * fn, and do_test.  */
>  #define NUM_FUNCTIONS 7
>  
> +/* Avoid the read wrapper frame truncation on targets that add extra frames
> +   between it and handle_signal (the cancellable syscall wrappers
> +   __syscall_cancel*, or the i686 __kernel_vsyscall entry).  */
> +#define MAX_FUNCTIONS 64
> +
>  void
>  handle_signal (int signum)
>  {
> -  void *addresses[NUM_FUNCTIONS];
> +  void *addresses[MAX_FUNCTIONS];
>    char **symbols;
>    int n;
>    int i;
> @@ -70,23 +75,28 @@ handle_signal (int signum)
>        return;
>      }
>  
> -  /* Do not check name for signal trampoline or cancellable syscall
> -     wrappers (__syscall_cancel*).  */
> -  for (; i < n - 1; i++)
> +  /* Skip the signal trampoline and any cancellable syscall wrapper frames
> +     (__syscall_cancel*) and require the read syscall wrapper to be
> +     present.  */
> +  for (i = 1; i < n; i++)
>      if (match (symbols[i], "read"))
>        break;
> -  if (i == n - 1)
> +  if (i == n)
>      {
>        FAIL ();
>        return;
>      }
>  
> -  for (; i < n - 1; i++)
> -    if (!match (symbols[i], "fn"))
> -      {
> -	FAIL ();
> -	return;
> -      }
> +  /* The read wrapper must be followed by the three fn recursion frames.  */
> +  for (int j = 0; j < 3; j++)
> +    {
> +      i++;
> +      if (i == n || !match (symbols[i], "fn"))
> +	{
> +	  FAIL ();
> +	  return;
> +	}
> +    }
>    /* Symbol names are not available for static functions, so we do not
>       check do_test.  */
>  
> diff --git a/elf/Makefile b/elf/Makefile
> index 65144282941..02c335ffb90 100644
> --- a/elf/Makefile
> +++ b/elf/Makefile
> @@ -1550,7 +1550,9 @@ $(objpfx)dl-allobjs.os: $(all-rtld-routines:%=$(objpfx)%.os)
>  # when compiled for libc.
>  rtld-stubbed-symbols = \
>    __libc_assert_fail \
> -  __syscall_cancel \
> +  __libc_single_threaded_internal \
> +  __syscall_cancel_arch \
> +  __syscall_do_cancel \
>    calloc \
>    free \
>    malloc \
> diff --git a/nptl/cancellation.c b/nptl/cancellation.c
> index 4368cb72319..63f09840ffe 100644
> --- a/nptl/cancellation.c
> +++ b/nptl/cancellation.c
> @@ -19,66 +19,6 @@
>  #include <stdlib.h>
>  #include "pthreadP.h"
>  
> -/* Called by the INTERNAL_SYSCALL_CANCEL macro, check for cancellation and
> -   returns the syscall value or its negative error code.  */
> -long int
> -__internal_syscall_cancel (__syscall_arg_t a1, __syscall_arg_t a2,
> -			   __syscall_arg_t a3, __syscall_arg_t a4,
> -			   __syscall_arg_t a5, __syscall_arg_t a6,
> -			   __SYSCALL_CANCEL7_ARG_DEF
> -			   __syscall_arg_t nr)
> -{
> -  long int result;
> -  struct pthread *pd = THREAD_SELF;
> -
> -  /* If cancellation is not enabled, call the syscall directly and also
> -     for thread terminatation to avoid call __syscall_do_cancel while
> -     executing cleanup handlers.  */
> -  int ch = atomic_load_relaxed (&pd->cancelhandling);
> -  if (SINGLE_THREAD_P || !cancel_enabled (ch) || cancel_exiting (ch))
> -    {
> -      result = INTERNAL_SYSCALL_NCS_CALL (nr, a1, a2, a3, a4, a5, a6
> -					  __SYSCALL_CANCEL7_ARCH_ARG7);
> -      if (INTERNAL_SYSCALL_ERROR_P (result))
> -	return -INTERNAL_SYSCALL_ERRNO (result);
> -      return result;
> -    }
> -
> -  /* Call the arch-specific entry points that contains the globals markers
> -     to be checked by SIGCANCEL handler.  */
> -  result = __syscall_cancel_arch (&pd->cancelhandling, nr, a1, a2, a3, a4, a5,
> -			          a6 __SYSCALL_CANCEL7_ARCH_ARG7);
> -
> -  /* If the cancellable syscall was interrupted by SIGCANCEL and it has no
> -     side-effect, cancel the thread if cancellation is enabled.  */
> -  ch = atomic_load_relaxed (&pd->cancelhandling);
> -  /* The behaviour here assumes that EINTR is returned only if there are no
> -     visible side effects.  POSIX Issue 7 has not yet provided any stronger
> -     language for close, and in theory the close syscall could return EINTR
> -     and leave the file descriptor open (conforming and leaks).  It expects
> -     that no such kernel is used with glibc.  */
> -  if (result == -EINTR && cancel_enabled_and_canceled (ch))
> -    __syscall_do_cancel ();
> -
> -  return result;
> -}
> -
> -/* Called by the SYSCALL_CANCEL macro, check for cancellation and return the
> -   syscall expected success value (usually 0) or, in case of failure, -1 and
> -   sets errno to syscall return value.  */
> -long int
> -__syscall_cancel (__syscall_arg_t a1, __syscall_arg_t a2,
> -		  __syscall_arg_t a3, __syscall_arg_t a4,
> -		  __syscall_arg_t a5, __syscall_arg_t a6,
> -		  __SYSCALL_CANCEL7_ARG_DEF __syscall_arg_t nr)
> -{
> -  long int r = __internal_syscall_cancel (a1, a2, a3, a4, a5, a6,
> -					  __SYSCALL_CANCEL7_ARG nr);
> -  return __glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (r))
> -	 ? SYSCALL_ERROR_LABEL (INTERNAL_SYSCALL_ERRNO (r))
> -	 : r;
> -}
> -
>  /* Called by __syscall_cancel_arch or function above start the thread
>     cancellation.  */
>  _Noreturn void
> diff --git a/nptl/futex-internal.c b/nptl/futex-internal.c
> index fc6b11c8ada..07f1462abeb 100644
> --- a/nptl/futex-internal.c
> +++ b/nptl/futex-internal.c
> @@ -17,7 +17,7 @@
>     <https://www.gnu.org/licenses/>.  */
>  
>  #include <errno.h>
> -#include <sysdep.h>
> +#include <sysdep-cancel.h>
>  #include <time.h>
>  #include <futex-internal.h>
>  #include <kernel-features.h>
> diff --git a/nptl/sem_waitcommon.c b/nptl/sem_waitcommon.c
> index b0cbe5cebf7..82c686f0201 100644
> --- a/nptl/sem_waitcommon.c
> +++ b/nptl/sem_waitcommon.c
> @@ -18,7 +18,7 @@
>  
>  #include <kernel-features.h>
>  #include <errno.h>
> -#include <sysdep.h>
> +#include <sysdep-cancel.h>
>  #include <futex-internal.h>
>  #include <internaltypes.h>
>  #include <semaphore.h>
> diff --git a/sysdeps/unix/sysdep.h b/sysdeps/unix/sysdep.h
> index a6ce5348ec3..f0f271ec021 100644
> --- a/sysdeps/unix/sysdep.h
> +++ b/sysdeps/unix/sysdep.h
> @@ -154,42 +154,31 @@
>  # define __SYSCALL_CANCEL7_ARG7
>  # define __SYSCALL_CANCEL7_ARCH_ARG7
>  #endif
> -long int __internal_syscall_cancel (__syscall_arg_t a1, __syscall_arg_t a2,
> -				    __syscall_arg_t a3, __syscall_arg_t a4,
> -				    __syscall_arg_t a5, __syscall_arg_t a6,
> -				    __SYSCALL_CANCEL7_ARG_DEF
> -				    __syscall_arg_t nr) attribute_hidden;
> -
> -long int __syscall_cancel (__syscall_arg_t arg1, __syscall_arg_t arg2,
> -			   __syscall_arg_t arg3, __syscall_arg_t arg4,
> -			   __syscall_arg_t arg5, __syscall_arg_t arg6,
> -			   __SYSCALL_CANCEL7_ARG_DEF
> -			   __syscall_arg_t nr) attribute_hidden;
>  
>  #define __SYSCALL_CANCEL0(name)						\
> -  __syscall_cancel (0, 0, 0, 0, 0, 0, __SYSCALL_CANCEL7_ARG __NR_##name)
> +  syscall_cancel (0, 0, 0, 0, 0, 0, __SYSCALL_CANCEL7_ARG __NR_##name)
>  #define __SYSCALL_CANCEL1(name, a1)					\
> -  __syscall_cancel (__SSC (a1), 0, 0, 0, 0, 0,				\
> -		    __SYSCALL_CANCEL7_ARG __NR_##name)
> +  syscall_cancel (__SSC (a1), 0, 0, 0, 0, 0,				\
> +		  __SYSCALL_CANCEL7_ARG __NR_##name)
>  #define __SYSCALL_CANCEL2(name, a1, a2) \
> -  __syscall_cancel (__SSC (a1), __SSC (a2), 0, 0, 0, 0,			\
> -		    __SYSCALL_CANCEL7_ARG __NR_##name)
> +  syscall_cancel (__SSC (a1), __SSC (a2), 0, 0, 0, 0,			\
> +		  __SYSCALL_CANCEL7_ARG __NR_##name)
>  #define __SYSCALL_CANCEL3(name, a1, a2, a3) \
> -  __syscall_cancel (__SSC (a1), __SSC (a2), __SSC (a3), 0, 0, 0,	\
> -		    __SYSCALL_CANCEL7_ARG __NR_##name)
> +  syscall_cancel (__SSC (a1), __SSC (a2), __SSC (a3), 0, 0, 0,	\
> +		  __SYSCALL_CANCEL7_ARG __NR_##name)
>  #define __SYSCALL_CANCEL4(name, a1, a2, a3, a4) \
> -  __syscall_cancel (__SSC (a1), __SSC (a2), __SSC (a3),			\
> -		    __SSC(a4), 0, 0, __SYSCALL_CANCEL7_ARG __NR_##name)
> +  syscall_cancel (__SSC (a1), __SSC (a2), __SSC (a3),			\
> +		  __SSC(a4), 0, 0, __SYSCALL_CANCEL7_ARG __NR_##name)
>  #define __SYSCALL_CANCEL5(name, a1, a2, a3, a4, a5) \
> -  __syscall_cancel (__SSC (a1), __SSC (a2), __SSC (a3), __SSC(a4),	\
> -		    __SSC (a5), 0, __SYSCALL_CANCEL7_ARG __NR_##name)
> +  syscall_cancel (__SSC (a1), __SSC (a2), __SSC (a3), __SSC(a4),	\
> +		  __SSC (a5), 0, __SYSCALL_CANCEL7_ARG __NR_##name)
>  #define __SYSCALL_CANCEL6(name, a1, a2, a3, a4, a5, a6) \
> -  __syscall_cancel (__SSC (a1), __SSC (a2), __SSC (a3), __SSC (a4),	\
> -		    __SSC (a5), __SSC (a6), __SYSCALL_CANCEL7_ARG	\
> -		    __NR_##name)
> +  syscall_cancel (__SSC (a1), __SSC (a2), __SSC (a3), __SSC (a4),	\
> +		  __SSC (a5), __SSC (a6), __SYSCALL_CANCEL7_ARG	\
> +		  __NR_##name)
>  #define __SYSCALL_CANCEL7(name, a1, a2, a3, a4, a5, a6, a7)		\
> -  __syscall_cancel (__SSC (a1), __SSC (a2), __SSC (a3), __SSC (a4),	\
> -		    __SSC (a5), __SSC (a6), __SSC (a7), __NR_##name)
> +  syscall_cancel (__SSC (a1), __SSC (a2), __SSC (a3), __SSC (a4),	\
> +		  __SSC (a5), __SSC (a6), __SSC (a7), __NR_##name)
>  
>  #define __SYSCALL_CANCEL_NARGS_X(a,b,c,d,e,f,g,h,n,...) n
>  #define __SYSCALL_CANCEL_NARGS(...) \
> @@ -206,33 +195,33 @@ long int __syscall_cancel (__syscall_arg_t arg1, __syscall_arg_t arg2,
>    __SYSCALL_CANCEL_DISP (__SYSCALL_CANCEL, __VA_ARGS__)
>  
>  #define __INTERNAL_SYSCALL_CANCEL0(name)				\
> -  __internal_syscall_cancel (0, 0, 0, 0, 0, 0, __SYSCALL_CANCEL7_ARG	\
> +  internal_syscall_cancel (0, 0, 0, 0, 0, 0, __SYSCALL_CANCEL7_ARG	\
>  			     __NR_##name)
>  #define __INTERNAL_SYSCALL_CANCEL1(name, a1)				\
> -  __internal_syscall_cancel (__SSC (a1), 0, 0, 0, 0, 0,			\
> -			     __SYSCALL_CANCEL7_ARG __NR_##name)
> +  internal_syscall_cancel (__SSC (a1), 0, 0, 0, 0, 0,			\
> +			   __SYSCALL_CANCEL7_ARG __NR_##name)
>  #define __INTERNAL_SYSCALL_CANCEL2(name, a1, a2)			\
> -  __internal_syscall_cancel (__SSC (a1), __SSC (a2), 0, 0, 0, 0,	\
> -			     __SYSCALL_CANCEL7_ARG __NR_##name)
> +  internal_syscall_cancel (__SSC (a1), __SSC (a2), 0, 0, 0, 0,	\
> +			   __SYSCALL_CANCEL7_ARG __NR_##name)
>  #define __INTERNAL_SYSCALL_CANCEL3(name, a1, a2, a3)			\
> -  __internal_syscall_cancel (__SSC (a1), __SSC (a2), __SSC (a3), 0,	\
> -			     0, 0, __SYSCALL_CANCEL7_ARG __NR_##name)
> +  internal_syscall_cancel (__SSC (a1), __SSC (a2), __SSC (a3), 0,	\
> +			   0, 0, __SYSCALL_CANCEL7_ARG __NR_##name)
>  #define __INTERNAL_SYSCALL_CANCEL4(name, a1, a2, a3, a4)		\
> -  __internal_syscall_cancel (__SSC (a1), __SSC (a2), __SSC (a3),	\
> -			     __SSC(a4), 0, 0,				\
> -			     __SYSCALL_CANCEL7_ARG __NR_##name)
> +  internal_syscall_cancel (__SSC (a1), __SSC (a2), __SSC (a3),	\
> +			   __SSC(a4), 0, 0,				\
> +			   __SYSCALL_CANCEL7_ARG __NR_##name)
>  #define __INTERNAL_SYSCALL_CANCEL5(name, a1, a2, a3, a4, a5)		\
> -  __internal_syscall_cancel (__SSC (a1), __SSC (a2), __SSC (a3),	\
> -			     __SSC(a4), __SSC (a5), 0,			\
> -			     __SYSCALL_CANCEL7_ARG __NR_##name)
> +  internal_syscall_cancel (__SSC (a1), __SSC (a2), __SSC (a3),	\
> +			   __SSC(a4), __SSC (a5), 0,			\
> +			   __SYSCALL_CANCEL7_ARG __NR_##name)
>  #define __INTERNAL_SYSCALL_CANCEL6(name, a1, a2, a3, a4, a5, a6)	\
> -  __internal_syscall_cancel (__SSC (a1), __SSC (a2), __SSC (a3),	\
> -			     __SSC (a4), __SSC (a5), __SSC (a6),	\
> -			     __SYSCALL_CANCEL7_ARG __NR_##name)
> +  internal_syscall_cancel (__SSC (a1), __SSC (a2), __SSC (a3),	\
> +			   __SSC (a4), __SSC (a5), __SSC (a6),	\
> +			   __SYSCALL_CANCEL7_ARG __NR_##name)
>  #define __INTERNAL_SYSCALL_CANCEL7(name, a1, a2, a3, a4, a5, a6, a7) \
> -  __internal_syscall_cancel (__SSC (a1), __SSC (a2), __SSC (a3),     \
> -			     __SSC (a4), __SSC (a5), __SSC (a6),     \
> -			     __SSC (a7), __NR_##name)
> +  internal_syscall_cancel (__SSC (a1), __SSC (a2), __SSC (a3),     \
> +			   __SSC (a4), __SSC (a5), __SSC (a6),     \
> +			   __SSC (a7), __NR_##name)
>  
>  /* Issue a cancellable syscall defined by syscall number NAME plus any other
>     argument required.  If an error occurs its value is returned as an negative
> diff --git a/sysdeps/unix/sysv/linux/epoll_pwait2.c b/sysdeps/unix/sysv/linux/epoll_pwait2.c
> index 4da03e3e69f..76ec1f8a71a 100644
> --- a/sysdeps/unix/sysv/linux/epoll_pwait2.c
> +++ b/sysdeps/unix/sysv/linux/epoll_pwait2.c
> @@ -17,7 +17,7 @@
>     <https://www.gnu.org/licenses/>.  */
>  
>  #include <sys/epoll.h>
> -#include <sysdep.h>
> +#include <sysdep-cancel.h>
>  
>  int
>  __epoll_pwait2_time64 (int fd, struct epoll_event *ev, int maxev,
> diff --git a/sysdeps/unix/sysv/linux/recvmmsg.c b/sysdeps/unix/sysv/linux/recvmmsg.c
> index 6fbe4b80aa5..6a89f914c27 100644
> --- a/sysdeps/unix/sysv/linux/recvmmsg.c
> +++ b/sysdeps/unix/sysv/linux/recvmmsg.c
> @@ -16,7 +16,7 @@
>     <https://www.gnu.org/licenses/>.  */
>  
>  #include <sys/socket.h>
> -#include <sysdep.h>
> +#include <sysdep-cancel.h>
>  #include <socketcall.h>
>  
>  static int
> diff --git a/sysdeps/unix/sysv/linux/sigtimedwait.c b/sysdeps/unix/sysv/linux/sigtimedwait.c
> index a4fa8e9e8ee..c2c5e2c0f25 100644
> --- a/sysdeps/unix/sysv/linux/sigtimedwait.c
> +++ b/sysdeps/unix/sysv/linux/sigtimedwait.c
> @@ -16,7 +16,7 @@
>     <https://www.gnu.org/licenses/>.  */
>  
>  #include <signal.h>
> -#include <sysdep.h>
> +#include <sysdep-cancel.h>
>  
>  int
>  __sigtimedwait64 (const sigset_t *set, siginfo_t *info,
> diff --git a/sysdeps/unix/sysv/linux/sysdep-cancel.h b/sysdeps/unix/sysv/linux/sysdep-cancel.h
> index 7fd8258ba59..4b7278915a7 100644
> --- a/sysdeps/unix/sysv/linux/sysdep-cancel.h
> +++ b/sysdeps/unix/sysv/linux/sysdep-cancel.h
> @@ -21,5 +21,66 @@
>  #define _SYSDEP_CANCEL_H
>  
>  #include <sysdep.h>
> +#include "pthreadP.h"
> +
> +/* Called by the INTERNAL_SYSCALL_CANCEL macro, check for cancellation and
> +   returns the syscall value or its negative error code.  */
> +static __always_inline long int
> +internal_syscall_cancel (__syscall_arg_t a1, __syscall_arg_t a2,
> +			 __syscall_arg_t a3, __syscall_arg_t a4,
> +			 __syscall_arg_t a5, __syscall_arg_t a6,
> +			 __SYSCALL_CANCEL7_ARG_DEF
> +			 __syscall_arg_t nr)
> +{
> +  long int result;
> +  struct pthread *pd = THREAD_SELF;
> +
> +  /* If cancellation is not enabled, call the syscall directly and also
> +     for thread terminatation to avoid call __syscall_do_cancel while
> +     executing cleanup handlers.  */
> +  int ch = atomic_load_relaxed (&pd->cancelhandling);
> +  if (SINGLE_THREAD_P || !cancel_enabled (ch) || cancel_exiting (ch))
> +    {
> +      result = INTERNAL_SYSCALL_NCS_CALL (nr, a1, a2, a3, a4, a5, a6
> +					  __SYSCALL_CANCEL7_ARCH_ARG7);
> +      if (INTERNAL_SYSCALL_ERROR_P (result))
> +	return -INTERNAL_SYSCALL_ERRNO (result);
> +      return result;
> +    }
> +
> +  /* Call the arch-specific entry points that contains the globals markers
> +     to be checked by SIGCANCEL handler.  */
> +  result = __syscall_cancel_arch (&pd->cancelhandling, nr, a1, a2, a3, a4, a5,
> +			          a6 __SYSCALL_CANCEL7_ARCH_ARG7);
> +
> +  /* If the cancellable syscall was interrupted by SIGCANCEL and it has no
> +     side-effect, cancel the thread if cancellation is enabled.  */
> +  ch = atomic_load_relaxed (&pd->cancelhandling);
> +  /* The behaviour here assumes that EINTR is returned only if there are no
> +     visible side effects.  POSIX Issue 7 has not yet provided any stronger
> +     language for close, and in theory the close syscall could return EINTR
> +     and leave the file descriptor open (conforming and leaks).  It expects
> +     that no such kernel is used with glibc.  */
> +  if (result == -EINTR && cancel_enabled_and_canceled (ch))
> +    __syscall_do_cancel ();
> +
> +  return result;
> +}
> +
> +/* Called by the SYSCALL_CANCEL macro, check for cancellation and return the
> +   syscall expected success value (usually 0) or, in case of failure, -1 and
> +   sets errno to syscall return value.  */
> +static __always_inline long int
> +syscall_cancel (__syscall_arg_t a1, __syscall_arg_t a2,
> +		__syscall_arg_t a3, __syscall_arg_t a4,
> +		__syscall_arg_t a5, __syscall_arg_t a6,
> +		__SYSCALL_CANCEL7_ARG_DEF __syscall_arg_t nr)
> +{
> +  long int r = internal_syscall_cancel (a1, a2, a3, a4, a5, a6,
> +					__SYSCALL_CANCEL7_ARG nr);
> +  return __glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (r))
> +	 ? SYSCALL_ERROR_LABEL (INTERNAL_SYSCALL_ERRNO (r))
> +	 : r;
> +}
>  
>  #endif
> 


-- 
PD Dr. Andreas K. Hüttel
[email protected]
Gentoo Linux developer 
(council, comrel, toolchain, base-system, perl, libreoffice)
https://wiki.gentoo.org/wiki/User:Dilfridge
signature.asc (application/pgp-signature, 870 B)
-----BEGIN PGP SIGNATURE-----

iQJPBAABCAA5FiEE/Rnm0xsZLuTcY+rT3CsWIV7VQSoFAmpctRwbFIAAAAAABAAO
bWFudTIsMi41KzEuMTIsMiwyAAoJENwrFiFe1UEqQ60QAI2aN3n0Q57Ji75jMQWb
DOxWP9i2U0I+aq7NJe/thAzXj4pwYFE8mjivsJ4U+DK15X36xY1lseBP7gKK2ILL
hLSuXOqk8nL9KnJldBUH0ztN/z4dVJyzd5c3uRBJW9HsMw76IBoxyvlZFdRpsE6R
BSTVI7BOV45MMz97iBn+c+Zxcmp68gdPIWooBKD9zk1Z09M6KtiRDyKvjMsxMeJd
u3zsYR0B+Cpit4j1XeHbIy5PfbRwiDJiyY/JPTRNi2fSvCUtL3fRBqEd+GLC4WJ1
51pnyp5QQHx7JV7sljdd7q/fe/w/mvKAg03CnquDO8Bbpp4ID56n7+wWUj/hgH1X
gbFnZdH1J3mfg9aoculQPJA0mNWNae3Tuo87XUxBGtuIaw+SWDxMt29HJR01ZYMy
lj4871UMHrjDvp0+Ercfv9LwdVSqtu3qDMdNpXsn9oRaDNyY0bJbVKNR7a2e5zbw
AIwkqGuG8EAdmR9KTR2ZXS2wLDWTSRWnJaHBfs1MpXbvC//K9ZbcTGenwHUZQfmR
yfFepNmBAXw8kKzKRNuhWq6NBBKxZb2src/BSCWdQeocUwk3Vfc93mKd9V5eqJgO
Ly+O5c4HCKvy16zmcKM/q2oyuM/VPIhnRP42qgNeMCDH1yzU5bcxEpi/hJDx5Xej
E34ORD5fBFFdkdUrflK3QDt/
=mo7D
-----END PGP SIGNATURE-----
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.