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