aboutsummaryrefslogtreecommitdiffstats
path: root/man2/__clone2.2
diff options
context:
space:
mode:
authorJack Pearson <jack@pearson.onl>2023-02-28 15:42:46 -0800
committerAlejandro Colomar <alx@kernel.org>2023-03-01 22:28:32 +0100
commit184ecd225079567aa3dede2b63c7ddf962cfdbdf (patch)
tree8f9bc2202956e5eb3d53123d6e5096354903bed5 /man2/__clone2.2
parentb2a916b48219db3ce744b991425fbae1fb7a3baf (diff)
downloadman-pages-184ecd225079.tar.gz
clone.2: Note EINVAL when exit_signal + bad flags
Document that Linux will report EINVAL when exit_signal is specified and either CLONE_THREAD or CLONE_PARENT is specified. From clone3_args_valid in Linux: ``` if ((kargs->flags & (CLONE_THREAD | CLONE_PARENT)) && kargs->exit_signal) return false; ``` I have verified that this happens on my kernel with a small program: ``` #include <stdio.h> #include <linux/sched.h> #include <signal.h> #include <sys/syscall.h> #include <unistd.h> int main(void) { struct clone_args ca = { .flags = CLONE_THREAD | CLONE_SIGHAND | CLONE_VM, .exit_signal = SIGCHLD, // comment me out to fix error .set_tid_size = 0, }; syscall(SYS_clone3, &ca, sizeof(struct clone_args)); perror(""); } ``` And I have verified that this doesn't happen with normal `clone` through the glibc helper: ``` #define _GNU_SOURCE #include <sched.h> #include <signal.h> #include <stdio.h> #include <sys/mman.h> int do_nothing(void *_) { return 0; } int main(void) { void *map = mmap(NULL, 0x10000, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); void *stack_top = map + 0x10000 - 1; clone(do_nothing, stack_top, CLONE_THREAD | CLONE_VM | CLONE_SIGHAND | SIGCHLD, NULL); perror(""); } ``` Signed-off-by: Jack Pearson <jack@pearson.onl> Cc: "Carlos O'Donell" <carlos@redhat.com> Signed-off-by: Alejandro Colomar <alx@kernel.org>
Diffstat (limited to 'man2/__clone2.2')
0 files changed, 0 insertions, 0 deletions