]>
Commit | Line | Data |
---|---|---|
813fb2f6 | 1 | #include <darwintest.h> |
5ba3f43e | 2 | #include "xnu_quick_test_helpers.h" |
813fb2f6 | 3 | |
5ba3f43e | 4 | #include <fcntl.h> |
813fb2f6 A |
5 | #include <stdlib.h> |
6 | #include <unistd.h> | |
5ba3f43e | 7 | #include <mach/mach.h> |
813fb2f6 | 8 | #include <sys/stat.h> |
5ba3f43e A |
9 | #include <sys/syscall.h> |
10 | #include <sys/sysctl.h> | |
813fb2f6 A |
11 | #include <sys/wait.h> |
12 | ||
cb323159 A |
13 | T_GLOBAL_META( |
14 | T_META_NAMESPACE("xnu.quicktest"), | |
15 | T_META_CHECK_LEAKS(false), | |
16 | T_META_RUN_CONCURRENTLY(true) | |
17 | ); | |
18 | ||
0a7de745 | 19 | char g_target_path[PATH_MAX]; |
5ba3f43e | 20 | |
cb323159 | 21 | T_DECL(syscall, "xnu_quick_test for syscall") |
5ba3f43e | 22 | { |
0a7de745 A |
23 | int my_fd = -1; |
24 | char * my_pathp; | |
5ba3f43e A |
25 | kern_return_t my_kr; |
26 | ||
27 | T_SETUPBEGIN; | |
28 | ||
29 | create_target_directory(TEST_DIRECTORY); | |
0a7de745 | 30 | |
5ba3f43e A |
31 | T_SETUPEND; |
32 | ||
0a7de745 A |
33 | my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, |
34 | PATH_MAX, VM_FLAGS_ANYWHERE); | |
5ba3f43e A |
35 | T_ASSERT_MACH_SUCCESS(my_kr, "Allocating vm to path %s", my_pathp); |
36 | ||
37 | *my_pathp = 0x00; | |
38 | strcpy( my_pathp, &g_target_path[0] ); | |
39 | strcat( my_pathp, "/" ); | |
40 | ||
41 | /* create a test file */ | |
0a7de745 | 42 | |
5ba3f43e A |
43 | T_ASSERT_MACH_SUCCESS( create_random_name( my_pathp, 1), "Create random test file" ); |
44 | /* use an indirect system call to open our test file. | |
45 | * I picked open since it uses a path pointer which grows to 64 bits in an LP64 environment. | |
46 | */ | |
47 | T_EXPECT_NE(my_fd = syscall( SYS_open, my_pathp, (O_RDWR | O_EXCL), 0 ), | |
0a7de745 | 48 | -1, "Attempt to open file using indirect syscall %s", my_pathp); |
5ba3f43e | 49 | |
0a7de745 | 50 | if (my_fd != -1) { |
5ba3f43e | 51 | close(my_fd); |
0a7de745 A |
52 | } |
53 | ||
5ba3f43e | 54 | if (my_pathp != NULL) { |
0a7de745 | 55 | remove(my_pathp); |
5ba3f43e A |
56 | vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX); |
57 | } | |
58 | ||
59 | T_ATEND(remove_target_directory); | |
60 | } | |
61 | ||
0a7de745 | 62 | T_DECL(fork_wait4_exit, |
cb323159 | 63 | "Tests forking off a process and waiting for the child to exit") |
813fb2f6 | 64 | { |
0a7de745 A |
65 | int my_err, my_status; |
66 | pid_t my_pid, my_wait_pid; | |
67 | struct rusage my_usage; | |
68 | ||
5ba3f43e | 69 | strncpy(g_target_path, "/", 2); |
813fb2f6 A |
70 | |
71 | /* spin off another process */ | |
72 | T_ASSERT_NE(my_pid = fork(), -1, "Fork off a process"); | |
0a7de745 A |
73 | |
74 | if (my_pid == 0) { | |
75 | struct stat my_sb; | |
76 | ||
813fb2f6 A |
77 | /* child process does very little then exits */ |
78 | my_err = stat( &g_target_path[0], &my_sb ); | |
79 | T_WITH_ERRNO; | |
0a7de745 | 80 | T_ASSERT_TRUE(my_err == 0, "stat call with path: \"%s\" returned \"%d\"", &g_target_path[0], errno); |
813fb2f6 A |
81 | exit( 44 ); |
82 | } | |
0a7de745 | 83 | |
813fb2f6 A |
84 | /* parent process waits for child to exit */ |
85 | T_ASSERT_NE(my_wait_pid = wait4( my_pid, &my_status, 0, &my_usage ), -1, | |
0a7de745 | 86 | "Wait for child to exit\n"); |
813fb2f6 A |
87 | |
88 | /* wait4 should return our child's pid when it exits */ | |
0a7de745 A |
89 | T_ASSERT_EQ(my_wait_pid, my_pid, |
90 | "wait4 should return our child's pid when it exits"); | |
91 | ||
92 | /* kind of just guessing on these values so if this fails we should take a closer | |
93 | * look at the returned rusage structure. | |
813fb2f6 | 94 | */ |
0a7de745 A |
95 | T_ASSERT_FALSE((my_usage.ru_utime.tv_sec > 1 || |
96 | my_usage.ru_stime.tv_sec > 1 || my_usage.ru_majflt > 1000 || | |
97 | my_usage.ru_msgsnd > 100), "wait4 returned rusage structure"); | |
813fb2f6 | 98 | |
0a7de745 A |
99 | T_ASSERT_TRUE((WIFEXITED( my_status ) && WEXITSTATUS( my_status ) == 44), |
100 | "check if wait4 returns right exit status"); | |
813fb2f6 | 101 | } |
5ba3f43e | 102 | |
cb323159 | 103 | T_DECL(getrusage, "check getrusage works") |
5ba3f43e | 104 | { |
cb323159 A |
105 | struct rusage rubuf; |
106 | ||
107 | int ret = getrusage(RUSAGE_SELF, &rubuf); | |
108 | T_ASSERT_POSIX_SUCCESS(ret, "getrusage for self"); | |
109 | ||
110 | T_EXPECT_LT(rubuf.ru_msgrcv, 1000, "upper bound on messages received"); | |
111 | T_EXPECT_GE(rubuf.ru_msgrcv, 0, "lower bound on messages reseived"); | |
112 | T_EXPECT_LT(rubuf.ru_nsignals, 1000, "upper bound on signals"); | |
113 | T_EXPECT_GE(rubuf.ru_nsignals, 0, "lower bound on signals"); | |
5ba3f43e | 114 | } |