static void print_result(const char *file, const int lineno, int ttype, const char *fmt, va_list va) { char buf[1024]; char *str = buf; int ret, size = sizeof(buf); const char *str_errno = NULL; const char *res; switch (TTYPE_RESULT(ttype)) { case TPASS: res = "PASS"; break; case TFAIL: res = "FAIL"; break; case TBROK: res = "BROK"; break; case TCONF: res = "CONF"; break; case TWARN: res = "WARN"; break; case TINFO: res = "INFO"; break; default: tst_brk(TBROK, "Invalid ttype value %i", ttype); } if (ttype & TERRNO) str_errno = tst_strerrno(errno); if (ttype & TTERRNO) str_errno = tst_strerrno(TEST_ERRNO); ret = snprintf(str, size, "%s:%i: %s: ", file, lineno, res); str += ret; size -= ret; ret = vsnprintf(str, size, fmt, va); str += ret; size -= ret; if (str_errno) snprintf(str, size, ": %s\n", str_errno); else snprintf(str, size, "\n"); fputs(buf, stderr); }
static void check_vulnerable(void) { struct hostent resbuf; struct hostent *result; int herrno; int retval; char name[sizeof(temp.buffer)]; size_t len; /* * <glibc>/nss/digits_dots.c: * strlen(name) = size_needed - sizeof(*host_addr) - * sizeof(*h_addr_ptrs) - 1; */ len = sizeof(temp.buffer) - 16 - 2 * sizeof(char *) - 1; memset(name, '0', len); name[len] = '\0'; retval = gethostbyname_r(name, &resbuf, temp.buffer, sizeof(temp.buffer), &result, &herrno); if (strcmp(temp.canary, CANARY) != 0) { tst_resm(TFAIL, "vulnerable"); return; } if (retval == ERANGE) { tst_resm(TPASS, "not vulnerable"); return; } tst_resm(TFAIL, "gethostbyname_r() returned %s, expected ERANGE", tst_strerrno(retval)); }
static void verify_quota(void) { struct fs_disk_quota res_dquota; res_dquota.d_id = 1; TEST(quotactl(QCMD(Q_XGETNEXTQUOTA, USRQUOTA), tst_device->dev, test_id, (void *)&res_dquota)); if (TST_RET != -1) { tst_res(TFAIL, "quotactl() found the next active ID:" " %u unexpectedly", res_dquota.d_id); return; } if (TST_ERR == EINVAL) { tst_brk(TCONF | TTERRNO, "Q_XGETNEXTQUOTA wasn't supported in quotactl()"); } if (TST_ERR != ENOENT) { tst_res(TFAIL | TTERRNO, "quotactl() failed unexpectedly with" " %s expected ENOENT", tst_strerrno(TST_ERR)); } else { tst_res(TPASS, "quotactl() failed with ENOENT as expected"); } }
static void verify_socketpair(unsigned int n) { struct test_case_t *tc = &tdat[n]; TEST(socketpair(tc->domain, tc->type, tc->proto, tc->sv)); if (TST_RET == 0) { SAFE_CLOSE(fds[0]); SAFE_CLOSE(fds[1]); } if (TST_RET != tc->retval) { tst_res(TFAIL, "%s returned %ld (expected %d)", tc->desc, TST_RET, tc->retval); return; } if (TST_ERR != tc->experrno) { tst_res(TFAIL | TTERRNO, "expected %s(%d)", tst_strerrno(tc->experrno), tc->experrno); return; } tst_res(TPASS, "%s successful", tc->desc); }
int tst_umount(const char *path) { int err, ret, i; for (i = 0; i < 50; i++) { ret = umount(path); err = errno; if (!ret) return 0; tst_resm(TINFO, "umount('%s') failed with %s, try %2i...", path, tst_strerrno(err), i+1); if (i == 0 && err == EBUSY) { tst_resm(TINFO, "Likely gvfsd-trash is probing newly " "mounted fs, kill it to speed up tests."); } usleep(100000); } tst_resm(TWARN, "Failed to umount('%s') after 50 retries", path); errno = err; return -1; }
static void detach_device(const char *dev) { int dev_fd, ret, i; dev_fd = open(dev, O_RDONLY); if (dev_fd < 0) { tst_resm(TWARN | TERRNO, "open(%s) failed", dev); return; } /* keep trying to clear LOOPDEV until we get ENXIO, a quick succession * of attach/detach might not give udev enough time to complete */ for (i = 0; i < 40; i++) { ret = ioctl(dev_fd, LOOP_CLR_FD, 0); if (ret && (errno == ENXIO)) { close(dev_fd); return; } if (ret && (errno != EBUSY)) { tst_resm(TWARN, "ioctl(%s, LOOP_CLR_FD, 0) unexpectedly failed with: %s", dev, tst_strerrno(errno)); } usleep(50000); } close(dev_fd); tst_resm(TWARN, "ioctl(%s, LOOP_CLR_FD, 0) no ENXIO for too long", dev); }
static void verify_socket(unsigned int n) { int fd; struct test_case_t *tc = &tdat[n]; TEST(fd = socket(tc->domain, tc->type, tc->proto)); if (TEST_RETURN >= 0) TEST_RETURN = 0; if (fd > 0) SAFE_CLOSE(fd); if (TEST_RETURN != tc->retval) { tst_res(TFAIL, "%s returned %d (expected %d)", tc->desc, fd, tc->retval); return; } if (TEST_ERRNO != tc->experrno) { tst_res(TFAIL | TTERRNO, "expected %s(%d)", tst_strerrno(tc->experrno), tc->experrno); return; } tst_res(TPASS, "%s successful", tc->desc); }
static void verify_mount(struct test_case *tc) { if (tc->setup) tc->setup(); TEST(mount(*tc->device, *tc->mntpoint, *tc->fs_type, tc->flag, NULL)); if (TEST_RETURN != -1) { tst_resm(TFAIL, "mount() succeded unexpectedly (ret=%li)", TEST_RETURN); goto cleanup; } if (TEST_ERRNO != tc->exp_errno) { tst_resm(TFAIL | TTERRNO, "mount() was expected to fail with %s(%i)", tst_strerrno(tc->exp_errno), tc->exp_errno); goto cleanup; } tst_resm(TPASS | TTERRNO, "mount() failed expectedly"); cleanup: if (tc->cleanup) tc->cleanup(); }
static void verify_read(unsigned int n) { struct tcase *tc = &tcases[n]; if (tc->fd == &fd4 && *tc->fd == -1) { tst_res(TCONF, "O_DIRECT not supported on %s filesystem", tst_fs_type_name(fs_type)); return; } TEST(read(*tc->fd, *tc->buf, tc->count)); if (*tc->fd == fd4 && TEST_RETURN >= 0) { tst_res(TPASS, "O_DIRECT unaligned reads fallbacks to buffered I/O"); return; } if (TEST_RETURN != -1) { tst_res(TFAIL, "read() succeeded unexpectedly"); return; } if (TEST_ERRNO == tc->exp_error) { tst_res(TPASS | TTERRNO, "read() failed as expected"); } else { tst_res(TFAIL | TTERRNO, "read() failed unexpectedly, " "expected %s", tst_strerrno(tc->exp_error)); } }
static void test_hugeshmget(unsigned int i) { int shm_id_2 = -1; if (*tcases[i].skey == -1) { shm_id_2 = shmget(*(tcases[i].skey), 0, 0); if (shm_id_2 != -1) shmctl(shm_id_2, IPC_RMID, NULL); } TEST(shmget(*(tcases[i].skey), tcases[i].size_coe * shm_size, tcases[i].flags)); if (TST_RET != -1) { tst_res(TFAIL, "shmget succeeded unexpectedly"); return; } if (TST_ERR != tcases[i].error) { tst_res(TFAIL | TTERRNO, "shmget failed unexpectedly, expected %s", tst_strerrno(tcases[i].error)); return; } tst_res(TPASS | TTERRNO, "shmget failed as expected"); }
static void renameat2_verify(const struct test_case *test) { TEST(renameat2(*(test->olddirfd), test->oldpath, *(test->newdirfd), test->newpath, test->flags)); if ((test->flags & RENAME_EXCHANGE) && EINVAL == TEST_ERRNO && fs_type == TST_BTRFS_MAGIC) { tst_resm(TCONF, "RENAME_EXCHANGE flag is not implemeted on %s", tst_fs_type_name(fs_type)); return; } if (test->exp_errno && TEST_RETURN != -1) { tst_resm(TFAIL, "renameat2() succeeded unexpectedly"); return; } if (test->exp_errno == 0 && TEST_RETURN != 0) { tst_resm(TFAIL | TTERRNO, "renameat2() failed unexpectedly"); return; } if (test->exp_errno == TEST_ERRNO) { tst_resm(TPASS | TTERRNO, "renameat2() returned the expected value"); return; } tst_resm(TFAIL | TTERRNO, "renameat2() got unexpected return value: expected: %d - %s", test->exp_errno, tst_strerrno(test->exp_errno)); }
static void do_child(void) { int res, i, j, awake; pthread_t t[55]; for (i = 0; i < (int)ARRAY_SIZE(t); i++) { res = pthread_create(&t[i], NULL, threaded, (void*)((long)i)); if (res) { tst_brkm(TBROK, NULL, "pthread_create(): %s", tst_strerrno(res)); } } while (wait_for_threads(ARRAY_SIZE(t))) usleep(100); for (i = 1; i <= 10; i++) { clear_threads_awake(); res = futex_wake(&futex, i, FUTEX_PRIVATE_FLAG); if (i != res) { tst_resm(TFAIL, "futex_wake() woken up %i threads, expected %i", res, i); } for (j = 0; j < 100000; j++) { awake = threads_awake(); if (awake == i) break; usleep(100); } if (awake == i) { tst_resm(TPASS, "futex_wake() woken up %i threads", i); } else { tst_resm(TFAIL, "Woken up %i threads, expected %i", awake, i); } } res = futex_wake(&futex, 1, FUTEX_PRIVATE_FLAG); if (res) { tst_resm(TFAIL, "futex_wake() woken up %i, none were waiting", res); } else { tst_resm(TPASS, "futex_wake() woken up 0 threads"); } for (i = 0; i < (int)ARRAY_SIZE(t); i++) pthread_join(t[i], NULL); tst_exit(); }
int safe_pthread_join(const char *file, const int lineno, pthread_t thread_id, void **retval) { int rval; rval = pthread_join(thread_id, retval); if (rval) { tst_brk_(file, lineno, TBROK, "pthread_join(..., %p) failed: %s", retval, tst_strerrno(rval)); } return rval; }
int safe_pthread_create(const char *file, const int lineno, pthread_t *thread_id, const pthread_attr_t *attr, void *(*thread_fn)(void *), void *arg) { int rval; rval = pthread_create(thread_id, attr, thread_fn, arg); if (rval) { tst_brk_(file, lineno, TBROK, "pthread_create(%p,%p,%p,%p) failed: %s", thread_id, attr, thread_fn, arg, tst_strerrno(rval)); } return rval; }
static void detach_device(void (*cleanup_fn)(void), const char *dev) { int dev_fd, err; dev_fd = SAFE_OPEN(cleanup_fn, dev, O_RDONLY); if (ioctl(dev_fd, LOOP_CLR_FD, 0) < 0) { err = errno; close(dev_fd); tst_brkm(TBROK, cleanup_fn, "ioctl(%s, LOOP_CLR_FD, 0) failed: %s", dev, tst_strerrno(err)); } close(dev_fd); }
static void verify_shmat(struct test_case_t *tc) { void *addr; addr = shmat(*tc->shmid, *tc->shmaddr, 0); if (addr != (void *)-1) { tst_res(TFAIL, "shmat() succeeded unexpectedly"); return; } if (errno == tc->exp_err) { tst_res(TPASS | TERRNO, "shmat() failed as expected"); } else { tst_res(TFAIL | TERRNO, "shmat() failed unexpectedly," "expected: %s", tst_strerrno(tc->exp_err)); } }
static void verify_epoll_ctl(unsigned int n) { struct testcase *tc = &tcases[n]; TEST(epoll_ctl(*tc->epfds, tc->opt, *tc->fds, tc->ts_event)); if (TEST_RETURN != -1) { tst_res(TFAIL, "epoll_ctl() succeeds unexpectedly"); return; } if (tc->exp_err == TEST_ERRNO) { tst_res(TPASS | TTERRNO, "epoll_ctl() fails as expected"); } else { tst_res(TFAIL | TTERRNO, "epoll_ctl() fails unexpectedly, expected %i: %s", tc->exp_err, tst_strerrno(tc->exp_err)); } }
static void verify_request_key(unsigned int n) { struct test_case *tc = tcases + n; TEST(request_key("keyring", tc->des, NULL, *tc->id)); if (TST_RET != -1) { tst_res(TFAIL, "request_key() succeed unexpectly"); return; } if (TST_ERR == tc->exp_err) { tst_res(TPASS | TTERRNO, "request_key() failed expectly"); return; } tst_res(TFAIL | TTERRNO, "request_key() failed unexpectly, " "expected %s", tst_strerrno(tc->exp_err)); }
static void access_test(struct tcase *tc, const char *user) { TEST(access(tc->pathname, tc->mode)); if (TST_RET != -1) { tst_res(TFAIL, "access as %s succeeded unexpectedly", user); return; } if (tc->exp_errno != TST_ERR) { tst_res(TFAIL | TTERRNO, "access as %s should fail with %s", user, tst_strerrno(tc->exp_errno)); return; } tst_res(TPASS | TTERRNO, "access as %s failed expectedly", user); }
static void verify_preadv(unsigned int n) { struct tcase *tc = &tcases[n]; TEST(preadv(*tc->fd, tc->name, tc->count, tc->offset)); if (TEST_RETURN == 0) { tst_res(TFAIL, "preadv() succeeded unexpectedly"); return; } if (TEST_ERRNO == tc->exp_err) { tst_res(TPASS | TTERRNO, "preadv() failed as expected"); return; } tst_res(TFAIL | TTERRNO, "preadv() failed unexpectedly, expected %s", tst_strerrno(tc->exp_err)); }
static void verify_failure(struct tcase *tc, const char *user) { if (TST_RET != -1) { tst_res(TFAIL, "access(%s, %s) as %s succeded unexpectedly", tc->fname, tc->name, user); return; } if (TST_ERR != tc->exp_errno) { tst_res(TFAIL | TTERRNO, "access(%s, %s) as %s should fail with %s", tc->fname, tc->name, user, tst_strerrno(tc->exp_errno)); return; } tst_res(TPASS | TTERRNO, "access(%s, %s) as %s", tc->fname, tc->name, user); }
static void verify_madvise(unsigned int i) { struct tcase *tc = &tcases[i]; TEST(madvise(*(tc->addr), st.st_size, tc->advice)); if (TEST_RETURN == -1) { if (TEST_ERRNO == EINVAL) { tst_res(TCONF, "%s is not supported", tc->name); } else { tst_res(TFAIL, "madvise test for %s failed with " "return = %ld, errno = %d : %s", tc->name, TEST_RETURN, TEST_ERRNO, tst_strerrno(TFAIL | TTERRNO)); } } else { tst_res(TPASS, "madvise test for %s PASSED", tc->name); } }
static void attach_device(void (*cleanup_fn)(void), const char *dev, const char *file) { int dev_fd, file_fd, err; dev_fd = SAFE_OPEN(cleanup_fn, dev, O_RDWR); file_fd = SAFE_OPEN(cleanup_fn, file, O_RDWR); if (ioctl(dev_fd, LOOP_SET_FD, file_fd) < 0) { err = errno; close(dev_fd); close(file_fd); tst_brkm(TBROK, cleanup_fn, "ioctl(%s, LOOP_SET_FD, %s) failed: %s", dev, file, tst_strerrno(err)); } close(dev_fd); close(file_fd); }
static void run(unsigned int i) { const struct testcase *tc = &testcases[i]; TEST(sys_tgkill(*tc->tgid, *tc->tid, tc->sig)); if (tc->err) { if (TST_RET < 0 && TST_ERR == tc->err) tst_res(TPASS | TTERRNO, "%s failed as expected", tc->desc); else tst_res(TFAIL | TTERRNO, "%s should have failed with %s", tc->desc, tst_strerrno(tc->err)); } else { if (TST_RET == 0) tst_res(TPASS, "%s succeeded", tc->desc); else tst_res(TFAIL | TTERRNO, "%s failed", tc->desc); } }
static void verify_io_destroy(void) { io_context_t ctx; memset(&ctx, 0xff, sizeof(ctx)); TEST(io_destroy(ctx)); if (TST_RET == 0) { tst_res(TFAIL, "io_destroy() succeeded unexpectedly"); return; } if (TST_RET == -EINVAL) { tst_res(TPASS, "io_destroy() failed as expected, returned -EINVAL"); } else { tst_res(TFAIL, "io_destroy() failed unexpectedly, " "returned -%s expected -EINVAL", tst_strerrno(-TST_RET)); } }
static void verify_flistxattr(unsigned int n) { struct test_case *t = tc + n; char buf[t->size]; TEST(flistxattr(*t->fd, buf, t->size)); if (TEST_RETURN != -1) { tst_res(TFAIL, "flistxattr() succeeded unexpectedly (returned %ld)", TEST_RETURN); return; } if (t->exp_err != TEST_ERRNO) { tst_res(TFAIL | TTERRNO, "flistxattr() failed " "unexpectedlly, expected %s", tst_strerrno(t->exp_err)); } else { tst_res(TPASS | TTERRNO, "flistxattr() failed as expected"); } }
static void advice_test(unsigned int i) { struct tcase *tc = &tcases[i]; if (tc->skip == 1) { tst_res(TCONF, "%s is not supported", tc->name); return; } TEST(madvise(*(tc->addr), st.st_size, tc->advice)); if (TEST_RETURN == -1) { if (TEST_ERRNO == tc->exp_errno) { tst_res(TPASS | TTERRNO, "failed as expected"); } else { tst_res(TFAIL | TTERRNO, "failed unexpectedly; expected - %d : %s", tc->exp_errno, tst_strerrno(TFAIL | TTERRNO)); } } else { tst_res(TFAIL, "madvise succeeded unexpectedly"); } }
static void verify_getpriority(unsigned int n) { struct tcase *tc = &tcases[n]; TEST(getpriority(tc->which, tc->who)); if (TEST_RETURN != -1) { tst_res(TFAIL, "getpriority(%d, %d) succeeds unexpectedly, " "returned %li", tc->which, tc->who, TEST_RETURN); return; } if (tc->exp_errno != TEST_ERRNO) { tst_res(TFAIL | TTERRNO, "getpriority(%d, %d) should fail with %s", tc->which, tc->who, tst_strerrno(tc->exp_errno)); return; } tst_res(TPASS | TTERRNO, "getpriority(%d, %d) fails as expected", tc->which, tc->who); }
static void verify_creat(unsigned int i) { if (tcases[i].setup != NULL) tcases[i].setup(i); TEST(creat(tcases[i].fname, tcases[i].mode)); if (tcases[i].cleanup != NULL) tcases[i].cleanup(); if (TEST_RETURN != -1) { tst_res(TFAIL, "call succeeded unexpectedly"); return; } if (TEST_ERRNO == tcases[i].error) { tst_res(TPASS | TTERRNO, "got expected failure"); return; } tst_res(TFAIL | TTERRNO, "expected %s", tst_strerrno(tcases[i].error)); }
static void verify_openat(struct test_case *test) { TEST(openat(*test->dir_fd, test->pathname, O_RDWR, 0600)); if ((test->exp_ret == -1 && TEST_RETURN != -1) || (test->exp_ret == 0 && TEST_RETURN < 0)) { tst_resm(TFAIL | TTERRNO, "openat() returned %ldl, expected %d", TEST_RETURN, test->exp_ret); return; } if (TEST_RETURN > 0) SAFE_CLOSE(cleanup, TEST_RETURN); if (TEST_ERRNO != test->exp_errno) { tst_resm(TFAIL | TTERRNO, "openat() returned wrong errno, expected %s(%d)", tst_strerrno(test->exp_errno), test->exp_errno); return; } tst_resm(TPASS | TTERRNO, "openat() returned %ld", TEST_RETURN); }