/* * stress_fork_fn() * stress by forking and exiting using * fork function fork_fn (fork or vfork) */ int stress_fork_fn( uint64_t *const counter, const uint32_t instance, const uint64_t max_ops, const char *name, pid_t (*fork_fn)(void), const uint64_t fork_max) { (void)instance; pid_t pids[MAX_FORKS]; do { unsigned int i; memset(pids, 0, sizeof(pids)); for (i = 0; i < fork_max; i++) { pids[i] = fork_fn(); if (pids[i] == 0) { setpgid(0, pgrp); stress_parent_died_alarm(); /* Child, immediately exit */ _exit(0); } if (pids[i] > -1) setpgid(pids[i], pgrp); if (!opt_do_run) break; } for (i = 0; i < fork_max; i++) { if (pids[i] > 0) { int status; /* Parent, wait for child */ (void)waitpid(pids[i], &status, 0); (*counter)++; } } for (i = 0; i < fork_max; i++) { if ((pids[i] < 0) && (opt_flags & OPT_FLAGS_VERIFY)) { pr_fail(stderr, "%s: fork failed\n", name); } } } while (opt_do_run && (!max_ops || *counter < max_ops)); return EXIT_SUCCESS; }
static void TestGetPidCachingWithFork(int (*fork_fn)()) { pid_t parent_pid = getpid(); ASSERT_EQ(syscall(__NR_getpid), parent_pid); pid_t fork_result = fork_fn(); ASSERT_NE(fork_result, -1); if (fork_result == 0) { // We're the child. AssertGetPidCorrect(); ASSERT_EQ(parent_pid, getppid()); _exit(123); } else { // We're the parent. ASSERT_EQ(parent_pid, getpid()); AssertChildExited(fork_result, 123); } }
static void TestGetPidCachingWithFork(int (*fork_fn)()) { pid_t parent_pid = getpid(); ASSERT_EQ(syscall(__NR_getpid), parent_pid); pid_t fork_result = fork_fn(); ASSERT_NE(fork_result, -1); if (fork_result == 0) { // We're the child. AssertGetPidCorrect(); ASSERT_EQ(parent_pid, getppid()); _exit(123); } else { // We're the parent. ASSERT_EQ(parent_pid, getpid()); int status; ASSERT_EQ(fork_result, waitpid(fork_result, &status, 0)); ASSERT_TRUE(WIFEXITED(status)); ASSERT_EQ(123, WEXITSTATUS(status)); } }