/* * Parameterized test function bodies */ void test_eagain(size_t sndbufsize, size_t rcvbufsize) { int i; int sv[2]; const size_t totalsize = (sndbufsize + rcvbufsize) * 2; const size_t pktsize = MIN(sndbufsize, rcvbufsize) / 4; char sndbuf[pktsize]; char recv_buf[pktsize]; ssize_t ssize, rsize; /* setup the socket pair */ do_socketpair_nonblocking(sv); /* Setup the buffers */ ATF_REQUIRE_EQ(0, setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbufsize, sizeof(sndbufsize))); ATF_REQUIRE_EQ(0, setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rcvbufsize, sizeof(rcvbufsize))); bzero(sndbuf, pktsize); /* Send data until we get EAGAIN */ for(i=0; i < totalsize / pktsize; i++) { ssize = send(sv[0], sndbuf, pktsize, MSG_EOR); if (ssize == -1) { if (errno == EAGAIN) atf_tc_pass(); else { perror("send"); atf_tc_fail("send returned < 0 but not EAGAIN"); } } } atf_tc_fail("Never got EAGAIN"); }
static void h_check(int test) { struct sigaction sa; jmp_buf jb; sigjmp_buf sjb; sigset_t ss; int i, x; myself = pthread_self(); i = getpid(); if (test == TEST_SETJMP || test == TEST_SIGSETJMP_SAVE) expectsignal = 0; else if (test == TEST_U_SETJMP || test == TEST_SIGSETJMP_NOSAVE) expectsignal = 1; else atf_tc_fail("unknown test"); sa.sa_handler = aborthandler; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; REQUIRE_ERRNO(sigaction(SIGABRT, &sa, NULL) != -1); REQUIRE_ERRNO(sigemptyset(&ss) != -1); REQUIRE_ERRNO(sigaddset(&ss, SIGABRT) != -1); REQUIRE_ERRNO(sigprocmask(SIG_BLOCK, &ss, NULL) != -1); ATF_REQUIRE(myself == pthread_self()); if (test == TEST_SETJMP) x = setjmp(jb); else if (test == TEST_U_SETJMP) x = _setjmp(jb); else x = sigsetjmp(sjb, !expectsignal); if (x != 0) { ATF_REQUIRE(myself == pthread_self()); ATF_REQUIRE_MSG(x == i, "setjmp returned wrong value"); kill(i, SIGABRT); ATF_REQUIRE_MSG(!expectsignal, "kill(SIGABRT) failed"); ATF_REQUIRE(myself == pthread_self()); atf_tc_pass(); } ATF_REQUIRE(myself == pthread_self()); REQUIRE_ERRNO(sigprocmask(SIG_UNBLOCK, &ss, NULL) != -1); if (test == TEST_SETJMP) longjmp(jb, i); else if (test == TEST_U_SETJMP) _longjmp(jb, i); else siglongjmp(sjb, i); atf_tc_fail("jmp failed"); }
static void aborthandler(int signo __unused) { ATF_REQUIRE(myself == pthread_self()); ATF_REQUIRE_MSG(expectsignal, "kill(SIGABRT) succeeded"); atf_tc_pass(); }
static void callback(const char *file, int line, isc_assertiontype_t type, const char *cond) { UNUSED(file); UNUSED(line); UNUSED(type); UNUSED(cond); if (strcmp(tempname, "dtXXXXXXXX")) unlink(tempname); atf_tc_pass(); exit(0); }
static void sigalrm_action(int signo, siginfo_t *info, void *ptr) { sig_debug(signo, info, (ucontext_t *)ptr); ATF_REQUIRE_EQ(info->si_signo, SIGALRM); ATF_REQUIRE_EQ(info->si_code, SI_TIMER); ATF_REQUIRE_EQ(info->si_value.sival_int, ITIMER_REAL); atf_tc_pass(); /* NOTREACHED */ }
static void sigsegv_action(int signo, siginfo_t *info, void *ptr) { sig_debug(signo, info, (ucontext_t *)ptr); ATF_REQUIRE_EQ(info->si_signo, SIGSEGV); ATF_REQUIRE_EQ(info->si_errno, 0); ATF_REQUIRE_EQ(info->si_code, SEGV_MAPERR); ATF_REQUIRE_EQ(info->si_addr, (void *)0); atf_tc_pass(); /* NOTREACHED */ }
static void sigbus_action(int signo, siginfo_t *info, void *ptr) { printf("si_addr = %p\n", info->si_addr); sig_debug(signo, info, (ucontext_t *)ptr); ATF_REQUIRE_EQ(info->si_signo, SIGBUS); ATF_REQUIRE_EQ(info->si_errno, 0); ATF_REQUIRE_EQ(info->si_code, BUS_ADRALN); if (strcmp(atf_config_get("atf_arch"), "i386") == 0 || strcmp(atf_config_get("atf_arch"), "x86_64") == 0) { atf_tc_expect_fail("x86 architecture does not correctly " "report the address where the unaligned access occured"); } ATF_REQUIRE_EQ(info->si_addr, (volatile void *)addr); atf_tc_pass(); /* NOTREACHED */ }
ATF_TC_BODY(deadlock, tc) { int fd; int error; int ret; pid_t pid; (void)unlink(lockfile); fd = open (lockfile, O_RDWR|O_CREAT|O_EXCL|O_TRUNC, 0666); ATF_REQUIRE_MSG(fd >= 0, "open(%s): %s", lockfile, strerror(errno)); ATF_REQUIRE_MSG(ftruncate(fd, filesize) >= 0, "ftruncate(%s): %s", lockfile, strerror(errno)); fsync(fd); error = dolock(fd, F_LOCK, 0, 1); ATF_REQUIRE_MSG(error == 0, "initial dolock: %s", strerror(errno)); pid = fork(); ATF_REQUIRE_MSG(pid != -1, "fork failed: %s", strerror(errno)); if (pid == 0) { error = dolock(fd, F_LOCK, 1, 1); ATF_REQUIRE_MSG(error == 0, "child dolock: %s", strerror(errno)); dolock(fd, F_LOCK, 0, 1); /* will block */ atf_tc_fail("child did not block"); } sleep(1); /* give child time to grab its lock then block */ error = dolock(fd, F_LOCK, 1, 1); ATF_REQUIRE_MSG(error == EDEADLK, "parent did not detect deadlock: %s", strerror(errno)); ret = kill(pid, SIGKILL); ATF_REQUIRE_MSG(ret != -1, "failed to kill child: %s", strerror(errno)); atf_tc_pass(); }
ATF_TC_BODY(buffer_allocate, tc) { struct buffer *buf = 0; /* * Check a 0-length buffer. */ buf = NULL; if (!buffer_allocate(&buf, 0, MDL)) { atf_tc_fail("failed on 0-len buffer"); } if (!buffer_dereference(&buf, MDL)) { atf_tc_fail("buffer_dereference() failed"); } if (buf != NULL) { atf_tc_fail("buffer_dereference() did not NULL-out buffer"); } /* * Check an actual buffer. */ buf = NULL; if (!buffer_allocate(&buf, 100, MDL)) { atf_tc_fail("failed on allocate 100 bytes\n"); } if (!buffer_dereference(&buf, MDL)) { atf_tc_fail("buffer_dereference() failed"); } if (buf != NULL) { atf_tc_fail("buffer_dereference() did not NULL-out buffer"); } /* * Okay, we're happy. */ atf_tc_pass(); }
ATF_TC_BODY(randlock, tc) { int i, j, fd; int pipe_fd[2]; pid_t *pid; int status; char pipe_in, pipe_out; const char pipe_errmsg[] = "child: pipe write failed\n"; (void)unlink(lockfile); fd = open (lockfile, O_RDWR|O_CREAT|O_EXCL|O_TRUNC, 0666); ATF_REQUIRE_MSG(fd >= 0, "open(%s): %s", lockfile, strerror(errno)); ATF_REQUIRE_MSG(ftruncate(fd, filesize) >= 0, "ftruncate(%s): %s", lockfile, strerror(errno)); ATF_REQUIRE_MSG(pipe(pipe_fd) == 0, "pipe: %s", strerror(errno)); fsync(fd); close(fd); pid = malloc(nprocs * sizeof(pid_t)); for (i = 0; i < nprocs; i++) { pipe_out = (char)('A' + i); pid[i] = fork(); switch (pid[i]) { case 0: if (write(pipe_fd[1], &pipe_out, 1) != 1) write(STDERR_FILENO, pipe_errmsg, __arraycount(pipe_errmsg) - 1); else trylocks(i); _exit(0); break; case -1: atf_tc_fail("fork %d failed", i); break; default: ATF_REQUIRE_MSG(read(pipe_fd[0], &pipe_in, 1) == 1, "parent: read_pipe(%i): %s", i, strerror(errno)); ATF_REQUIRE_MSG(pipe_in == pipe_out, "parent: pipe does not match"); break; } } for (j = 0; j < npasses; j++) { printf("parent: run %i\n", j+1); for (i = 0; i < nprocs; i++) { ATF_REQUIRE_MSG(ptrace(PT_ATTACH, pid[i], 0, 0) >= 0, "ptrace attach %d", pid[i]); ATF_REQUIRE_MSG(waitpid(pid[i], &status, WUNTRACED) >= 0, "waitpid(ptrace)"); usleep(sleeptime / 3); ATF_REQUIRE_MSG(ptrace(PT_DETACH, pid[i], (caddr_t)1, 0) >= 0, "ptrace detach %d", pid[i]); usleep(sleeptime / 3); } } for (i = 0; i < nprocs; i++) { printf("reap %d: ", i); fflush(stdout); kill(pid[i], SIGINT); waitpid(pid[i], &status, 0); printf(" status %d\n", status); } atf_tc_pass(); }
ATF_TC_BODY(pass, tc) { atf_tc_pass(); }
ATF_TC_BODY(msg, tc) { struct sigaction sa; struct msqid_ds m_ds; struct mymsg m; sigset_t sigmask; int loop; int c_status; /* * Install a SIGSYS handler so that we can exit gracefully if * System V Message Queue support isn't in the kernel. */ did_sigsys = 0; sa.sa_handler = sigsys_handler; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; ATF_REQUIRE_MSG(sigaction(SIGSYS, &sa, NULL) != -1, "sigaction SIGSYS: %d", errno); /* * Install a SIGCHLD handler to deal with all possible exit * conditions of the receiver. */ did_sigchild = 0; child_count = 0; sa.sa_handler = sigchld_handler; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; ATF_REQUIRE_MSG(sigaction(SIGCHLD, &sa, NULL) != -1, "sigaction SIGCHLD: %d", errno); msgkey = get_ftok(4160); ATF_REQUIRE_MSG(msgkey != (key_t)-1, "get_ftok failed"); sender_msqid = msgget(msgkey, IPC_CREAT | 0640); ATF_REQUIRE_MSG(sender_msqid != -1, "msgget: %d", errno); if (did_sigsys) { atf_tc_skip("SYSV Message Queue not supported"); return; } ATF_REQUIRE_MSG(msgctl(sender_msqid, IPC_STAT, &m_ds) != -1, "msgctl IPC_STAT 1: %d", errno); print_msqid_ds(&m_ds, 0640); m_ds.msg_perm.mode = (m_ds.msg_perm.mode & ~0777) | 0600; ATF_REQUIRE_MSG(msgctl(sender_msqid, IPC_SET, &m_ds) != -1, "msgctl IPC_SET: %d", errno); memset(&m_ds, 0, sizeof(m_ds)); ATF_REQUIRE_MSG(msgctl(sender_msqid, IPC_STAT, &m_ds) != -1, "msgctl IPC_STAT 2: %d", errno); ATF_REQUIRE_MSG((m_ds.msg_perm.mode & 0777) == 0600, "IPC_SET of mode didn't hold"); print_msqid_ds(&m_ds, 0600); switch ((child_pid = fork())) { case -1: atf_tc_fail("fork: %d", errno); return; case 0: child_count++; receiver(); break; default: break; } for (loop = 0; loop < maxloop; loop++) { /* * Send the first message to the receiver and wait for the ACK. */ m.mtype = MTYPE_1; strcpy(m.mtext, m1_str); ATF_REQUIRE_MSG(msgsnd(sender_msqid, &m, sizeof(m), 0) != -1, "sender: msgsnd 1: %d", errno); ATF_REQUIRE_MSG(msgrcv(sender_msqid, &m, sizeof(m), MTYPE_1_ACK, 0) == sizeof(m), "sender: msgrcv 1 ack: %d", errno); print_msqid_ds(&m_ds, 0600); /* * Send the second message to the receiver and wait for the ACK. */ m.mtype = MTYPE_2; strcpy(m.mtext, m2_str); ATF_REQUIRE_MSG(msgsnd(sender_msqid, &m, sizeof(m), 0) != -1, "sender: msgsnd 2: %d", errno); ATF_REQUIRE_MSG(msgrcv(sender_msqid, &m, sizeof(m), MTYPE_2_ACK, 0) == sizeof(m), "sender: msgrcv 2 ack: %d", errno); } /* * Wait for child to finish */ sigemptyset(&sigmask); (void) sigsuspend(&sigmask); /* * ...and any other signal is an unexpected error. */ if (did_sigchild) { c_status = child_status; if (c_status < 0) atf_tc_fail("waitpid: %d", -c_status); else if (WIFEXITED(c_status) == 0) atf_tc_fail("child abnormal exit: %d", c_status); else if (WEXITSTATUS(c_status) != 0) atf_tc_fail("c status: %d", WEXITSTATUS(c_status)); else { ATF_REQUIRE_MSG(msgctl(sender_msqid, IPC_STAT, &m_ds) != -1, "msgctl IPC_STAT: %d", errno); print_msqid_ds(&m_ds, 0600); atf_tc_pass(); } } else atf_tc_fail("sender: received unexpected signal"); }
int sleeptest(int (*test)(struct timespec *, struct timespec *), bool subsec, bool sim_remain) { struct timespec tsa, tsb, tslp, tremain; int64_t delta1, delta2, delta3, round; sig = 0; signal(SIGALRM, sigalrm); if (subsec) { round = 1; delta3 = FUZZ; } else { round = 1000000000; delta3 = round; } tslp.tv_sec = delta3 / 1000000000; tslp.tv_nsec = delta3 % 1000000000; while (tslp.tv_sec <= MAXSLEEP) { /* * disturb sleep by signal on purpose */ if (tslp.tv_sec > ALARM && sig == 0) alarm(ALARM); clock_gettime(CLOCK_REALTIME, &tsa); (*test)(&tslp, &tremain); clock_gettime(CLOCK_REALTIME, &tsb); if (sim_remain) { timespecsub(&tsb, &tsa, &tremain); timespecsub(&tslp, &tremain, &tremain); } delta1 = (int64_t)tsb.tv_sec - (int64_t)tsa.tv_sec; delta1 *= BILLION; delta1 += (int64_t)tsb.tv_nsec - (int64_t)tsa.tv_nsec; delta2 = (int64_t)tremain.tv_sec * BILLION; delta2 += (int64_t)tremain.tv_nsec; delta3 = (int64_t)tslp.tv_sec * BILLION; delta3 += (int64_t)tslp.tv_nsec - delta1 - delta2; delta3 /= round; delta3 *= round; if (delta3 > FUZZ || delta3 < -FUZZ) { if (!sim_remain) atf_tc_expect_fail("Long reschedule latency " "due to PR kern/43997"); atf_tc_fail("Reschedule latency %"PRId64" exceeds " "allowable fuzz %lld", delta3, FUZZ); } delta3 = (int64_t)tslp.tv_sec * 2 * BILLION; delta3 += (int64_t)tslp.tv_nsec * 2; delta3 /= round; delta3 *= round; if (delta3 < FUZZ) break; tslp.tv_sec = delta3 / BILLION; tslp.tv_nsec = delta3 % BILLION; } ATF_REQUIRE_MSG(sig == 1, "Alarm did not fire!"); atf_tc_pass(); }
ATF_TC_BODY(shm, tc) { struct sigaction sa; struct shmid_ds s_ds; sigset_t sigmask; char *shm_buf; int sender_shmid; int c_status; /* * Install a SIGSYS handler so that we can exit gracefully if * System V Shared Memory support isn't in the kernel. */ did_sigsys = 0; sa.sa_handler = sigsys_handler; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; ATF_REQUIRE_MSG(sigaction(SIGSYS, &sa, NULL) != -1, "sigaction SIGSYS: %d", errno); /* * Install a SIGCHLD handler to deal with all possible exit * conditions of the sharer. */ did_sigchild = 0; child_count = 0; sa.sa_handler = sigchld_handler; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; ATF_REQUIRE_MSG(sigaction(SIGCHLD, &sa, NULL) != -1, "sigaction SIGCHLD: %d", errno); pgsize = sysconf(_SC_PAGESIZE); shmkey = get_ftok(4160); ATF_REQUIRE_MSG(shmkey != (key_t)-1, "get_ftok failed"); ATF_REQUIRE_MSG((sender_shmid = shmget(shmkey, pgsize, IPC_CREAT | 0640)) != -1, "shmget: %d", errno); write_int("sender_shmid", sender_shmid); ATF_REQUIRE_MSG(shmctl(sender_shmid, IPC_STAT, &s_ds) != -1, "shmctl IPC_STAT: %d", errno); print_shmid_ds(&s_ds, 0640); s_ds.shm_perm.mode = (s_ds.shm_perm.mode & ~0777) | 0600; ATF_REQUIRE_MSG(shmctl(sender_shmid, IPC_SET, &s_ds) != -1, "shmctl IPC_SET: %d", errno); memset(&s_ds, 0, sizeof(s_ds)); ATF_REQUIRE_MSG(shmctl(sender_shmid, IPC_STAT, &s_ds) != -1, "shmctl IPC_STAT: %d", errno); ATF_REQUIRE_MSG((s_ds.shm_perm.mode & 0777) == 0600, "IPC_SET of mode didn't hold"); print_shmid_ds(&s_ds, 0600); shm_buf = shmat(sender_shmid, NULL, 0); ATF_REQUIRE_MSG(shm_buf != (void *) -1, "sender: shmat: %d", errno); /* * Write the test pattern into the shared memory buffer. */ strcpy(shm_buf, m2_str); switch ((child_pid = fork())) { case -1: atf_tc_fail("fork: %d", errno); return; case 0: sharer(); break; default: break; } /* * Wait for child to finish */ sigemptyset(&sigmask); (void) sigsuspend(&sigmask); if (did_sigchild) { c_status = child_status; if (c_status < 0) atf_tc_fail("waitpid: %d", -c_status); else if (WIFEXITED(c_status) == 0) atf_tc_fail("c abnormal exit: %d", c_status); else if (WEXITSTATUS(c_status) != 0) atf_tc_fail("c status: %d", WEXITSTATUS(c_status)); else { ATF_REQUIRE_MSG(shmctl(sender_shmid, IPC_STAT, &s_ds) != -1, "shmctl IPC_STAT: %d", errno); print_shmid_ds(&s_ds, 0600); atf_tc_pass(); } } else atf_tc_fail("sender: received unexpected signal"); }
ATF_TC_BODY(sem, tc) { struct sigaction sa; union semun sun; struct semid_ds s_ds; sigset_t sigmask; int sender_semid; int i; int c_status; /* * Install a SIGSYS handler so that we can exit gracefully if * System V Semaphore support isn't in the kernel. */ did_sigsys = 0; sa.sa_handler = sigsys_handler; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; ATF_REQUIRE_MSG(sigaction(SIGSYS, &sa, NULL) != -1, "sigaction SIGSYS: %d", errno); /* * Install a SIGCHLD handler to deal with all possible exit * conditions of the receiver. */ did_sigchild = 0; child_count = 0; sa.sa_handler = sigchld_handler; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; ATF_REQUIRE_MSG(sigaction(SIGCHLD, &sa, NULL) != -1, "sigaction SIGCHLD: %d", errno); semkey = get_ftok(4160); ATF_REQUIRE_MSG(semkey != (key_t)-1, "get_ftok failed"); sender_semid = semget(semkey, 1, IPC_CREAT | 0640); ATF_REQUIRE_MSG(sender_semid != -1, "semget: %d", errno); write_int("sender_semid", sender_semid); if (did_sigsys) { atf_tc_skip("SYSV Semaphore not supported"); return; } sun.buf = &s_ds; ATF_REQUIRE_MSG(semctl(sender_semid, 0, IPC_STAT, sun) != -1, "semctl IPC_STAT: %d", errno); print_semid_ds(&s_ds, 0640); s_ds.sem_perm.mode = (s_ds.sem_perm.mode & ~0777) | 0600; sun.buf = &s_ds; ATF_REQUIRE_MSG(semctl(sender_semid, 0, IPC_SET, sun) != -1, "semctl IPC_SET: %d", errno); memset(&s_ds, 0, sizeof(s_ds)); sun.buf = &s_ds; ATF_REQUIRE_MSG(semctl(sender_semid, 0, IPC_STAT, sun) != -1, "semctl IPC_STAT: %d", errno); ATF_REQUIRE_MSG((s_ds.sem_perm.mode & 0777) == 0600, "IPC_SET of mode didn't hold"); print_semid_ds(&s_ds, 0600); for (child_count = 0; child_count < 5; child_count++) { switch ((child_pid = fork())) { case -1: atf_tc_fail("fork: %d", errno); return; case 0: waiter(); break; default: break; } } /* * Wait for all of the waiters to be attempting to acquire the * semaphore. */ for (;;) { i = semctl(sender_semid, 0, GETNCNT); if (i == -1) atf_tc_fail("semctl GETNCNT: %d", i); if (i == 5) break; } /* * Now set the thundering herd in motion by initializing the * semaphore to the value 1. */ sun.val = 1; ATF_REQUIRE_MSG(semctl(sender_semid, 0, SETVAL, sun) != -1, "sender: semctl SETVAL to 1: %d", errno); /* * Wait for all children to finish */ sigemptyset(&sigmask); for (;;) { (void) sigsuspend(&sigmask); if (did_sigchild) { c_status = child_status; if (c_status < 0) atf_tc_fail("waitpid: %d", -c_status); else if (WIFEXITED(c_status) == 0) atf_tc_fail("c abnormal exit: %d", c_status); else if (WEXITSTATUS(c_status) != 0) atf_tc_fail("c status: %d", WEXITSTATUS(c_status)); else { sun.buf = &s_ds; ATF_REQUIRE_MSG(semctl(sender_semid, 0, IPC_STAT, sun) != -1, "semctl IPC_STAT: %d", errno); print_semid_ds(&s_ds, 0600); atf_tc_pass(); } if (child_count <= 0) break; did_sigchild = 0; } else { atf_tc_fail("sender: received unexpected signal"); break; } } }