diff options
Diffstat (limited to 'sysdeps/unix/sysv/linux/clone-internal.c')
-rw-r--r-- | sysdeps/unix/sysv/linux/clone-internal.c | 37 |
1 files changed, 22 insertions, 15 deletions
diff --git a/sysdeps/unix/sysv/linux/clone-internal.c b/sysdeps/unix/sysv/linux/clone-internal.c index a8611772a2..e125c9125e 100644 --- a/sysdeps/unix/sysv/linux/clone-internal.c +++ b/sysdeps/unix/sysv/linux/clone-internal.c @@ -44,27 +44,15 @@ _Static_assert (sizeof (struct clone_args) == CLONE_ARGS_SIZE_VER2, "sizeof (struct clone_args) != CLONE_ARGS_SIZE_VER2"); int -__clone_internal (struct clone_args *cl_args, - int (*func) (void *arg), void *arg) +__clone_internal_fallback (struct clone_args *cl_args, + int (*func) (void *arg), void *arg) { - int ret; -#ifdef HAVE_CLONE3_WRAPPER - /* Try clone3 first. */ - int saved_errno = errno; - ret = __clone3 (cl_args, sizeof (*cl_args), func, arg); - if (ret != -1 || errno != ENOSYS) - return ret; - - /* NB: Restore errno since errno may be checked against non-zero - return value. */ - __set_errno (saved_errno); -#endif - /* Map clone3 arguments to clone arguments. NB: No need to check invalid clone3 specific bits in flags nor exit_signal since this is an internal function. */ int flags = cl_args->flags | cl_args->exit_signal; void *stack = cast_to_pointer (cl_args->stack); + int ret; #ifdef __ia64__ ret = __clone2 (func, stack, cl_args->stack_size, @@ -88,4 +76,23 @@ __clone_internal (struct clone_args *cl_args, return ret; } + +int +__clone_internal (struct clone_args *cl_args, + int (*func) (void *arg), void *arg) +{ +#ifdef HAVE_CLONE3_WRAPPER + int saved_errno = errno; + int ret = __clone3 (cl_args, sizeof (*cl_args), func, arg); + if (ret != -1 || errno != ENOSYS) + return ret; + + /* NB: Restore errno since errno may be checked against non-zero + return value. */ + __set_errno (saved_errno); +#endif + + return __clone_internal_fallback (cl_args, func, arg); +} + libc_hidden_def (__clone_internal) |