diff options
author | Andrew G. Morgan <morgan@kernel.org> | 2020-02-17 13:08:42 -0800 |
---|---|---|
committer | Andrew G. Morgan <morgan@kernel.org> | 2020-02-17 13:08:42 -0800 |
commit | 51ed0ec9b78ef321e5feba3780aefbc4d0246449 (patch) | |
tree | aec9db9f15dc5085209a34257b04f9c48a65959a /tests/libcap_psx_test.c | |
parent | 13227f9b2f2b2f222e8022e19bd46db6f6f898c6 (diff) | |
download | libcap-51ed0ec9b78ef321e5feba3780aefbc4d0246449.tar.gz |
Add support for fork() in libpsx.
When we fork() we disable thread-shared semantics for
the psx_syscall()s of the child, but retain them in the
parent. This change also enhances support for unexpectedly
exiting threads (which seems to be the way Go likes to
terminate pthreads when using cgo linkage).
Enhanced licap_psx_test to fork() from created threads and
exit that thread after the forked child dies. (Ran this
10,000 times to generate confidence no races in libpsx.)
Signed-off-by: Andrew G. Morgan <morgan@kernel.org>
Diffstat (limited to 'tests/libcap_psx_test.c')
-rw-r--r-- | tests/libcap_psx_test.c | 42 |
1 files changed, 38 insertions, 4 deletions
diff --git a/tests/libcap_psx_test.c b/tests/libcap_psx_test.c index f3c9143..d8d62c7 100644 --- a/tests/libcap_psx_test.c +++ b/tests/libcap_psx_test.c @@ -1,12 +1,46 @@ +#include <errno.h> #include <pthread.h> #include <stdio.h> +#include <stdlib.h> #include <sys/capability.h> #include <sys/psx_syscall.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <unistd.h> -int main(int argc, char **argv) { - printf("hello libcap and libpsx\n"); - psx_register(pthread_self()); +static void *thread_fork_exit(void *data) { + usleep(1234); + pid_t pid = fork(); cap_t start = cap_get_proc(); + if (pid == 0) { + cap_set_proc(start); + exit(0); + } + int res; + if (waitpid(pid, &res, 0) != pid || res != 0) { + printf("FAILED: pid=%d wait returned %d and/or error: %d\n", + pid, res, errno); + exit(1); + } cap_set_proc(start); - return 0; + return NULL; +} + +int main(int argc, char **argv) { + int i; + printf("hello libcap and libpsx "); + fflush(stdout); + cap_t start = cap_get_proc(); + pthread_t ignored[10]; + for (i = 0; i < 10; i++) { + pthread_create(&ignored[i], NULL, thread_fork_exit, NULL); + } + for (i = 0; i < 10; i++) { + printf("."); /* because of fork, this may print double */ + fflush(stdout); /* try to limit the above effect */ + cap_set_proc(start); + usleep(1000); + } + printf(" PASSED\n"); + exit(0); } |