aboutsummaryrefslogtreecommitdiff
path: root/tests/libcap_psx_test.c
diff options
context:
space:
mode:
authorAndrew G. Morgan <morgan@kernel.org>2020-02-17 13:08:42 -0800
committerAndrew G. Morgan <morgan@kernel.org>2020-02-17 13:08:42 -0800
commit51ed0ec9b78ef321e5feba3780aefbc4d0246449 (patch)
treeaec9db9f15dc5085209a34257b04f9c48a65959a /tests/libcap_psx_test.c
parent13227f9b2f2b2f222e8022e19bd46db6f6f898c6 (diff)
downloadlibcap-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.c42
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);
}