Loading...
#include <sys/wait.h> #include <stdlib.h> #include <unistd.h> #include <darwintest.h> T_GLOBAL_META(T_META_RUN_CONCURRENTLY(true)); static void func_a(void) { if (write(STDOUT_FILENO, "a", 1) != 1) _Exit(1); } static void func_b(void) { if (write(STDOUT_FILENO, "b", 1) != 1) _Exit(1); } static void func_c(void) { if (write(STDOUT_FILENO, "c", 1) != 1) _Exit(1); } static void child(void) { // this will be received by the parent printf("hello, "); fflush(stdout); // this won't, because quick_exit() does not flush printf("world"); // these will be called in reverse order, producing "abc" if (at_quick_exit(func_c) != 0 || at_quick_exit(func_b) != 0 || at_quick_exit(func_a) != 0) _Exit(1); quick_exit(0); } T_DECL(quick_exit, "Test quick_exit and at_quick_exit") { char buf[100] = ""; ssize_t len; int p[2], wstatus = 0; pid_t pid; T_ASSERT_POSIX_SUCCESS(pipe(p), NULL); pid = fork(); if (pid == 0) { if (dup2(p[1], STDOUT_FILENO) < 0) _Exit(1); (void)close(p[1]); (void)close(p[0]); child(); _Exit(1); } T_ASSERT_POSIX_SUCCESS(pid, "expect fork() to succeed"); T_EXPECT_EQ(waitpid(pid, &wstatus, 0), pid, "expect to collect child process"); T_EXPECT_EQ(wstatus, 0, "expect child to exit cleanly"); T_EXPECT_POSIX_SUCCESS(len = read(p[0], buf, sizeof(buf)), NULL); T_EXPECT_EQ_STR(buf, "hello, abc", NULL); } |