clang-format
This commit is contained in:
@@ -37,25 +37,19 @@
|
||||
|
||||
#include "test.h"
|
||||
|
||||
static
|
||||
void
|
||||
chdir_empty(void)
|
||||
{
|
||||
int rv;
|
||||
static void chdir_empty(void) {
|
||||
int rv;
|
||||
|
||||
/*
|
||||
* This is actually valid by some interpretations.
|
||||
*/
|
||||
/*
|
||||
* This is actually valid by some interpretations.
|
||||
*/
|
||||
|
||||
report_begin("chdir to empty string");
|
||||
rv = chdir("");
|
||||
report_check2(rv, errno, EINVAL, 0);
|
||||
report_begin("chdir to empty string");
|
||||
rv = chdir("");
|
||||
report_check2(rv, errno, EINVAL, 0);
|
||||
}
|
||||
|
||||
void
|
||||
test_chdir(void)
|
||||
{
|
||||
test_chdir_path();
|
||||
chdir_empty();
|
||||
void test_chdir(void) {
|
||||
test_chdir_path();
|
||||
chdir_empty();
|
||||
}
|
||||
|
||||
|
||||
@@ -33,8 +33,4 @@
|
||||
|
||||
#include "test.h"
|
||||
|
||||
void
|
||||
test_close(void)
|
||||
{
|
||||
test_close_fd();
|
||||
}
|
||||
void test_close(void) { test_close_fd(); }
|
||||
|
||||
@@ -44,99 +44,86 @@
|
||||
#include "config.h"
|
||||
#include "test.h"
|
||||
|
||||
static
|
||||
void
|
||||
dup2_fd2(int fd, const char *desc)
|
||||
{
|
||||
int rv;
|
||||
static void dup2_fd2(int fd, const char *desc) {
|
||||
int rv;
|
||||
|
||||
report_begin("%s", desc);
|
||||
rv = dup2(STDIN_FILENO, fd);
|
||||
report_check(rv, errno, EBADF);
|
||||
report_begin("%s", desc);
|
||||
rv = dup2(STDIN_FILENO, fd);
|
||||
report_check(rv, errno, EBADF);
|
||||
|
||||
if (rv != -1) {
|
||||
close(fd); /* just in case */
|
||||
}
|
||||
if (rv != -1) {
|
||||
close(fd); /* just in case */
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
dup2_self(void)
|
||||
{
|
||||
struct stat sb;
|
||||
int rv;
|
||||
int testfd;
|
||||
static void dup2_self(void) {
|
||||
struct stat sb;
|
||||
int rv;
|
||||
int testfd;
|
||||
|
||||
/* use fd that isn't in use */
|
||||
testfd = CLOSED_FD;
|
||||
/* use fd that isn't in use */
|
||||
testfd = CLOSED_FD;
|
||||
|
||||
report_begin("copying stdin to test with");
|
||||
report_begin("copying stdin to test with");
|
||||
|
||||
rv = dup2(STDIN_FILENO, testfd);
|
||||
if (rv == -1) {
|
||||
report_result(rv, errno);
|
||||
report_aborted();
|
||||
return;
|
||||
}
|
||||
rv = dup2(STDIN_FILENO, testfd);
|
||||
if (rv == -1) {
|
||||
report_result(rv, errno);
|
||||
report_aborted();
|
||||
return;
|
||||
}
|
||||
|
||||
report_begin("dup2 to same fd");
|
||||
rv = dup2(testfd, testfd);
|
||||
if (rv == testfd) {
|
||||
report_passed();
|
||||
}
|
||||
else if (rv<0) {
|
||||
report_result(rv, errno);
|
||||
report_failure();
|
||||
}
|
||||
else {
|
||||
report_warnx("returned %d instead", rv);
|
||||
report_failure();
|
||||
}
|
||||
report_begin("dup2 to same fd");
|
||||
rv = dup2(testfd, testfd);
|
||||
if (rv == testfd) {
|
||||
report_passed();
|
||||
} else if (rv < 0) {
|
||||
report_result(rv, errno);
|
||||
report_failure();
|
||||
} else {
|
||||
report_warnx("returned %d instead", rv);
|
||||
report_failure();
|
||||
}
|
||||
|
||||
report_begin("fstat fd after dup2 to itself");
|
||||
rv = fstat(testfd, &sb);
|
||||
if (errno == ENOSYS) {
|
||||
report_saw_enosys();
|
||||
}
|
||||
report_result(rv, errno);
|
||||
if (rv==0) {
|
||||
report_passed();
|
||||
}
|
||||
else if (errno != ENOSYS) {
|
||||
report_failure();
|
||||
}
|
||||
else {
|
||||
report_skipped();
|
||||
/* no support for fstat; try lseek */
|
||||
report_begin("lseek fd after dup2 to itself");
|
||||
rv = lseek(testfd, 0, SEEK_CUR);
|
||||
report_result(rv, errno);
|
||||
if (rv==0 || (rv==-1 && errno==ESPIPE)) {
|
||||
report_passed();
|
||||
}
|
||||
else {
|
||||
report_failure();
|
||||
}
|
||||
}
|
||||
report_begin("fstat fd after dup2 to itself");
|
||||
rv = fstat(testfd, &sb);
|
||||
if (errno == ENOSYS) {
|
||||
report_saw_enosys();
|
||||
}
|
||||
report_result(rv, errno);
|
||||
if (rv == 0) {
|
||||
report_passed();
|
||||
} else if (errno != ENOSYS) {
|
||||
report_failure();
|
||||
} else {
|
||||
report_skipped();
|
||||
/* no support for fstat; try lseek */
|
||||
report_begin("lseek fd after dup2 to itself");
|
||||
rv = lseek(testfd, 0, SEEK_CUR);
|
||||
report_result(rv, errno);
|
||||
if (rv == 0 || (rv == -1 && errno == ESPIPE)) {
|
||||
report_passed();
|
||||
} else {
|
||||
report_failure();
|
||||
}
|
||||
}
|
||||
|
||||
close(testfd);
|
||||
close(testfd);
|
||||
}
|
||||
|
||||
void
|
||||
test_dup2(void)
|
||||
{
|
||||
/* This does the first fd. */
|
||||
test_dup2_fd();
|
||||
void test_dup2(void) {
|
||||
/* This does the first fd. */
|
||||
test_dup2_fd();
|
||||
|
||||
/* Any interesting cases added here should also go in common_fds.c */
|
||||
dup2_fd2(-1, "dup2 to -1");
|
||||
dup2_fd2(-5, "dup2 to -5");
|
||||
dup2_fd2(IMPOSSIBLE_FD, "dup2 to impossible fd");
|
||||
/* Any interesting cases added here should also go in common_fds.c */
|
||||
dup2_fd2(-1, "dup2 to -1");
|
||||
dup2_fd2(-5, "dup2 to -5");
|
||||
dup2_fd2(IMPOSSIBLE_FD, "dup2 to impossible fd");
|
||||
#ifdef OPEN_MAX
|
||||
dup2_fd2(OPEN_MAX, "dup2 to OPEN_MAX");
|
||||
dup2_fd2(OPEN_MAX, "dup2 to OPEN_MAX");
|
||||
#else
|
||||
warnx("Warning: OPEN_MAX not defined - test skipped");
|
||||
warnx("Warning: OPEN_MAX not defined - test skipped");
|
||||
#endif
|
||||
|
||||
dup2_self();
|
||||
dup2_self();
|
||||
}
|
||||
|
||||
@@ -40,142 +40,124 @@
|
||||
#include "config.h"
|
||||
#include "test.h"
|
||||
|
||||
static
|
||||
int
|
||||
exec_common_fork(void)
|
||||
{
|
||||
int pid, rv, status, err;
|
||||
static int exec_common_fork(void) {
|
||||
int pid, rv, status, err;
|
||||
|
||||
/*
|
||||
* This does not happen in a test context (from the point of
|
||||
* view of report.c) so we have to fiddle a bit.
|
||||
*/
|
||||
/*
|
||||
* This does not happen in a test context (from the point of
|
||||
* view of report.c) so we have to fiddle a bit.
|
||||
*/
|
||||
|
||||
pid = fork();
|
||||
if (pid<0) {
|
||||
err = errno;
|
||||
report_begin("forking for test");
|
||||
report_result(pid, err);
|
||||
report_aborted();
|
||||
return -1;
|
||||
}
|
||||
pid = fork();
|
||||
if (pid < 0) {
|
||||
err = errno;
|
||||
report_begin("forking for test");
|
||||
report_result(pid, err);
|
||||
report_aborted();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pid==0) {
|
||||
/* child */
|
||||
return 0;
|
||||
}
|
||||
if (pid == 0) {
|
||||
/* child */
|
||||
return 0;
|
||||
}
|
||||
|
||||
rv = waitpid(pid, &status, 0);
|
||||
if (rv == -1) {
|
||||
err = errno;
|
||||
report_begin("waiting for test subprocess");
|
||||
report_result(rv, err);
|
||||
report_failure();
|
||||
return -1;
|
||||
}
|
||||
if (WIFEXITED(status) && WEXITSTATUS(status) == MAGIC_STATUS) {
|
||||
return 1;
|
||||
}
|
||||
/* Oops... */
|
||||
report_begin("exit code of subprocess; should be %d", MAGIC_STATUS);
|
||||
if (WIFSIGNALED(status)) {
|
||||
report_warnx("signal %d", WTERMSIG(status));
|
||||
}
|
||||
else {
|
||||
report_warnx("exit %d", WEXITSTATUS(status));
|
||||
}
|
||||
report_failure();
|
||||
return -1;
|
||||
rv = waitpid(pid, &status, 0);
|
||||
if (rv == -1) {
|
||||
err = errno;
|
||||
report_begin("waiting for test subprocess");
|
||||
report_result(rv, err);
|
||||
report_failure();
|
||||
return -1;
|
||||
}
|
||||
if (WIFEXITED(status) && WEXITSTATUS(status) == MAGIC_STATUS) {
|
||||
return 1;
|
||||
}
|
||||
/* Oops... */
|
||||
report_begin("exit code of subprocess; should be %d", MAGIC_STATUS);
|
||||
if (WIFSIGNALED(status)) {
|
||||
report_warnx("signal %d", WTERMSIG(status));
|
||||
} else {
|
||||
report_warnx("exit %d", WEXITSTATUS(status));
|
||||
}
|
||||
report_failure();
|
||||
return -1;
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
exec_badprog(const void *prog, const char *desc)
|
||||
{
|
||||
int rv;
|
||||
char *args[2];
|
||||
args[0] = (char *)"foo";
|
||||
args[1] = NULL;
|
||||
static void exec_badprog(const void *prog, const char *desc) {
|
||||
int rv;
|
||||
char *args[2];
|
||||
args[0] = (char *)"foo";
|
||||
args[1] = NULL;
|
||||
|
||||
if (exec_common_fork() != 0) {
|
||||
return;
|
||||
}
|
||||
if (exec_common_fork() != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
report_begin(desc);
|
||||
rv = execv(prog, args);
|
||||
report_check(rv, errno, EFAULT);
|
||||
exit(MAGIC_STATUS);
|
||||
report_begin(desc);
|
||||
rv = execv(prog, args);
|
||||
report_check(rv, errno, EFAULT);
|
||||
exit(MAGIC_STATUS);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
exec_emptyprog(void)
|
||||
{
|
||||
int rv;
|
||||
char *args[2];
|
||||
args[0] = (char *)"foo";
|
||||
args[1] = NULL;
|
||||
static void exec_emptyprog(void) {
|
||||
int rv;
|
||||
char *args[2];
|
||||
args[0] = (char *)"foo";
|
||||
args[1] = NULL;
|
||||
|
||||
if (exec_common_fork() != 0) {
|
||||
return;
|
||||
}
|
||||
if (exec_common_fork() != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
report_begin("exec the empty string");
|
||||
rv = execv("", args);
|
||||
report_check2(rv, errno, EINVAL, EISDIR);
|
||||
exit(MAGIC_STATUS);
|
||||
report_begin("exec the empty string");
|
||||
rv = execv("", args);
|
||||
report_check2(rv, errno, EINVAL, EISDIR);
|
||||
exit(MAGIC_STATUS);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
exec_badargs(void *args, const char *desc)
|
||||
{
|
||||
int rv;
|
||||
static void exec_badargs(void *args, const char *desc) {
|
||||
int rv;
|
||||
|
||||
if (exec_common_fork() != 0) {
|
||||
return;
|
||||
}
|
||||
if (exec_common_fork() != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
report_begin(desc);
|
||||
rv = execv("/bin/true", args);
|
||||
report_check(rv, errno, EFAULT);
|
||||
exit(MAGIC_STATUS);
|
||||
report_begin(desc);
|
||||
rv = execv("/bin/true", args);
|
||||
report_check(rv, errno, EFAULT);
|
||||
exit(MAGIC_STATUS);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
exec_onearg(void *ptr, const char *desc)
|
||||
{
|
||||
int rv;
|
||||
static void exec_onearg(void *ptr, const char *desc) {
|
||||
int rv;
|
||||
|
||||
char *args[3];
|
||||
args[0] = (char *)"foo";
|
||||
args[1] = (char *)ptr;
|
||||
args[2] = NULL;
|
||||
char *args[3];
|
||||
args[0] = (char *)"foo";
|
||||
args[1] = (char *)ptr;
|
||||
args[2] = NULL;
|
||||
|
||||
if (exec_common_fork() != 0) {
|
||||
return;
|
||||
}
|
||||
if (exec_common_fork() != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
report_begin(desc);
|
||||
rv = execv("/bin/true", args);
|
||||
report_check(rv, errno, EFAULT);
|
||||
exit(MAGIC_STATUS);
|
||||
report_begin(desc);
|
||||
rv = execv("/bin/true", args);
|
||||
report_check(rv, errno, EFAULT);
|
||||
exit(MAGIC_STATUS);
|
||||
}
|
||||
|
||||
void
|
||||
test_execv(void)
|
||||
{
|
||||
exec_badprog(NULL, "exec with NULL program");
|
||||
exec_badprog(INVAL_PTR, "exec with invalid pointer program");
|
||||
exec_badprog(KERN_PTR, "exec with kernel pointer program");
|
||||
void test_execv(void) {
|
||||
exec_badprog(NULL, "exec with NULL program");
|
||||
exec_badprog(INVAL_PTR, "exec with invalid pointer program");
|
||||
exec_badprog(KERN_PTR, "exec with kernel pointer program");
|
||||
|
||||
exec_emptyprog();
|
||||
exec_emptyprog();
|
||||
|
||||
exec_badargs(NULL, "exec with NULL arglist");
|
||||
exec_badargs(INVAL_PTR, "exec with invalid pointer arglist");
|
||||
exec_badargs(KERN_PTR, "exec with kernel pointer arglist");
|
||||
exec_badargs(NULL, "exec with NULL arglist");
|
||||
exec_badargs(INVAL_PTR, "exec with invalid pointer arglist");
|
||||
exec_badargs(KERN_PTR, "exec with kernel pointer arglist");
|
||||
|
||||
exec_onearg(INVAL_PTR, "exec with invalid pointer arg");
|
||||
exec_onearg(KERN_PTR, "exec with kernel pointer arg");
|
||||
exec_onearg(INVAL_PTR, "exec with invalid pointer arg");
|
||||
exec_onearg(KERN_PTR, "exec with kernel pointer arg");
|
||||
}
|
||||
|
||||
@@ -33,9 +33,4 @@
|
||||
|
||||
#include "test.h"
|
||||
|
||||
void
|
||||
test_fsync(void)
|
||||
{
|
||||
test_fsync_fd();
|
||||
}
|
||||
|
||||
void test_fsync(void) { test_fsync_fd(); }
|
||||
|
||||
@@ -43,53 +43,45 @@
|
||||
#include "config.h"
|
||||
#include "test.h"
|
||||
|
||||
static
|
||||
void
|
||||
ftruncate_fd_device(void)
|
||||
{
|
||||
int rv, fd;
|
||||
static void ftruncate_fd_device(void) {
|
||||
int rv, fd;
|
||||
|
||||
report_begin("ftruncate on device");
|
||||
report_begin("ftruncate on device");
|
||||
|
||||
fd = open("null:", O_RDWR);
|
||||
if (fd<0) {
|
||||
report_warn("opening null: failed");
|
||||
report_aborted();
|
||||
return;
|
||||
}
|
||||
fd = open("null:", O_RDWR);
|
||||
if (fd < 0) {
|
||||
report_warn("opening null: failed");
|
||||
report_aborted();
|
||||
return;
|
||||
}
|
||||
|
||||
rv = ftruncate(fd, 6);
|
||||
report_check(rv, errno, EINVAL);
|
||||
rv = ftruncate(fd, 6);
|
||||
report_check(rv, errno, EINVAL);
|
||||
|
||||
close(fd);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
ftruncate_size_neg(void)
|
||||
{
|
||||
int rv, fd;
|
||||
static void ftruncate_size_neg(void) {
|
||||
int rv, fd;
|
||||
|
||||
report_begin("ftruncate to negative size");
|
||||
report_begin("ftruncate to negative size");
|
||||
|
||||
fd = open_testfile(NULL);
|
||||
if (fd<0) {
|
||||
report_aborted();
|
||||
return;
|
||||
}
|
||||
fd = open_testfile(NULL);
|
||||
if (fd < 0) {
|
||||
report_aborted();
|
||||
return;
|
||||
}
|
||||
|
||||
rv = ftruncate(fd, -60);
|
||||
report_check(rv, errno, EINVAL);
|
||||
rv = ftruncate(fd, -60);
|
||||
report_check(rv, errno, EINVAL);
|
||||
|
||||
close(fd);
|
||||
remove(TESTFILE);
|
||||
close(fd);
|
||||
remove(TESTFILE);
|
||||
}
|
||||
|
||||
void
|
||||
test_ftruncate(void)
|
||||
{
|
||||
test_ftruncate_fd();
|
||||
void test_ftruncate(void) {
|
||||
test_ftruncate_fd();
|
||||
|
||||
ftruncate_fd_device();
|
||||
ftruncate_size_neg();
|
||||
ftruncate_fd_device();
|
||||
ftruncate_size_neg();
|
||||
}
|
||||
|
||||
@@ -33,8 +33,4 @@
|
||||
|
||||
#include "test.h"
|
||||
|
||||
void
|
||||
test_getcwd(void)
|
||||
{
|
||||
test_getcwd_buf();
|
||||
}
|
||||
void test_getcwd(void) { test_getcwd_buf(); }
|
||||
|
||||
@@ -33,9 +33,7 @@
|
||||
|
||||
#include "test.h"
|
||||
|
||||
void
|
||||
test_getdirentry(void)
|
||||
{
|
||||
test_getdirentry_fd();
|
||||
test_getdirentry_buf();
|
||||
void test_getdirentry(void) {
|
||||
test_getdirentry_fd();
|
||||
test_getdirentry_buf();
|
||||
}
|
||||
|
||||
@@ -40,64 +40,49 @@
|
||||
#include "config.h"
|
||||
#include "test.h"
|
||||
|
||||
static
|
||||
void
|
||||
one_ioctl_badbuf(int fd, int code, const char *codename,
|
||||
void *ptr, const char *ptrdesc)
|
||||
{
|
||||
int rv;
|
||||
static void one_ioctl_badbuf(int fd, int code, const char *codename, void *ptr,
|
||||
const char *ptrdesc) {
|
||||
int rv;
|
||||
|
||||
report_begin("ioctl %s with %s", codename, ptrdesc);
|
||||
rv = ioctl(fd, code, ptr);
|
||||
report_check(rv, errno, EFAULT);
|
||||
report_begin("ioctl %s with %s", codename, ptrdesc);
|
||||
rv = ioctl(fd, code, ptr);
|
||||
report_check(rv, errno, EFAULT);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
any_ioctl_badbuf(int fd, int code, const char *codename)
|
||||
{
|
||||
one_ioctl_badbuf(fd, code, codename, NULL, "NULL pointer");
|
||||
one_ioctl_badbuf(fd, code, codename, INVAL_PTR, "invalid pointer");
|
||||
one_ioctl_badbuf(fd, code, codename, KERN_PTR, "kernel pointer");
|
||||
static void any_ioctl_badbuf(int fd, int code, const char *codename) {
|
||||
one_ioctl_badbuf(fd, code, codename, NULL, "NULL pointer");
|
||||
one_ioctl_badbuf(fd, code, codename, INVAL_PTR, "invalid pointer");
|
||||
one_ioctl_badbuf(fd, code, codename, KERN_PTR, "kernel pointer");
|
||||
}
|
||||
|
||||
#define IOCTL(fd, sym) any_ioctl_badbuf(fd, sym, #sym)
|
||||
|
||||
static
|
||||
void
|
||||
ioctl_badbuf(void)
|
||||
{
|
||||
/*
|
||||
* Since we don't actually define any ioctls, this code won't
|
||||
* actually run. But if you do define ioctls, turn these tests
|
||||
* on for those that actually use the data buffer argument for
|
||||
* anything.
|
||||
*/
|
||||
static void ioctl_badbuf(void) {
|
||||
/*
|
||||
* Since we don't actually define any ioctls, this code won't
|
||||
* actually run. But if you do define ioctls, turn these tests
|
||||
* on for those that actually use the data buffer argument for
|
||||
* anything.
|
||||
*/
|
||||
|
||||
/* IOCTL(STDIN_FILENO, TIOCGETA); */
|
||||
/* IOCTL(STDIN_FILENO, TIOCGETA); */
|
||||
|
||||
|
||||
/* suppress gcc warning */
|
||||
(void)any_ioctl_badbuf;
|
||||
/* suppress gcc warning */
|
||||
(void)any_ioctl_badbuf;
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
ioctl_badcode(void)
|
||||
{
|
||||
int rv;
|
||||
static void ioctl_badcode(void) {
|
||||
int rv;
|
||||
|
||||
report_begin("invalid ioctl");
|
||||
rv = ioctl(STDIN_FILENO, NONEXIST_IOCTL, NULL);
|
||||
report_check(rv, errno, EIOCTL);
|
||||
report_begin("invalid ioctl");
|
||||
rv = ioctl(STDIN_FILENO, NONEXIST_IOCTL, NULL);
|
||||
report_check(rv, errno, EIOCTL);
|
||||
}
|
||||
|
||||
void
|
||||
test_ioctl(void)
|
||||
{
|
||||
test_ioctl_fd();
|
||||
void test_ioctl(void) {
|
||||
test_ioctl_fd();
|
||||
|
||||
/* Since we don't actually define any ioctls, this is not meaningful */
|
||||
ioctl_badcode();
|
||||
ioctl_badbuf();
|
||||
/* Since we don't actually define any ioctls, this is not meaningful */
|
||||
ioctl_badcode();
|
||||
ioctl_badbuf();
|
||||
}
|
||||
|
||||
@@ -36,53 +36,42 @@
|
||||
|
||||
#include "test.h"
|
||||
|
||||
static
|
||||
void
|
||||
link_dir(void)
|
||||
{
|
||||
int rv;
|
||||
static void link_dir(void) {
|
||||
int rv;
|
||||
|
||||
report_begin("hard link of .");
|
||||
rv = link(".", TESTDIR);
|
||||
report_check(rv, errno, EINVAL);
|
||||
if (rv==0) {
|
||||
/* this might help recover... maybe */
|
||||
remove(TESTDIR);
|
||||
}
|
||||
report_begin("hard link of .");
|
||||
rv = link(".", TESTDIR);
|
||||
report_check(rv, errno, EINVAL);
|
||||
if (rv == 0) {
|
||||
/* this might help recover... maybe */
|
||||
remove(TESTDIR);
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
link_empty1(void)
|
||||
{
|
||||
int rv;
|
||||
static void link_empty1(void) {
|
||||
int rv;
|
||||
|
||||
report_begin("hard link of empty string");
|
||||
rv = link("", TESTDIR);
|
||||
report_check(rv, errno, EINVAL);
|
||||
report_begin("hard link of empty string");
|
||||
rv = link("", TESTDIR);
|
||||
report_check(rv, errno, EINVAL);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
link_empty2(void)
|
||||
{
|
||||
int rv;
|
||||
static void link_empty2(void) {
|
||||
int rv;
|
||||
|
||||
report_begin("hard link to empty string");
|
||||
if (create_testdir()<0) {
|
||||
/*report_aborted();*/ /* XXX in create_testdir */
|
||||
return;
|
||||
}
|
||||
rv = link(TESTDIR, "");
|
||||
report_check(rv, errno, EINVAL);
|
||||
rmdir(TESTDIR);
|
||||
report_begin("hard link to empty string");
|
||||
if (create_testdir() < 0) {
|
||||
/*report_aborted();*/ /* XXX in create_testdir */
|
||||
return;
|
||||
}
|
||||
rv = link(TESTDIR, "");
|
||||
report_check(rv, errno, EINVAL);
|
||||
rmdir(TESTDIR);
|
||||
}
|
||||
|
||||
void
|
||||
test_link(void)
|
||||
{
|
||||
test_link_paths();
|
||||
link_dir();
|
||||
link_empty1();
|
||||
link_empty2();
|
||||
void test_link(void) {
|
||||
test_link_paths();
|
||||
link_dir();
|
||||
link_empty1();
|
||||
link_empty2();
|
||||
}
|
||||
|
||||
@@ -43,236 +43,213 @@
|
||||
#include "config.h"
|
||||
#include "test.h"
|
||||
|
||||
static
|
||||
void
|
||||
lseek_fd_device(void)
|
||||
{
|
||||
int fd, rv;
|
||||
static void lseek_fd_device(void) {
|
||||
int fd, rv;
|
||||
|
||||
report_begin("lseek on device");
|
||||
report_begin("lseek on device");
|
||||
|
||||
fd = open("null:", O_RDONLY);
|
||||
if (fd<0) {
|
||||
report_warn("opening null: failed");
|
||||
report_aborted();
|
||||
return;
|
||||
}
|
||||
fd = open("null:", O_RDONLY);
|
||||
if (fd < 0) {
|
||||
report_warn("opening null: failed");
|
||||
report_aborted();
|
||||
return;
|
||||
}
|
||||
|
||||
rv = lseek(fd, 309, SEEK_SET);
|
||||
report_check(rv, errno, ESPIPE);
|
||||
rv = lseek(fd, 309, SEEK_SET);
|
||||
report_check(rv, errno, ESPIPE);
|
||||
|
||||
close(fd);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
lseek_file_stdin(void)
|
||||
{
|
||||
int fd, fd2, rv, status;
|
||||
const char slogan[] = "There ain't no such thing as a free lunch";
|
||||
size_t len = strlen(slogan);
|
||||
pid_t pid;
|
||||
static void lseek_file_stdin(void) {
|
||||
int fd, fd2, rv, status;
|
||||
const char slogan[] = "There ain't no such thing as a free lunch";
|
||||
size_t len = strlen(slogan);
|
||||
pid_t pid;
|
||||
|
||||
report_begin("lseek stdin when open on file");
|
||||
report_begin("lseek stdin when open on file");
|
||||
|
||||
/* fork so we don't affect our own stdin */
|
||||
pid = fork();
|
||||
if (pid<0) {
|
||||
report_warn("fork failed");
|
||||
report_aborted();
|
||||
return;
|
||||
}
|
||||
else if (pid!=0) {
|
||||
/* parent */
|
||||
rv = waitpid(pid, &status, 0);
|
||||
if (rv<0) {
|
||||
report_warn("waitpid failed");
|
||||
report_aborted();
|
||||
}
|
||||
if (WIFSIGNALED(status)) {
|
||||
report_warnx("subprocess exited with signal %d",
|
||||
WTERMSIG(status));
|
||||
report_aborted();
|
||||
}
|
||||
else if (WIFEXITED(status) && WEXITSTATUS(status) != 0) {
|
||||
report_warnx("subprocess exited with code %d",
|
||||
WEXITSTATUS(status));
|
||||
report_aborted();
|
||||
}
|
||||
return;
|
||||
}
|
||||
/* fork so we don't affect our own stdin */
|
||||
pid = fork();
|
||||
if (pid < 0) {
|
||||
report_warn("fork failed");
|
||||
report_aborted();
|
||||
return;
|
||||
} else if (pid != 0) {
|
||||
/* parent */
|
||||
rv = waitpid(pid, &status, 0);
|
||||
if (rv < 0) {
|
||||
report_warn("waitpid failed");
|
||||
report_aborted();
|
||||
}
|
||||
if (WIFSIGNALED(status)) {
|
||||
report_warnx("subprocess exited with signal %d", WTERMSIG(status));
|
||||
report_aborted();
|
||||
} else if (WIFEXITED(status) && WEXITSTATUS(status) != 0) {
|
||||
report_warnx("subprocess exited with code %d", WEXITSTATUS(status));
|
||||
report_aborted();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* child */
|
||||
/* child */
|
||||
|
||||
fd = open_testfile(NULL);
|
||||
if (fd<0) {
|
||||
_exit(0);
|
||||
}
|
||||
fd = open_testfile(NULL);
|
||||
if (fd < 0) {
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Move file to stdin.
|
||||
* Use stdin (rather than stdout or stderr) to maximize the
|
||||
* chances of detecting any special-case handling of fds 0-2.
|
||||
* (Writing to stdin is fine as long as it's open for write,
|
||||
* and it will be.)
|
||||
*/
|
||||
fd2 = dup2(fd, STDIN_FILENO);
|
||||
if (fd2<0) {
|
||||
report_warn("dup2 to stdin failed");
|
||||
close(fd);
|
||||
remove(TESTFILE);
|
||||
_exit(1);
|
||||
}
|
||||
if (fd2 != STDIN_FILENO) {
|
||||
report_warn("dup2 returned wrong file handle");
|
||||
close(fd);
|
||||
remove(TESTFILE);
|
||||
_exit(1);
|
||||
}
|
||||
close(fd);
|
||||
/*
|
||||
* Move file to stdin.
|
||||
* Use stdin (rather than stdout or stderr) to maximize the
|
||||
* chances of detecting any special-case handling of fds 0-2.
|
||||
* (Writing to stdin is fine as long as it's open for write,
|
||||
* and it will be.)
|
||||
*/
|
||||
fd2 = dup2(fd, STDIN_FILENO);
|
||||
if (fd2 < 0) {
|
||||
report_warn("dup2 to stdin failed");
|
||||
close(fd);
|
||||
remove(TESTFILE);
|
||||
_exit(1);
|
||||
}
|
||||
if (fd2 != STDIN_FILENO) {
|
||||
report_warn("dup2 returned wrong file handle");
|
||||
close(fd);
|
||||
remove(TESTFILE);
|
||||
_exit(1);
|
||||
}
|
||||
close(fd);
|
||||
|
||||
rv = write(STDIN_FILENO, slogan, len);
|
||||
if (rv<0) {
|
||||
report_warn("write to %s (via stdin) failed", TESTFILE);
|
||||
remove(TESTFILE);
|
||||
_exit(1);
|
||||
}
|
||||
rv = write(STDIN_FILENO, slogan, len);
|
||||
if (rv < 0) {
|
||||
report_warn("write to %s (via stdin) failed", TESTFILE);
|
||||
remove(TESTFILE);
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
if ((unsigned)rv != len) {
|
||||
report_warnx("write to %s (via stdin) got short count",
|
||||
TESTFILE);
|
||||
remove(TESTFILE);
|
||||
_exit(1);
|
||||
}
|
||||
if ((unsigned)rv != len) {
|
||||
report_warnx("write to %s (via stdin) got short count", TESTFILE);
|
||||
remove(TESTFILE);
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
/* blah */
|
||||
report_skipped();
|
||||
/* blah */
|
||||
report_skipped();
|
||||
|
||||
rv = lseek(STDIN_FILENO, 0, SEEK_SET);
|
||||
report_begin("try 1: SEEK_SET");
|
||||
report_check(rv, errno, 0);
|
||||
rv = lseek(STDIN_FILENO, 0, SEEK_SET);
|
||||
report_begin("try 1: SEEK_SET");
|
||||
report_check(rv, errno, 0);
|
||||
|
||||
rv = lseek(STDIN_FILENO, 0, SEEK_END);
|
||||
report_begin("try 2: SEEK_END");
|
||||
report_check(rv, errno, 0);
|
||||
rv = lseek(STDIN_FILENO, 0, SEEK_END);
|
||||
report_begin("try 2: SEEK_END");
|
||||
report_check(rv, errno, 0);
|
||||
|
||||
remove(TESTFILE);
|
||||
_exit(0);
|
||||
remove(TESTFILE);
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
lseek_loc_negative(void)
|
||||
{
|
||||
int fd, rv;
|
||||
static void lseek_loc_negative(void) {
|
||||
int fd, rv;
|
||||
|
||||
report_begin("lseek to negative offset");
|
||||
report_begin("lseek to negative offset");
|
||||
|
||||
fd = open_testfile(NULL);
|
||||
if (fd<0) {
|
||||
report_aborted();
|
||||
return;
|
||||
}
|
||||
fd = open_testfile(NULL);
|
||||
if (fd < 0) {
|
||||
report_aborted();
|
||||
return;
|
||||
}
|
||||
|
||||
rv = lseek(fd, -309, SEEK_SET);
|
||||
report_check(rv, errno, EINVAL);
|
||||
rv = lseek(fd, -309, SEEK_SET);
|
||||
report_check(rv, errno, EINVAL);
|
||||
|
||||
close(fd);
|
||||
remove(TESTFILE);
|
||||
close(fd);
|
||||
remove(TESTFILE);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
lseek_whence_inval(void)
|
||||
{
|
||||
int fd, rv;
|
||||
static void lseek_whence_inval(void) {
|
||||
int fd, rv;
|
||||
|
||||
report_begin("lseek with invalid whence code");
|
||||
report_begin("lseek with invalid whence code");
|
||||
|
||||
fd = open_testfile(NULL);
|
||||
if (fd<0) {
|
||||
report_aborted();
|
||||
return;
|
||||
}
|
||||
fd = open_testfile(NULL);
|
||||
if (fd < 0) {
|
||||
report_aborted();
|
||||
return;
|
||||
}
|
||||
|
||||
rv = lseek(fd, 0, 3594);
|
||||
report_check(rv, errno, EINVAL);
|
||||
rv = lseek(fd, 0, 3594);
|
||||
report_check(rv, errno, EINVAL);
|
||||
|
||||
close(fd);
|
||||
remove(TESTFILE);
|
||||
close(fd);
|
||||
remove(TESTFILE);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
lseek_loc_pasteof(void)
|
||||
{
|
||||
const char *message = "blahblah";
|
||||
int fd;
|
||||
off_t pos;
|
||||
static void lseek_loc_pasteof(void) {
|
||||
const char *message = "blahblah";
|
||||
int fd;
|
||||
off_t pos;
|
||||
|
||||
report_begin("seek past/to EOF");
|
||||
report_begin("seek past/to EOF");
|
||||
|
||||
fd = open_testfile(message);
|
||||
if (fd<0) {
|
||||
report_aborted();
|
||||
return;
|
||||
}
|
||||
fd = open_testfile(message);
|
||||
if (fd < 0) {
|
||||
report_aborted();
|
||||
return;
|
||||
}
|
||||
|
||||
pos = lseek(fd, 5340, SEEK_SET);
|
||||
if (pos == -1) {
|
||||
report_warn("lseek past EOF failed");
|
||||
report_failure();
|
||||
goto out;
|
||||
}
|
||||
if (pos != 5340) {
|
||||
report_warnx("lseek to 5340 got offset %lld", (long long) pos);
|
||||
report_failure();
|
||||
goto out;
|
||||
}
|
||||
pos = lseek(fd, 5340, SEEK_SET);
|
||||
if (pos == -1) {
|
||||
report_warn("lseek past EOF failed");
|
||||
report_failure();
|
||||
goto out;
|
||||
}
|
||||
if (pos != 5340) {
|
||||
report_warnx("lseek to 5340 got offset %lld", (long long)pos);
|
||||
report_failure();
|
||||
goto out;
|
||||
}
|
||||
|
||||
pos = lseek(fd, -50, SEEK_CUR);
|
||||
if (pos == -1) {
|
||||
report_warn("small seek beyond EOF failed");
|
||||
report_failure();
|
||||
goto out;
|
||||
}
|
||||
if (pos != 5290) {
|
||||
report_warnx("SEEK_CUR to 5290 got offset %lld",
|
||||
(long long) pos);
|
||||
report_failure();
|
||||
goto out;
|
||||
}
|
||||
pos = lseek(fd, -50, SEEK_CUR);
|
||||
if (pos == -1) {
|
||||
report_warn("small seek beyond EOF failed");
|
||||
report_failure();
|
||||
goto out;
|
||||
}
|
||||
if (pos != 5290) {
|
||||
report_warnx("SEEK_CUR to 5290 got offset %lld", (long long)pos);
|
||||
report_failure();
|
||||
goto out;
|
||||
}
|
||||
|
||||
pos = lseek(fd, 0, SEEK_END);
|
||||
if (pos == -1) {
|
||||
report_warn("seek to EOF failed");
|
||||
report_failure();
|
||||
goto out;
|
||||
}
|
||||
pos = lseek(fd, 0, SEEK_END);
|
||||
if (pos == -1) {
|
||||
report_warn("seek to EOF failed");
|
||||
report_failure();
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (pos != (off_t) strlen(message)) {
|
||||
report_warnx("seek to EOF got %lld (should be %zu)",
|
||||
(long long) pos, strlen(message));
|
||||
report_failure();
|
||||
goto out;
|
||||
}
|
||||
if (pos != (off_t)strlen(message)) {
|
||||
report_warnx("seek to EOF got %lld (should be %zu)", (long long)pos,
|
||||
strlen(message));
|
||||
report_failure();
|
||||
goto out;
|
||||
}
|
||||
|
||||
report_passed();
|
||||
report_passed();
|
||||
|
||||
out:
|
||||
close(fd);
|
||||
remove(TESTFILE);
|
||||
return;
|
||||
out:
|
||||
close(fd);
|
||||
remove(TESTFILE);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
test_lseek(void)
|
||||
{
|
||||
test_lseek_fd();
|
||||
void test_lseek(void) {
|
||||
test_lseek_fd();
|
||||
|
||||
lseek_fd_device();
|
||||
lseek_file_stdin();
|
||||
lseek_loc_negative();
|
||||
lseek_loc_pasteof();
|
||||
lseek_whence_inval();
|
||||
lseek_fd_device();
|
||||
lseek_file_stdin();
|
||||
lseek_loc_negative();
|
||||
lseek_loc_pasteof();
|
||||
lseek_whence_inval();
|
||||
}
|
||||
|
||||
@@ -43,45 +43,34 @@
|
||||
#include "config.h"
|
||||
#include "test.h"
|
||||
|
||||
static
|
||||
void
|
||||
mkdir_dot(void)
|
||||
{
|
||||
int rv;
|
||||
static void mkdir_dot(void) {
|
||||
int rv;
|
||||
|
||||
report_begin("mkdir .");
|
||||
rv = mkdir(".", 0775);
|
||||
report_check(rv, errno, EEXIST);
|
||||
report_begin("mkdir .");
|
||||
rv = mkdir(".", 0775);
|
||||
report_check(rv, errno, EEXIST);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
mkdir_dotdot(void)
|
||||
{
|
||||
int rv;
|
||||
static void mkdir_dotdot(void) {
|
||||
int rv;
|
||||
|
||||
report_begin("mkdir ..");
|
||||
rv = mkdir("..", 0775);
|
||||
report_check(rv, errno, EEXIST);
|
||||
report_begin("mkdir ..");
|
||||
rv = mkdir("..", 0775);
|
||||
report_check(rv, errno, EEXIST);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
mkdir_empty(void)
|
||||
{
|
||||
int rv;
|
||||
static void mkdir_empty(void) {
|
||||
int rv;
|
||||
|
||||
report_begin("mkdir of empty string");
|
||||
rv = mkdir("", 0775);
|
||||
report_check(rv, errno, EINVAL);
|
||||
report_begin("mkdir of empty string");
|
||||
rv = mkdir("", 0775);
|
||||
report_check(rv, errno, EINVAL);
|
||||
}
|
||||
|
||||
void
|
||||
test_mkdir(void)
|
||||
{
|
||||
test_mkdir_path();
|
||||
void test_mkdir(void) {
|
||||
test_mkdir_path();
|
||||
|
||||
mkdir_dot();
|
||||
mkdir_dotdot();
|
||||
mkdir_empty();
|
||||
mkdir_dot();
|
||||
mkdir_dotdot();
|
||||
mkdir_empty();
|
||||
}
|
||||
|
||||
@@ -43,36 +43,28 @@
|
||||
#include "config.h"
|
||||
#include "test.h"
|
||||
|
||||
static
|
||||
void
|
||||
open_badflags(void)
|
||||
{
|
||||
int fd;
|
||||
static void open_badflags(void) {
|
||||
int fd;
|
||||
|
||||
report_begin("open null: with bad flags");
|
||||
fd = open("null:", 309842);
|
||||
report_check(fd, errno, EINVAL);
|
||||
report_begin("open null: with bad flags");
|
||||
fd = open("null:", 309842);
|
||||
report_check(fd, errno, EINVAL);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
open_empty(void)
|
||||
{
|
||||
int rv;
|
||||
static void open_empty(void) {
|
||||
int rv;
|
||||
|
||||
report_begin("open empty string");
|
||||
rv = open("", O_RDONLY);
|
||||
report_check(rv, errno, EINVAL);
|
||||
if (rv>=0) {
|
||||
close(rv);
|
||||
}
|
||||
report_begin("open empty string");
|
||||
rv = open("", O_RDONLY);
|
||||
report_check(rv, errno, EINVAL);
|
||||
if (rv >= 0) {
|
||||
close(rv);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
test_open(void)
|
||||
{
|
||||
test_open_path();
|
||||
void test_open(void) {
|
||||
test_open_path();
|
||||
|
||||
open_badflags();
|
||||
open_empty();
|
||||
open_badflags();
|
||||
open_empty();
|
||||
}
|
||||
|
||||
@@ -43,44 +43,36 @@
|
||||
#include "config.h"
|
||||
#include "test.h"
|
||||
|
||||
static
|
||||
void
|
||||
pipe_badptr(void *ptr, const char *desc)
|
||||
{
|
||||
int rv;
|
||||
static void pipe_badptr(void *ptr, const char *desc) {
|
||||
int rv;
|
||||
|
||||
report_begin("%s", desc);
|
||||
rv = pipe(ptr);
|
||||
report_check(rv, errno, EFAULT);
|
||||
report_begin("%s", desc);
|
||||
rv = pipe(ptr);
|
||||
report_check(rv, errno, EFAULT);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
pipe_unaligned(void)
|
||||
{
|
||||
int fds[3], rv;
|
||||
char *ptr;
|
||||
static void pipe_unaligned(void) {
|
||||
int fds[3], rv;
|
||||
char *ptr;
|
||||
|
||||
report_begin("pipe with unaligned pointer");
|
||||
report_begin("pipe with unaligned pointer");
|
||||
|
||||
ptr = (char *)&fds[0];
|
||||
ptr++;
|
||||
ptr = (char *)&fds[0];
|
||||
ptr++;
|
||||
|
||||
rv = pipe((int *)ptr);
|
||||
report_survival(rv, errno);
|
||||
if (rv == 0) {
|
||||
memmove(fds, ptr, 2*sizeof(int));
|
||||
close(fds[0]);
|
||||
close(fds[1]);
|
||||
}
|
||||
rv = pipe((int *)ptr);
|
||||
report_survival(rv, errno);
|
||||
if (rv == 0) {
|
||||
memmove(fds, ptr, 2 * sizeof(int));
|
||||
close(fds[0]);
|
||||
close(fds[1]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
test_pipe(void)
|
||||
{
|
||||
pipe_badptr(NULL, "pipe with NULL pointer");
|
||||
pipe_badptr(INVAL_PTR, "pipe with invalid pointer");
|
||||
pipe_badptr(KERN_PTR, "pipe with kernel pointer");
|
||||
void test_pipe(void) {
|
||||
pipe_badptr(NULL, "pipe with NULL pointer");
|
||||
pipe_badptr(INVAL_PTR, "pipe with invalid pointer");
|
||||
pipe_badptr(KERN_PTR, "pipe with kernel pointer");
|
||||
|
||||
pipe_unaligned();
|
||||
pipe_unaligned();
|
||||
}
|
||||
|
||||
@@ -33,10 +33,7 @@
|
||||
|
||||
#include "test.h"
|
||||
|
||||
void
|
||||
test_read(void)
|
||||
{
|
||||
test_read_fd();
|
||||
test_read_buf();
|
||||
void test_read(void) {
|
||||
test_read_fd();
|
||||
test_read_buf();
|
||||
}
|
||||
|
||||
|
||||
@@ -36,57 +36,45 @@
|
||||
|
||||
#include "test.h"
|
||||
|
||||
static
|
||||
void
|
||||
readlink_file(void)
|
||||
{
|
||||
char buf[128];
|
||||
int fd, rv;
|
||||
static void readlink_file(void) {
|
||||
char buf[128];
|
||||
int fd, rv;
|
||||
|
||||
report_begin("readlink on file");
|
||||
fd = open_testfile("the question contains an invalid assumption");
|
||||
if (fd<0) {
|
||||
report_aborted();
|
||||
return;
|
||||
}
|
||||
close(fd);
|
||||
rv = readlink(TESTFILE, buf, sizeof(buf));
|
||||
report_check(rv, errno, EINVAL);
|
||||
remove(TESTFILE);
|
||||
report_begin("readlink on file");
|
||||
fd = open_testfile("the question contains an invalid assumption");
|
||||
if (fd < 0) {
|
||||
report_aborted();
|
||||
return;
|
||||
}
|
||||
close(fd);
|
||||
rv = readlink(TESTFILE, buf, sizeof(buf));
|
||||
report_check(rv, errno, EINVAL);
|
||||
remove(TESTFILE);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
readlink_dir(void)
|
||||
{
|
||||
char buf[128];
|
||||
int rv;
|
||||
static void readlink_dir(void) {
|
||||
char buf[128];
|
||||
int rv;
|
||||
|
||||
report_begin("readlink on .");
|
||||
rv = readlink(".", buf, sizeof(buf));
|
||||
report_check(rv, errno, EISDIR);
|
||||
report_begin("readlink on .");
|
||||
rv = readlink(".", buf, sizeof(buf));
|
||||
report_check(rv, errno, EISDIR);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
readlink_empty(void)
|
||||
{
|
||||
char buf[128];
|
||||
int rv;
|
||||
static void readlink_empty(void) {
|
||||
char buf[128];
|
||||
int rv;
|
||||
|
||||
report_begin("readlink on empty string");
|
||||
rv = readlink("", buf, sizeof(buf));
|
||||
report_check2(rv, errno, EISDIR, EINVAL);
|
||||
report_begin("readlink on empty string");
|
||||
rv = readlink("", buf, sizeof(buf));
|
||||
report_check2(rv, errno, EISDIR, EINVAL);
|
||||
}
|
||||
|
||||
void
|
||||
test_readlink(void)
|
||||
{
|
||||
test_readlink_path();
|
||||
test_readlink_buf();
|
||||
void test_readlink(void) {
|
||||
test_readlink_path();
|
||||
test_readlink_buf();
|
||||
|
||||
readlink_file();
|
||||
readlink_dir();
|
||||
readlink_empty();
|
||||
readlink_file();
|
||||
readlink_dir();
|
||||
readlink_empty();
|
||||
}
|
||||
|
||||
|
||||
@@ -43,20 +43,13 @@
|
||||
#include "config.h"
|
||||
#include "test.h"
|
||||
|
||||
static
|
||||
void
|
||||
reboot_badflags(void)
|
||||
{
|
||||
int rv;
|
||||
static void reboot_badflags(void) {
|
||||
int rv;
|
||||
|
||||
printf("(This should not kill the system...)\n");
|
||||
report_begin("reboot with invalid flags");
|
||||
rv = reboot(15353);
|
||||
report_check(rv, errno, EINVAL);
|
||||
printf("(This should not kill the system...)\n");
|
||||
report_begin("reboot with invalid flags");
|
||||
rv = reboot(15353);
|
||||
report_check(rv, errno, EINVAL);
|
||||
}
|
||||
|
||||
void
|
||||
test_reboot(void)
|
||||
{
|
||||
reboot_badflags();
|
||||
}
|
||||
void test_reboot(void) { reboot_badflags(); }
|
||||
|
||||
@@ -43,64 +43,50 @@
|
||||
#include "config.h"
|
||||
#include "test.h"
|
||||
|
||||
static
|
||||
void
|
||||
remove_dir(void)
|
||||
{
|
||||
int rv;
|
||||
static void remove_dir(void) {
|
||||
int rv;
|
||||
|
||||
report_begin("remove() on a directory");
|
||||
report_begin("remove() on a directory");
|
||||
|
||||
if (create_testdir() < 0) {
|
||||
/*report_aborted();*/ /* XXX in create_testdir */
|
||||
return;
|
||||
}
|
||||
if (create_testdir() < 0) {
|
||||
/*report_aborted();*/ /* XXX in create_testdir */
|
||||
return;
|
||||
}
|
||||
|
||||
rv = remove(TESTDIR);
|
||||
report_check(rv, errno, EISDIR);
|
||||
rmdir(TESTDIR);
|
||||
rv = remove(TESTDIR);
|
||||
report_check(rv, errno, EISDIR);
|
||||
rmdir(TESTDIR);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
remove_dot(void)
|
||||
{
|
||||
int rv;
|
||||
static void remove_dot(void) {
|
||||
int rv;
|
||||
|
||||
report_begin("remove() on .");
|
||||
rv = remove(".");
|
||||
report_check2(rv, errno, EISDIR, EINVAL);
|
||||
report_begin("remove() on .");
|
||||
rv = remove(".");
|
||||
report_check2(rv, errno, EISDIR, EINVAL);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
remove_dotdot(void)
|
||||
{
|
||||
int rv;
|
||||
static void remove_dotdot(void) {
|
||||
int rv;
|
||||
|
||||
report_begin("remove() on ..");
|
||||
rv = remove("..");
|
||||
report_check2(rv, errno, EISDIR, EINVAL);
|
||||
report_begin("remove() on ..");
|
||||
rv = remove("..");
|
||||
report_check2(rv, errno, EISDIR, EINVAL);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
remove_empty(void)
|
||||
{
|
||||
int rv;
|
||||
static void remove_empty(void) {
|
||||
int rv;
|
||||
|
||||
report_begin("remove() on empty string");
|
||||
rv = remove("");
|
||||
report_check2(rv, errno, EISDIR, EINVAL);
|
||||
report_begin("remove() on empty string");
|
||||
rv = remove("");
|
||||
report_check2(rv, errno, EISDIR, EINVAL);
|
||||
}
|
||||
|
||||
void
|
||||
test_remove(void)
|
||||
{
|
||||
test_remove_path();
|
||||
void test_remove(void) {
|
||||
test_remove_path();
|
||||
|
||||
remove_dir();
|
||||
remove_dot();
|
||||
remove_dotdot();
|
||||
remove_empty();
|
||||
remove_dir();
|
||||
remove_dot();
|
||||
remove_dotdot();
|
||||
remove_empty();
|
||||
}
|
||||
|
||||
@@ -36,76 +36,61 @@
|
||||
|
||||
#include "test.h"
|
||||
|
||||
static
|
||||
void
|
||||
rename_dot(void)
|
||||
{
|
||||
int rv;
|
||||
static void rename_dot(void) {
|
||||
int rv;
|
||||
|
||||
report_begin("rename .");
|
||||
report_begin("rename .");
|
||||
|
||||
rv = rename(".", TESTDIR);
|
||||
report_check(rv, errno, EINVAL);
|
||||
if (rv==0) {
|
||||
/* oops... put it back */
|
||||
rename(TESTDIR, ".");
|
||||
}
|
||||
rv = rename(".", TESTDIR);
|
||||
report_check(rv, errno, EINVAL);
|
||||
if (rv == 0) {
|
||||
/* oops... put it back */
|
||||
rename(TESTDIR, ".");
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
rename_dotdot(void)
|
||||
{
|
||||
int rv;
|
||||
static void rename_dotdot(void) {
|
||||
int rv;
|
||||
|
||||
report_begin("rename ..");
|
||||
rv = rename("..", TESTDIR);
|
||||
report_check(rv, errno, EINVAL);
|
||||
if (rv==0) {
|
||||
/* oops... put it back */
|
||||
rename(TESTDIR, "..");
|
||||
}
|
||||
report_begin("rename ..");
|
||||
rv = rename("..", TESTDIR);
|
||||
report_check(rv, errno, EINVAL);
|
||||
if (rv == 0) {
|
||||
/* oops... put it back */
|
||||
rename(TESTDIR, "..");
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
rename_empty1(void)
|
||||
{
|
||||
int rv;
|
||||
static void rename_empty1(void) {
|
||||
int rv;
|
||||
|
||||
report_begin("rename empty string");
|
||||
rv = rename("", TESTDIR);
|
||||
report_check2(rv, errno, EISDIR, EINVAL);
|
||||
if (rv==0) {
|
||||
/* don't try to remove it */
|
||||
rename(TESTDIR, TESTDIR "-foo");
|
||||
}
|
||||
report_begin("rename empty string");
|
||||
rv = rename("", TESTDIR);
|
||||
report_check2(rv, errno, EISDIR, EINVAL);
|
||||
if (rv == 0) {
|
||||
/* don't try to remove it */
|
||||
rename(TESTDIR, TESTDIR "-foo");
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
rename_empty2(void)
|
||||
{
|
||||
int rv;
|
||||
static void rename_empty2(void) {
|
||||
int rv;
|
||||
|
||||
report_begin("rename to empty string");
|
||||
if (create_testdir()<0) {
|
||||
/*report_aborted();*/ /* XXX in create_testdir */
|
||||
return;
|
||||
}
|
||||
rv = rename(TESTDIR, "");
|
||||
report_check2(rv, errno, EISDIR, EINVAL);
|
||||
rmdir(TESTDIR);
|
||||
report_begin("rename to empty string");
|
||||
if (create_testdir() < 0) {
|
||||
/*report_aborted();*/ /* XXX in create_testdir */
|
||||
return;
|
||||
}
|
||||
rv = rename(TESTDIR, "");
|
||||
report_check2(rv, errno, EISDIR, EINVAL);
|
||||
rmdir(TESTDIR);
|
||||
}
|
||||
|
||||
void
|
||||
test_rename(void)
|
||||
{
|
||||
test_rename_paths();
|
||||
void test_rename(void) {
|
||||
test_rename_paths();
|
||||
|
||||
rename_dot();
|
||||
rename_dotdot();
|
||||
rename_empty1();
|
||||
rename_empty2();
|
||||
rename_dot();
|
||||
rename_dotdot();
|
||||
rename_empty1();
|
||||
rename_empty2();
|
||||
}
|
||||
|
||||
|
||||
@@ -43,62 +43,48 @@
|
||||
#include "config.h"
|
||||
#include "test.h"
|
||||
|
||||
static
|
||||
void
|
||||
rmdir_file(void)
|
||||
{
|
||||
int rv;
|
||||
static void rmdir_file(void) {
|
||||
int rv;
|
||||
|
||||
report_begin("rmdir a file");
|
||||
if (create_testfile()<0) {
|
||||
report_aborted();
|
||||
return;
|
||||
}
|
||||
rv = rmdir(TESTFILE);
|
||||
report_check(rv, errno, ENOTDIR);
|
||||
remove(TESTFILE);
|
||||
report_begin("rmdir a file");
|
||||
if (create_testfile() < 0) {
|
||||
report_aborted();
|
||||
return;
|
||||
}
|
||||
rv = rmdir(TESTFILE);
|
||||
report_check(rv, errno, ENOTDIR);
|
||||
remove(TESTFILE);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
rmdir_dot(void)
|
||||
{
|
||||
int rv;
|
||||
static void rmdir_dot(void) {
|
||||
int rv;
|
||||
|
||||
report_begin("rmdir .");
|
||||
rv = rmdir(".");
|
||||
report_check(rv, errno, EINVAL);
|
||||
report_begin("rmdir .");
|
||||
rv = rmdir(".");
|
||||
report_check(rv, errno, EINVAL);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
rmdir_dotdot(void)
|
||||
{
|
||||
int rv;
|
||||
static void rmdir_dotdot(void) {
|
||||
int rv;
|
||||
|
||||
report_begin("rmdir ..");
|
||||
rv = rmdir("..");
|
||||
report_check2(rv, errno, EINVAL, ENOTEMPTY);
|
||||
report_begin("rmdir ..");
|
||||
rv = rmdir("..");
|
||||
report_check2(rv, errno, EINVAL, ENOTEMPTY);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
rmdir_empty(void)
|
||||
{
|
||||
int rv;
|
||||
static void rmdir_empty(void) {
|
||||
int rv;
|
||||
|
||||
report_begin("rmdir empty string");
|
||||
rv = rmdir("");
|
||||
report_check(rv, errno, EINVAL);
|
||||
report_begin("rmdir empty string");
|
||||
rv = rmdir("");
|
||||
report_check(rv, errno, EINVAL);
|
||||
}
|
||||
|
||||
void
|
||||
test_rmdir(void)
|
||||
{
|
||||
test_rmdir_path();
|
||||
void test_rmdir(void) {
|
||||
test_rmdir_path();
|
||||
|
||||
rmdir_file();
|
||||
rmdir_dot();
|
||||
rmdir_dotdot();
|
||||
rmdir_empty();
|
||||
rmdir_file();
|
||||
rmdir_dot();
|
||||
rmdir_dotdot();
|
||||
rmdir_empty();
|
||||
}
|
||||
|
||||
@@ -46,80 +46,56 @@
|
||||
/*
|
||||
* typing wrapper around sbrk
|
||||
*/
|
||||
static
|
||||
int
|
||||
try_sbrk(long val)
|
||||
{
|
||||
void *rv;
|
||||
rv = sbrk(val);
|
||||
if (rv==(void *)-1) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
static int try_sbrk(long val) {
|
||||
void *rv;
|
||||
rv = sbrk(val);
|
||||
if (rv == (void *)-1) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
enforce_sbrk(long val, const char *desc, int err)
|
||||
{
|
||||
int result;
|
||||
static void enforce_sbrk(long val, const char *desc, int err) {
|
||||
int result;
|
||||
|
||||
report_begin("sbrk %s", desc);
|
||||
report_begin("sbrk %s", desc);
|
||||
|
||||
result = try_sbrk(val);
|
||||
report_check(result, errno, err);
|
||||
result = try_sbrk(val);
|
||||
report_check(result, errno, err);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
sbrk_bigpos(void)
|
||||
{
|
||||
enforce_sbrk(4096*1024*256, "huge positive", ENOMEM);
|
||||
static void sbrk_bigpos(void) {
|
||||
enforce_sbrk(4096 * 1024 * 256, "huge positive", ENOMEM);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
sbrk_bigneg(void)
|
||||
{
|
||||
enforce_sbrk(-4096*1024*256, "huge negative", EINVAL);
|
||||
static void sbrk_bigneg(void) {
|
||||
enforce_sbrk(-4096 * 1024 * 256, "huge negative", EINVAL);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
sbrk_neg(void)
|
||||
{
|
||||
enforce_sbrk(-8192, "too-large negative", EINVAL);
|
||||
static void sbrk_neg(void) {
|
||||
enforce_sbrk(-8192, "too-large negative", EINVAL);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
sbrk_unalignedpos(void)
|
||||
{
|
||||
int result;
|
||||
static void sbrk_unalignedpos(void) {
|
||||
int result;
|
||||
|
||||
report_begin("sbrk unaligned positive");
|
||||
result = try_sbrk(17);
|
||||
report_check2(result, errno, 0, EINVAL);
|
||||
report_begin("sbrk unaligned positive");
|
||||
result = try_sbrk(17);
|
||||
report_check2(result, errno, 0, EINVAL);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
sbrk_unalignedneg(void)
|
||||
{
|
||||
int result;
|
||||
static void sbrk_unalignedneg(void) {
|
||||
int result;
|
||||
|
||||
report_begin("sbrk unaligned negative");
|
||||
result = try_sbrk(-17);
|
||||
report_check2(result, errno, 0, EINVAL);
|
||||
report_begin("sbrk unaligned negative");
|
||||
result = try_sbrk(-17);
|
||||
report_check2(result, errno, 0, EINVAL);
|
||||
}
|
||||
|
||||
void
|
||||
test_sbrk(void)
|
||||
{
|
||||
sbrk_neg();
|
||||
sbrk_bigpos();
|
||||
sbrk_bigneg();
|
||||
sbrk_unalignedpos();
|
||||
sbrk_unalignedneg();
|
||||
void test_sbrk(void) {
|
||||
sbrk_neg();
|
||||
sbrk_bigpos();
|
||||
sbrk_bigneg();
|
||||
sbrk_unalignedpos();
|
||||
sbrk_unalignedneg();
|
||||
}
|
||||
|
||||
|
||||
@@ -45,84 +45,54 @@
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
static
|
||||
int
|
||||
badbuf_fstat(struct stat *sb)
|
||||
{
|
||||
return fstat(STDIN_FILENO, sb);
|
||||
static int badbuf_fstat(struct stat *sb) { return fstat(STDIN_FILENO, sb); }
|
||||
|
||||
static int badbuf_lstat(struct stat *sb) { return lstat("null:", sb); }
|
||||
|
||||
static int badbuf_stat(struct stat *sb) { return stat("null:", sb); }
|
||||
|
||||
static void common_badbuf(int (*statfunc)(struct stat *), void *ptr,
|
||||
const char *call, const char *ptrdesc) {
|
||||
int rv;
|
||||
|
||||
report_begin("%s with %s buf", call, ptrdesc);
|
||||
rv = statfunc(ptr);
|
||||
report_check(rv, errno, EFAULT);
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
badbuf_lstat(struct stat *sb)
|
||||
{
|
||||
return lstat("null:", sb);
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
badbuf_stat(struct stat *sb)
|
||||
{
|
||||
return stat("null:", sb);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
common_badbuf(int (*statfunc)(struct stat *), void *ptr,
|
||||
const char *call, const char *ptrdesc)
|
||||
{
|
||||
int rv;
|
||||
|
||||
report_begin("%s with %s buf", call, ptrdesc);
|
||||
rv = statfunc(ptr);
|
||||
report_check(rv, errno, EFAULT);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
any_badbuf(int (*statfunc)(struct stat *), const char *call)
|
||||
{
|
||||
common_badbuf(statfunc, NULL, call, "NULL");
|
||||
common_badbuf(statfunc, INVAL_PTR, call, "invalid pointer");
|
||||
common_badbuf(statfunc, KERN_PTR, call, "kernel pointer");
|
||||
static void any_badbuf(int (*statfunc)(struct stat *), const char *call) {
|
||||
common_badbuf(statfunc, NULL, call, "NULL");
|
||||
common_badbuf(statfunc, INVAL_PTR, call, "invalid pointer");
|
||||
common_badbuf(statfunc, KERN_PTR, call, "kernel pointer");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
static
|
||||
void
|
||||
any_empty(int (*statfunc)(const char *, struct stat *), const char *call)
|
||||
{
|
||||
struct stat sb;
|
||||
int rv;
|
||||
static void any_empty(int (*statfunc)(const char *, struct stat *),
|
||||
const char *call) {
|
||||
struct stat sb;
|
||||
int rv;
|
||||
|
||||
report_begin("%s on empty string", call);
|
||||
rv = statfunc("", &sb);
|
||||
report_check2(rv, errno, 0, EINVAL);
|
||||
report_begin("%s on empty string", call);
|
||||
rv = statfunc("", &sb);
|
||||
report_check2(rv, errno, 0, EINVAL);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
void
|
||||
test_fstat(void)
|
||||
{
|
||||
test_fstat_fd();
|
||||
any_badbuf(badbuf_fstat, "fstat");
|
||||
void test_fstat(void) {
|
||||
test_fstat_fd();
|
||||
any_badbuf(badbuf_fstat, "fstat");
|
||||
}
|
||||
|
||||
void
|
||||
test_lstat(void)
|
||||
{
|
||||
test_lstat_path();
|
||||
any_empty(lstat, "lstat");
|
||||
any_badbuf(badbuf_lstat, "lstat");
|
||||
void test_lstat(void) {
|
||||
test_lstat_path();
|
||||
any_empty(lstat, "lstat");
|
||||
any_badbuf(badbuf_lstat, "lstat");
|
||||
}
|
||||
|
||||
void
|
||||
test_stat(void)
|
||||
{
|
||||
test_stat_path();
|
||||
any_empty(stat, "stat");
|
||||
any_badbuf(badbuf_stat, "stat");
|
||||
void test_stat(void) {
|
||||
test_stat_path();
|
||||
any_empty(stat, "stat");
|
||||
any_badbuf(badbuf_stat, "stat");
|
||||
}
|
||||
|
||||
|
||||
@@ -36,33 +36,25 @@
|
||||
|
||||
#include "test.h"
|
||||
|
||||
static
|
||||
void
|
||||
symlink_empty1(void)
|
||||
{
|
||||
int rv;
|
||||
static void symlink_empty1(void) {
|
||||
int rv;
|
||||
|
||||
report_begin("symlink -> empty string");
|
||||
rv = symlink("", TESTLINK);
|
||||
report_check2(rv, errno, 0, EINVAL);
|
||||
remove(TESTLINK);
|
||||
report_begin("symlink -> empty string");
|
||||
rv = symlink("", TESTLINK);
|
||||
report_check2(rv, errno, 0, EINVAL);
|
||||
remove(TESTLINK);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
symlink_empty2(void)
|
||||
{
|
||||
int rv;
|
||||
static void symlink_empty2(void) {
|
||||
int rv;
|
||||
|
||||
report_begin("symlink named empty string");
|
||||
rv = symlink("foo", "");
|
||||
report_check(rv, errno, EINVAL);
|
||||
report_begin("symlink named empty string");
|
||||
rv = symlink("foo", "");
|
||||
report_check(rv, errno, EINVAL);
|
||||
}
|
||||
|
||||
void
|
||||
test_symlink(void)
|
||||
{
|
||||
test_symlink_paths();
|
||||
symlink_empty1();
|
||||
symlink_empty2();
|
||||
void test_symlink(void) {
|
||||
test_symlink_paths();
|
||||
symlink_empty1();
|
||||
symlink_empty2();
|
||||
}
|
||||
|
||||
@@ -43,34 +43,26 @@
|
||||
#include "config.h"
|
||||
#include "test.h"
|
||||
|
||||
static
|
||||
void
|
||||
time_badsecs(void *ptr, const char *desc)
|
||||
{
|
||||
int rv;
|
||||
static void time_badsecs(void *ptr, const char *desc) {
|
||||
int rv;
|
||||
|
||||
report_begin("%s", desc);
|
||||
rv = __time(ptr, NULL);
|
||||
report_check(rv, errno, EFAULT);
|
||||
report_begin("%s", desc);
|
||||
rv = __time(ptr, NULL);
|
||||
report_check(rv, errno, EFAULT);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
time_badnsecs(void *ptr, const char *desc)
|
||||
{
|
||||
int rv;
|
||||
static void time_badnsecs(void *ptr, const char *desc) {
|
||||
int rv;
|
||||
|
||||
report_begin("%s", desc);
|
||||
rv = __time(NULL, ptr);
|
||||
report_check(rv, errno, EFAULT);
|
||||
report_begin("%s", desc);
|
||||
rv = __time(NULL, ptr);
|
||||
report_check(rv, errno, EFAULT);
|
||||
}
|
||||
|
||||
void
|
||||
test_time(void)
|
||||
{
|
||||
time_badsecs(INVAL_PTR, "__time with invalid seconds pointer");
|
||||
time_badsecs(KERN_PTR, "__time with kernel seconds pointer");
|
||||
void test_time(void) {
|
||||
time_badsecs(INVAL_PTR, "__time with invalid seconds pointer");
|
||||
time_badsecs(KERN_PTR, "__time with kernel seconds pointer");
|
||||
|
||||
time_badnsecs(INVAL_PTR, "__time with invalid nsecs pointer");
|
||||
time_badnsecs(KERN_PTR, "__time with kernel nsecs pointer");
|
||||
time_badnsecs(INVAL_PTR, "__time with invalid nsecs pointer");
|
||||
time_badnsecs(KERN_PTR, "__time with kernel nsecs pointer");
|
||||
}
|
||||
|
||||
@@ -41,383 +41,344 @@
|
||||
#include "config.h"
|
||||
#include "test.h"
|
||||
|
||||
static
|
||||
void
|
||||
wait_badpid(pid_t pid, const char *desc)
|
||||
{
|
||||
pid_t rv;
|
||||
int x;
|
||||
int err;
|
||||
static void wait_badpid(pid_t pid, const char *desc) {
|
||||
pid_t rv;
|
||||
int x;
|
||||
int err;
|
||||
|
||||
report_begin(desc);
|
||||
rv = waitpid(pid, &x, 0);
|
||||
err = errno;
|
||||
/* Allow ENOSYS for 0 or negative values of pid only */
|
||||
if (pid <= 0 && rv == -1 && err == ENOSYS) {
|
||||
err = ESRCH;
|
||||
}
|
||||
else if (err == ENOSYS) {
|
||||
report_saw_enosys();
|
||||
}
|
||||
report_check2(rv, err, ESRCH, ECHILD);
|
||||
report_begin(desc);
|
||||
rv = waitpid(pid, &x, 0);
|
||||
err = errno;
|
||||
/* Allow ENOSYS for 0 or negative values of pid only */
|
||||
if (pid <= 0 && rv == -1 && err == ENOSYS) {
|
||||
err = ESRCH;
|
||||
} else if (err == ENOSYS) {
|
||||
report_saw_enosys();
|
||||
}
|
||||
report_check2(rv, err, ESRCH, ECHILD);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
wait_nullstatus(void)
|
||||
{
|
||||
pid_t pid, rv;
|
||||
int x;
|
||||
static void wait_nullstatus(void) {
|
||||
pid_t pid, rv;
|
||||
int x;
|
||||
|
||||
report_begin("wait with NULL status");
|
||||
report_begin("wait with NULL status");
|
||||
|
||||
pid = fork();
|
||||
if (pid<0) {
|
||||
report_warn("fork failed");
|
||||
report_aborted();
|
||||
return;
|
||||
}
|
||||
if (pid==0) {
|
||||
exit(0);
|
||||
}
|
||||
pid = fork();
|
||||
if (pid < 0) {
|
||||
report_warn("fork failed");
|
||||
report_aborted();
|
||||
return;
|
||||
}
|
||||
if (pid == 0) {
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* POSIX explicitly says passing NULL for status is allowed */
|
||||
rv = waitpid(pid, NULL, 0);
|
||||
report_check(rv, errno, 0);
|
||||
waitpid(pid, &x, 0);
|
||||
/* POSIX explicitly says passing NULL for status is allowed */
|
||||
rv = waitpid(pid, NULL, 0);
|
||||
report_check(rv, errno, 0);
|
||||
waitpid(pid, &x, 0);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
wait_badstatus(void *ptr, const char *desc)
|
||||
{
|
||||
pid_t pid, rv;
|
||||
int x;
|
||||
static void wait_badstatus(void *ptr, const char *desc) {
|
||||
pid_t pid, rv;
|
||||
int x;
|
||||
|
||||
report_begin(desc);
|
||||
report_begin(desc);
|
||||
|
||||
pid = fork();
|
||||
if (pid<0) {
|
||||
report_warn("fork failed");
|
||||
report_aborted();
|
||||
return;
|
||||
}
|
||||
if (pid==0) {
|
||||
exit(0);
|
||||
}
|
||||
pid = fork();
|
||||
if (pid < 0) {
|
||||
report_warn("fork failed");
|
||||
report_aborted();
|
||||
return;
|
||||
}
|
||||
if (pid == 0) {
|
||||
exit(0);
|
||||
}
|
||||
|
||||
rv = waitpid(pid, ptr, 0);
|
||||
report_check(rv, errno, EFAULT);
|
||||
waitpid(pid, &x, 0);
|
||||
rv = waitpid(pid, ptr, 0);
|
||||
report_check(rv, errno, EFAULT);
|
||||
waitpid(pid, &x, 0);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
wait_unaligned(void)
|
||||
{
|
||||
pid_t pid, rv;
|
||||
int x;
|
||||
int status[2]; /* will have integer alignment */
|
||||
char *ptr;
|
||||
static void wait_unaligned(void) {
|
||||
pid_t pid, rv;
|
||||
int x;
|
||||
int status[2]; /* will have integer alignment */
|
||||
char *ptr;
|
||||
|
||||
report_begin("wait with unaligned status");
|
||||
report_begin("wait with unaligned status");
|
||||
|
||||
pid = fork();
|
||||
if (pid<0) {
|
||||
report_warn("fork failed");
|
||||
report_aborted();
|
||||
return;
|
||||
}
|
||||
if (pid==0) {
|
||||
exit(0);
|
||||
}
|
||||
pid = fork();
|
||||
if (pid < 0) {
|
||||
report_warn("fork failed");
|
||||
report_aborted();
|
||||
return;
|
||||
}
|
||||
if (pid == 0) {
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* start with proper integer alignment */
|
||||
ptr = (char *)(&status[0]);
|
||||
/* start with proper integer alignment */
|
||||
ptr = (char *)(&status[0]);
|
||||
|
||||
/* generate improper alignment on platforms with restrictions */
|
||||
ptr++;
|
||||
/* generate improper alignment on platforms with restrictions */
|
||||
ptr++;
|
||||
|
||||
rv = waitpid(pid, (int *)ptr, 0);
|
||||
report_survival(rv, errno);
|
||||
if (rv<0) {
|
||||
waitpid(pid, &x, 0);
|
||||
}
|
||||
rv = waitpid(pid, (int *)ptr, 0);
|
||||
report_survival(rv, errno);
|
||||
if (rv < 0) {
|
||||
waitpid(pid, &x, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
wait_badflags(void)
|
||||
{
|
||||
pid_t pid, rv;
|
||||
int x;
|
||||
static void wait_badflags(void) {
|
||||
pid_t pid, rv;
|
||||
int x;
|
||||
|
||||
report_begin("wait with bad flags");
|
||||
report_begin("wait with bad flags");
|
||||
|
||||
pid = fork();
|
||||
if (pid<0) {
|
||||
report_warn("fork failed");
|
||||
report_aborted();
|
||||
return;
|
||||
}
|
||||
if (pid==0) {
|
||||
exit(0);
|
||||
}
|
||||
pid = fork();
|
||||
if (pid < 0) {
|
||||
report_warn("fork failed");
|
||||
report_aborted();
|
||||
return;
|
||||
}
|
||||
if (pid == 0) {
|
||||
exit(0);
|
||||
}
|
||||
|
||||
rv = waitpid(pid, &x, 309429);
|
||||
report_check(rv, errno, EINVAL);
|
||||
waitpid(pid, &x, 0);
|
||||
rv = waitpid(pid, &x, 309429);
|
||||
report_check(rv, errno, EINVAL);
|
||||
waitpid(pid, &x, 0);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
wait_self(void)
|
||||
{
|
||||
pid_t rv;
|
||||
int x;
|
||||
static void wait_self(void) {
|
||||
pid_t rv;
|
||||
int x;
|
||||
|
||||
report_begin("wait for self");
|
||||
report_begin("wait for self");
|
||||
|
||||
rv = waitpid(getpid(), &x, 0);
|
||||
report_survival(rv, errno);
|
||||
rv = waitpid(getpid(), &x, 0);
|
||||
report_survival(rv, errno);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
wait_parent(void)
|
||||
{
|
||||
pid_t mypid, childpid, rv;
|
||||
int x;
|
||||
static void wait_parent(void) {
|
||||
pid_t mypid, childpid, rv;
|
||||
int x;
|
||||
|
||||
report_begin("wait for parent");
|
||||
report_hassubs();
|
||||
report_begin("wait for parent");
|
||||
report_hassubs();
|
||||
|
||||
mypid = getpid();
|
||||
childpid = fork();
|
||||
if (childpid<0) {
|
||||
report_warn("can't fork");
|
||||
report_aborted();
|
||||
return;
|
||||
}
|
||||
if (childpid==0) {
|
||||
/* Child. Wait for parent. */
|
||||
rv = waitpid(mypid, &x, 0);
|
||||
report_beginsub("from child:");
|
||||
report_survival(rv, errno);
|
||||
_exit(0);
|
||||
}
|
||||
rv = waitpid(childpid, &x, 0);
|
||||
report_beginsub("from parent:");
|
||||
report_survival(rv, errno);
|
||||
mypid = getpid();
|
||||
childpid = fork();
|
||||
if (childpid < 0) {
|
||||
report_warn("can't fork");
|
||||
report_aborted();
|
||||
return;
|
||||
}
|
||||
if (childpid == 0) {
|
||||
/* Child. Wait for parent. */
|
||||
rv = waitpid(mypid, &x, 0);
|
||||
report_beginsub("from child:");
|
||||
report_survival(rv, errno);
|
||||
_exit(0);
|
||||
}
|
||||
rv = waitpid(childpid, &x, 0);
|
||||
report_beginsub("from parent:");
|
||||
report_survival(rv, errno);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
static
|
||||
void
|
||||
wait_siblings_child(const char *semname)
|
||||
{
|
||||
pid_t pids[2], mypid, otherpid;
|
||||
int rv, fd, semfd, x;
|
||||
char c;
|
||||
static void wait_siblings_child(const char *semname) {
|
||||
pid_t pids[2], mypid, otherpid;
|
||||
int rv, fd, semfd, x;
|
||||
char c;
|
||||
|
||||
mypid = getpid();
|
||||
mypid = getpid();
|
||||
|
||||
/*
|
||||
* Get our own handle for the semaphore, in case naive
|
||||
* file-level synchronization causes concurrent use to
|
||||
* deadlock.
|
||||
*/
|
||||
semfd = open(semname, O_RDONLY);
|
||||
if (semfd < 0) {
|
||||
report_warn("child process (pid %d) can't open %s",
|
||||
mypid, semname);
|
||||
}
|
||||
else {
|
||||
if (read(semfd, &c, 1) < 0) {
|
||||
report_warn("in pid %d: %s: read", mypid, semname);
|
||||
}
|
||||
close(semfd);
|
||||
}
|
||||
/*
|
||||
* Get our own handle for the semaphore, in case naive
|
||||
* file-level synchronization causes concurrent use to
|
||||
* deadlock.
|
||||
*/
|
||||
semfd = open(semname, O_RDONLY);
|
||||
if (semfd < 0) {
|
||||
report_warn("child process (pid %d) can't open %s", mypid, semname);
|
||||
} else {
|
||||
if (read(semfd, &c, 1) < 0) {
|
||||
report_warn("in pid %d: %s: read", mypid, semname);
|
||||
}
|
||||
close(semfd);
|
||||
}
|
||||
|
||||
fd = open(TESTFILE, O_RDONLY);
|
||||
if (fd<0) {
|
||||
report_warn("child process (pid %d) can't open %s",
|
||||
mypid, TESTFILE);
|
||||
return;
|
||||
}
|
||||
fd = open(TESTFILE, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
report_warn("child process (pid %d) can't open %s", mypid, TESTFILE);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* In case the semaphore above didn't work, as a backup
|
||||
* busy-wait until the parent writes the pids into the
|
||||
* file. If the semaphore did work, this shouldn't loop.
|
||||
*/
|
||||
do {
|
||||
rv = lseek(fd, 0, SEEK_SET);
|
||||
if (rv<0) {
|
||||
report_warn("child process (pid %d) lseek error",
|
||||
mypid);
|
||||
return;
|
||||
}
|
||||
rv = read(fd, pids, sizeof(pids));
|
||||
if (rv<0) {
|
||||
report_warn("child process (pid %d) read error",
|
||||
mypid);
|
||||
return;
|
||||
}
|
||||
} while (rv < (int)sizeof(pids));
|
||||
/*
|
||||
* In case the semaphore above didn't work, as a backup
|
||||
* busy-wait until the parent writes the pids into the
|
||||
* file. If the semaphore did work, this shouldn't loop.
|
||||
*/
|
||||
do {
|
||||
rv = lseek(fd, 0, SEEK_SET);
|
||||
if (rv < 0) {
|
||||
report_warn("child process (pid %d) lseek error", mypid);
|
||||
return;
|
||||
}
|
||||
rv = read(fd, pids, sizeof(pids));
|
||||
if (rv < 0) {
|
||||
report_warn("child process (pid %d) read error", mypid);
|
||||
return;
|
||||
}
|
||||
} while (rv < (int)sizeof(pids));
|
||||
|
||||
if (mypid==pids[0]) {
|
||||
otherpid = pids[1];
|
||||
}
|
||||
else if (mypid==pids[1]) {
|
||||
otherpid = pids[0];
|
||||
}
|
||||
else {
|
||||
report_warn("child process (pid %d) got garbage in comm file",
|
||||
mypid);
|
||||
return;
|
||||
}
|
||||
close(fd);
|
||||
if (mypid == pids[0]) {
|
||||
otherpid = pids[1];
|
||||
} else if (mypid == pids[1]) {
|
||||
otherpid = pids[0];
|
||||
} else {
|
||||
report_warn("child process (pid %d) got garbage in comm file", mypid);
|
||||
return;
|
||||
}
|
||||
close(fd);
|
||||
|
||||
rv = waitpid(otherpid, &x, 0);
|
||||
report_beginsub("sibling (pid %d)", mypid);
|
||||
report_survival(rv, errno);
|
||||
rv = waitpid(otherpid, &x, 0);
|
||||
report_beginsub("sibling (pid %d)", mypid);
|
||||
report_survival(rv, errno);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
wait_siblings(void)
|
||||
{
|
||||
pid_t pids[2];
|
||||
int rv, fd, semfd, x;
|
||||
int bad = 0;
|
||||
char semname[32];
|
||||
static void wait_siblings(void) {
|
||||
pid_t pids[2];
|
||||
int rv, fd, semfd, x;
|
||||
int bad = 0;
|
||||
char semname[32];
|
||||
|
||||
/* This test may also blow up if FS synchronization is substandard */
|
||||
/* This test may also blow up if FS synchronization is substandard */
|
||||
|
||||
report_begin("siblings wait for each other");
|
||||
report_hassubs();
|
||||
report_begin("siblings wait for each other");
|
||||
report_hassubs();
|
||||
|
||||
snprintf(semname, sizeof(semname), "sem:badcall.%d", (int)getpid());
|
||||
semfd = open(semname, O_WRONLY|O_CREAT|O_TRUNC, 0664);
|
||||
if (semfd < 0) {
|
||||
report_warn("can't make semaphore");
|
||||
report_aborted();
|
||||
return;
|
||||
}
|
||||
snprintf(semname, sizeof(semname), "sem:badcall.%d", (int)getpid());
|
||||
semfd = open(semname, O_WRONLY | O_CREAT | O_TRUNC, 0664);
|
||||
if (semfd < 0) {
|
||||
report_warn("can't make semaphore");
|
||||
report_aborted();
|
||||
return;
|
||||
}
|
||||
|
||||
fd = open_testfile(NULL);
|
||||
if (fd<0) {
|
||||
report_aborted();
|
||||
close(semfd);
|
||||
remove(semname);
|
||||
return;
|
||||
}
|
||||
fd = open_testfile(NULL);
|
||||
if (fd < 0) {
|
||||
report_aborted();
|
||||
close(semfd);
|
||||
remove(semname);
|
||||
return;
|
||||
}
|
||||
|
||||
pids[0] = fork();
|
||||
if (pids[0]<0) {
|
||||
report_warn("can't fork");
|
||||
report_aborted();
|
||||
close(fd);
|
||||
close(semfd);
|
||||
remove(semname);
|
||||
return;
|
||||
}
|
||||
if (pids[0]==0) {
|
||||
close(fd);
|
||||
close(semfd);
|
||||
wait_siblings_child(semname);
|
||||
_exit(0);
|
||||
}
|
||||
pids[0] = fork();
|
||||
if (pids[0] < 0) {
|
||||
report_warn("can't fork");
|
||||
report_aborted();
|
||||
close(fd);
|
||||
close(semfd);
|
||||
remove(semname);
|
||||
return;
|
||||
}
|
||||
if (pids[0] == 0) {
|
||||
close(fd);
|
||||
close(semfd);
|
||||
wait_siblings_child(semname);
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
pids[1] = fork();
|
||||
if (pids[1]<0) {
|
||||
report_warn("can't fork");
|
||||
report_aborted();
|
||||
/* abandon the other child process :( */
|
||||
close(fd);
|
||||
close(semfd);
|
||||
remove(semname);
|
||||
return;
|
||||
}
|
||||
if (pids[1]==0) {
|
||||
close(fd);
|
||||
close(semfd);
|
||||
wait_siblings_child(semname);
|
||||
_exit(0);
|
||||
}
|
||||
pids[1] = fork();
|
||||
if (pids[1] < 0) {
|
||||
report_warn("can't fork");
|
||||
report_aborted();
|
||||
/* abandon the other child process :( */
|
||||
close(fd);
|
||||
close(semfd);
|
||||
remove(semname);
|
||||
return;
|
||||
}
|
||||
if (pids[1] == 0) {
|
||||
close(fd);
|
||||
close(semfd);
|
||||
wait_siblings_child(semname);
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
rv = write(fd, pids, sizeof(pids));
|
||||
if (rv < 0) {
|
||||
report_warn("write error on %s", TESTFILE);
|
||||
report_aborted();
|
||||
/* abandon child procs :( */
|
||||
close(fd);
|
||||
close(semfd);
|
||||
remove(semname);
|
||||
return;
|
||||
}
|
||||
if (rv != (int)sizeof(pids)) {
|
||||
report_warnx("write error on %s: short count", TESTFILE);
|
||||
report_aborted();
|
||||
/* abandon child procs :( */
|
||||
close(fd);
|
||||
close(semfd);
|
||||
remove(semname);
|
||||
return;
|
||||
}
|
||||
rv = write(fd, pids, sizeof(pids));
|
||||
if (rv < 0) {
|
||||
report_warn("write error on %s", TESTFILE);
|
||||
report_aborted();
|
||||
/* abandon child procs :( */
|
||||
close(fd);
|
||||
close(semfd);
|
||||
remove(semname);
|
||||
return;
|
||||
}
|
||||
if (rv != (int)sizeof(pids)) {
|
||||
report_warnx("write error on %s: short count", TESTFILE);
|
||||
report_aborted();
|
||||
/* abandon child procs :( */
|
||||
close(fd);
|
||||
close(semfd);
|
||||
remove(semname);
|
||||
return;
|
||||
}
|
||||
|
||||
/* gate the child procs */
|
||||
rv = write(semfd, " ", 2);
|
||||
if (rv < 0) {
|
||||
report_warn("%s: write", semname);
|
||||
bad = 1;
|
||||
}
|
||||
/* gate the child procs */
|
||||
rv = write(semfd, " ", 2);
|
||||
if (rv < 0) {
|
||||
report_warn("%s: write", semname);
|
||||
bad = 1;
|
||||
}
|
||||
|
||||
report_beginsub("overall");
|
||||
rv = waitpid(pids[0], &x, 0);
|
||||
if (rv<0) {
|
||||
report_warn("error waiting for child 0 (pid %d)", pids[0]);
|
||||
bad = 1;
|
||||
}
|
||||
rv = waitpid(pids[1], &x, 0);
|
||||
if (rv<0) {
|
||||
report_warn("error waiting for child 1 (pid %d)", pids[1]);
|
||||
bad = 1;
|
||||
}
|
||||
if (bad) {
|
||||
/* XXX: aborted, or failure, or what? */
|
||||
report_aborted();
|
||||
}
|
||||
else {
|
||||
report_passed();
|
||||
}
|
||||
close(fd);
|
||||
close(semfd);
|
||||
remove(semname);
|
||||
remove(TESTFILE);
|
||||
report_beginsub("overall");
|
||||
rv = waitpid(pids[0], &x, 0);
|
||||
if (rv < 0) {
|
||||
report_warn("error waiting for child 0 (pid %d)", pids[0]);
|
||||
bad = 1;
|
||||
}
|
||||
rv = waitpid(pids[1], &x, 0);
|
||||
if (rv < 0) {
|
||||
report_warn("error waiting for child 1 (pid %d)", pids[1]);
|
||||
bad = 1;
|
||||
}
|
||||
if (bad) {
|
||||
/* XXX: aborted, or failure, or what? */
|
||||
report_aborted();
|
||||
} else {
|
||||
report_passed();
|
||||
}
|
||||
close(fd);
|
||||
close(semfd);
|
||||
remove(semname);
|
||||
remove(TESTFILE);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
void
|
||||
test_waitpid(void)
|
||||
{
|
||||
wait_badpid(-8, "wait for pid -8");
|
||||
wait_badpid(-1, "wait for pid -1");
|
||||
wait_badpid(0, "pid zero");
|
||||
wait_badpid(NONEXIST_PID, "nonexistent pid");
|
||||
void test_waitpid(void) {
|
||||
wait_badpid(-8, "wait for pid -8");
|
||||
wait_badpid(-1, "wait for pid -1");
|
||||
wait_badpid(0, "pid zero");
|
||||
wait_badpid(NONEXIST_PID, "nonexistent pid");
|
||||
|
||||
wait_nullstatus();
|
||||
wait_badstatus(INVAL_PTR, "wait with invalid pointer status");
|
||||
wait_badstatus(KERN_PTR, "wait with kernel pointer status");
|
||||
wait_nullstatus();
|
||||
wait_badstatus(INVAL_PTR, "wait with invalid pointer status");
|
||||
wait_badstatus(KERN_PTR, "wait with kernel pointer status");
|
||||
|
||||
wait_unaligned();
|
||||
wait_unaligned();
|
||||
|
||||
wait_badflags();
|
||||
wait_badflags();
|
||||
|
||||
wait_self();
|
||||
wait_parent();
|
||||
wait_siblings();
|
||||
wait_self();
|
||||
wait_parent();
|
||||
wait_siblings();
|
||||
}
|
||||
|
||||
@@ -33,9 +33,7 @@
|
||||
|
||||
#include "test.h"
|
||||
|
||||
void
|
||||
test_write(void)
|
||||
{
|
||||
test_write_fd();
|
||||
test_write_buf();
|
||||
void test_write(void) {
|
||||
test_write_fd();
|
||||
test_write_buf();
|
||||
}
|
||||
|
||||
@@ -47,169 +47,108 @@
|
||||
static int buf_fd;
|
||||
|
||||
struct buftest {
|
||||
int (*setup)(void);
|
||||
int (*op)(void *);
|
||||
void (*cleanup)(void);
|
||||
const char *name;
|
||||
int (*setup)(void);
|
||||
int (*op)(void *);
|
||||
void (*cleanup)(void);
|
||||
const char *name;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
static
|
||||
int
|
||||
read_setup(void)
|
||||
{
|
||||
buf_fd = open_testfile("i do not like green eggs and ham");
|
||||
if (buf_fd<0) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
static int read_setup(void) {
|
||||
buf_fd = open_testfile("i do not like green eggs and ham");
|
||||
if (buf_fd < 0) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
read_badbuf(void *buf)
|
||||
{
|
||||
return read(buf_fd, buf, 128);
|
||||
}
|
||||
static int read_badbuf(void *buf) { return read(buf_fd, buf, 128); }
|
||||
|
||||
static
|
||||
void
|
||||
read_cleanup(void)
|
||||
{
|
||||
close(buf_fd);
|
||||
remove(TESTFILE);
|
||||
static void read_cleanup(void) {
|
||||
close(buf_fd);
|
||||
remove(TESTFILE);
|
||||
}
|
||||
|
||||
//////////
|
||||
|
||||
static
|
||||
int
|
||||
write_setup(void)
|
||||
{
|
||||
buf_fd = open_testfile(NULL);
|
||||
if (buf_fd<0) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
static int write_setup(void) {
|
||||
buf_fd = open_testfile(NULL);
|
||||
if (buf_fd < 0) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
write_badbuf(void *ptr)
|
||||
{
|
||||
return write(buf_fd, ptr, 128);
|
||||
}
|
||||
static int write_badbuf(void *ptr) { return write(buf_fd, ptr, 128); }
|
||||
|
||||
static
|
||||
void
|
||||
write_cleanup(void)
|
||||
{
|
||||
close(buf_fd);
|
||||
remove(TESTFILE);
|
||||
static void write_cleanup(void) {
|
||||
close(buf_fd);
|
||||
remove(TESTFILE);
|
||||
}
|
||||
|
||||
//////////
|
||||
|
||||
static
|
||||
int
|
||||
getdirentry_setup(void)
|
||||
{
|
||||
buf_fd = open(".", O_RDONLY);
|
||||
if (buf_fd < 0) {
|
||||
warn("UH-OH: couldn't open .");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
static int getdirentry_setup(void) {
|
||||
buf_fd = open(".", O_RDONLY);
|
||||
if (buf_fd < 0) {
|
||||
warn("UH-OH: couldn't open .");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
getdirentry_badbuf(void *ptr)
|
||||
{
|
||||
return getdirentry(buf_fd, ptr, 1024);
|
||||
static int getdirentry_badbuf(void *ptr) {
|
||||
return getdirentry(buf_fd, ptr, 1024);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
getdirentry_cleanup(void)
|
||||
{
|
||||
close(buf_fd);
|
||||
}
|
||||
static void getdirentry_cleanup(void) { close(buf_fd); }
|
||||
|
||||
//////////
|
||||
|
||||
static
|
||||
int
|
||||
readlink_setup(void)
|
||||
{
|
||||
return create_testlink();
|
||||
}
|
||||
static int readlink_setup(void) { return create_testlink(); }
|
||||
|
||||
static
|
||||
int
|
||||
readlink_badbuf(void *buf)
|
||||
{
|
||||
return readlink(TESTLINK, buf, 168);
|
||||
}
|
||||
static int readlink_badbuf(void *buf) { return readlink(TESTLINK, buf, 168); }
|
||||
|
||||
static
|
||||
void
|
||||
readlink_cleanup(void)
|
||||
{
|
||||
remove(TESTLINK);
|
||||
}
|
||||
static void readlink_cleanup(void) { remove(TESTLINK); }
|
||||
|
||||
//////////
|
||||
|
||||
static int getcwd_setup(void) { return 0; }
|
||||
static void getcwd_cleanup(void) {}
|
||||
|
||||
static
|
||||
int
|
||||
getcwd_badbuf(void *buf)
|
||||
{
|
||||
return __getcwd(buf, 408);
|
||||
static int getcwd_badbuf(void *buf) { return __getcwd(buf, 408); }
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
static void common_badbuf(struct buftest *info, void *buf,
|
||||
const char *bufdesc) {
|
||||
int rv;
|
||||
|
||||
report_begin("%s with %s buffer", info->name, bufdesc);
|
||||
info->setup();
|
||||
rv = info->op(buf);
|
||||
report_check(rv, errno, EFAULT);
|
||||
info->cleanup();
|
||||
}
|
||||
|
||||
static void any_badbuf(struct buftest *info) {
|
||||
common_badbuf(info, NULL, "NULL");
|
||||
common_badbuf(info, INVAL_PTR, "invalid");
|
||||
common_badbuf(info, KERN_PTR, "kernel-space");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
static
|
||||
void
|
||||
common_badbuf(struct buftest *info, void *buf, const char *bufdesc)
|
||||
{
|
||||
int rv;
|
||||
|
||||
|
||||
report_begin("%s with %s buffer", info->name, bufdesc);
|
||||
info->setup();
|
||||
rv = info->op(buf);
|
||||
report_check(rv, errno, EFAULT);
|
||||
info->cleanup();
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
any_badbuf(struct buftest *info)
|
||||
{
|
||||
common_badbuf(info, NULL, "NULL");
|
||||
common_badbuf(info, INVAL_PTR, "invalid");
|
||||
common_badbuf(info, KERN_PTR, "kernel-space");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
#define T(call) \
|
||||
void \
|
||||
test_##call##_buf(void) \
|
||||
{ \
|
||||
static struct buftest info = { \
|
||||
call##_setup, \
|
||||
call##_badbuf, \
|
||||
call##_cleanup, \
|
||||
#call, \
|
||||
}; \
|
||||
any_badbuf(&info); \
|
||||
#define T(call) \
|
||||
void test_##call##_buf(void) { \
|
||||
static struct buftest info = { \
|
||||
call##_setup, \
|
||||
call##_badbuf, \
|
||||
call##_cleanup, \
|
||||
#call, \
|
||||
}; \
|
||||
any_badbuf(&info); \
|
||||
}
|
||||
|
||||
T(read);
|
||||
|
||||
@@ -44,182 +44,119 @@
|
||||
#include "config.h"
|
||||
#include "test.h"
|
||||
|
||||
|
||||
enum rwtestmodes {
|
||||
RW_TEST_NONE,
|
||||
RW_TEST_RDONLY,
|
||||
RW_TEST_WRONLY,
|
||||
RW_TEST_NONE,
|
||||
RW_TEST_RDONLY,
|
||||
RW_TEST_WRONLY,
|
||||
};
|
||||
|
||||
static
|
||||
int
|
||||
read_badfd(int fd)
|
||||
{
|
||||
char buf[128];
|
||||
return read(fd, buf, sizeof(buf));
|
||||
static int read_badfd(int fd) {
|
||||
char buf[128];
|
||||
return read(fd, buf, sizeof(buf));
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
write_badfd(int fd)
|
||||
{
|
||||
char buf[128];
|
||||
memset(buf, 'a', sizeof(buf));
|
||||
return write(fd, buf, sizeof(buf));
|
||||
static int write_badfd(int fd) {
|
||||
char buf[128];
|
||||
memset(buf, 'a', sizeof(buf));
|
||||
return write(fd, buf, sizeof(buf));
|
||||
}
|
||||
|
||||
static int close_badfd(int fd) { return close(fd); }
|
||||
|
||||
static
|
||||
int
|
||||
close_badfd(int fd)
|
||||
{
|
||||
return close(fd);
|
||||
static int ioctl_badfd(int fd) { return ioctl(fd, 0, NULL); }
|
||||
|
||||
static int lseek_badfd(int fd) { return lseek(fd, 0, SEEK_SET); }
|
||||
|
||||
static int fsync_badfd(int fd) { return fsync(fd); }
|
||||
|
||||
static int ftruncate_badfd(int fd) { return ftruncate(fd, 60); }
|
||||
|
||||
static int fstat_badfd(int fd) {
|
||||
struct stat sb;
|
||||
return fstat(fd, &sb);
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
ioctl_badfd(int fd)
|
||||
{
|
||||
return ioctl(fd, 0, NULL);
|
||||
static int getdirentry_badfd(int fd) {
|
||||
char buf[32];
|
||||
return getdirentry(fd, buf, sizeof(buf));
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
lseek_badfd(int fd)
|
||||
{
|
||||
return lseek(fd, 0, SEEK_SET);
|
||||
static int dup2_badfd(int fd) {
|
||||
/* use the +1 to avoid doing dup2(CLOSED_FD, CLOSED_FD) */
|
||||
return dup2(fd, CLOSED_FD + 1);
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
fsync_badfd(int fd)
|
||||
{
|
||||
return fsync(fd);
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
ftruncate_badfd(int fd)
|
||||
{
|
||||
return ftruncate(fd, 60);
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
fstat_badfd(int fd)
|
||||
{
|
||||
struct stat sb;
|
||||
return fstat(fd, &sb);
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
getdirentry_badfd(int fd)
|
||||
{
|
||||
char buf[32];
|
||||
return getdirentry(fd, buf, sizeof(buf));
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
dup2_badfd(int fd)
|
||||
{
|
||||
/* use the +1 to avoid doing dup2(CLOSED_FD, CLOSED_FD) */
|
||||
return dup2(fd, CLOSED_FD+1);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
dup2_cleanup(void)
|
||||
{
|
||||
close(CLOSED_FD+1);
|
||||
}
|
||||
static void dup2_cleanup(void) { close(CLOSED_FD + 1); }
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
static
|
||||
void
|
||||
any_badfd(int (*func)(int fd), void (*cleanup)(void), const char *callname,
|
||||
int fd, const char *fddesc)
|
||||
{
|
||||
int rv;
|
||||
static void any_badfd(int (*func)(int fd), void (*cleanup)(void),
|
||||
const char *callname, int fd, const char *fddesc) {
|
||||
int rv;
|
||||
|
||||
report_begin("%s using %s", callname, fddesc);
|
||||
rv = func(fd);
|
||||
report_check(rv, errno, EBADF);
|
||||
if (cleanup) {
|
||||
cleanup();
|
||||
}
|
||||
report_begin("%s using %s", callname, fddesc);
|
||||
rv = func(fd);
|
||||
report_check(rv, errno, EBADF);
|
||||
if (cleanup) {
|
||||
cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
runtest(int (*func)(int fd), void (*cleanup)(void), const char *callname,
|
||||
enum rwtestmodes rw)
|
||||
{
|
||||
int fd;
|
||||
static void runtest(int (*func)(int fd), void (*cleanup)(void),
|
||||
const char *callname, enum rwtestmodes rw) {
|
||||
int fd;
|
||||
|
||||
/*
|
||||
* If adding cases, also see bad_dup2.c
|
||||
*/
|
||||
/*
|
||||
* If adding cases, also see bad_dup2.c
|
||||
*/
|
||||
|
||||
/* basic invalid case: fd -1 */
|
||||
any_badfd(func, cleanup, callname, -1, "fd -1");
|
||||
/* basic invalid case: fd -1 */
|
||||
any_badfd(func, cleanup, callname, -1, "fd -1");
|
||||
|
||||
/* also try -5 in case -1 is special somehow */
|
||||
any_badfd(func, cleanup, callname, -5, "fd -5");
|
||||
/* also try -5 in case -1 is special somehow */
|
||||
any_badfd(func, cleanup, callname, -5, "fd -5");
|
||||
|
||||
/* try a fd we know is closed */
|
||||
any_badfd(func, cleanup, callname, CLOSED_FD, "closed fd");
|
||||
/* try a fd we know is closed */
|
||||
any_badfd(func, cleanup, callname, CLOSED_FD, "closed fd");
|
||||
|
||||
/* try a positive fd we know is out of range */
|
||||
any_badfd(func, cleanup, callname, IMPOSSIBLE_FD, "impossible fd");
|
||||
/* try a positive fd we know is out of range */
|
||||
any_badfd(func, cleanup, callname, IMPOSSIBLE_FD, "impossible fd");
|
||||
|
||||
/* test for off-by-one errors */
|
||||
/* test for off-by-one errors */
|
||||
#ifdef OPEN_MAX
|
||||
any_badfd(func, cleanup, callname, OPEN_MAX, "fd OPEN_MAX");
|
||||
any_badfd(func, cleanup, callname, OPEN_MAX, "fd OPEN_MAX");
|
||||
#else
|
||||
warnx("Warning: OPEN_MAX not defined, test skipped");
|
||||
warnx("Warning: OPEN_MAX not defined, test skipped");
|
||||
#endif
|
||||
|
||||
if (rw == RW_TEST_RDONLY) {
|
||||
fd = reopen_testfile(O_RDONLY|O_CREAT);
|
||||
if (fd < 0) {
|
||||
/* already printed a message */
|
||||
}
|
||||
else {
|
||||
any_badfd(func, cleanup, callname, fd,
|
||||
"fd opened read-only");
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
if (rw == RW_TEST_WRONLY) {
|
||||
fd = reopen_testfile(O_WRONLY|O_CREAT);
|
||||
if (fd < 0) {
|
||||
/* already printed a message */
|
||||
}
|
||||
else {
|
||||
any_badfd(func, cleanup, callname, fd,
|
||||
"fd opened write-only");
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
if (rw == RW_TEST_RDONLY) {
|
||||
fd = reopen_testfile(O_RDONLY | O_CREAT);
|
||||
if (fd < 0) {
|
||||
/* already printed a message */
|
||||
} else {
|
||||
any_badfd(func, cleanup, callname, fd, "fd opened read-only");
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
if (rw == RW_TEST_WRONLY) {
|
||||
fd = reopen_testfile(O_WRONLY | O_CREAT);
|
||||
if (fd < 0) {
|
||||
/* already printed a message */
|
||||
} else {
|
||||
any_badfd(func, cleanup, callname, fd, "fd opened write-only");
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
#define T(call, rw) \
|
||||
void \
|
||||
test_##call##_fd(void) \
|
||||
{ \
|
||||
runtest(call##_badfd, NULL, #call, rw); \
|
||||
}
|
||||
#define T(call, rw) \
|
||||
void test_##call##_fd(void) { runtest(call##_badfd, NULL, #call, rw); }
|
||||
|
||||
#define TC(call, rw) \
|
||||
void \
|
||||
test_##call##_fd(void) \
|
||||
{ \
|
||||
runtest(call##_badfd, call##_cleanup, #call, rw);\
|
||||
#define TC(call, rw) \
|
||||
void test_##call##_fd(void) { \
|
||||
runtest(call##_badfd, call##_cleanup, #call, rw); \
|
||||
}
|
||||
|
||||
T(read, RW_TEST_WRONLY);
|
||||
|
||||
@@ -44,151 +44,83 @@
|
||||
#include "config.h"
|
||||
#include "test.h"
|
||||
|
||||
static
|
||||
int
|
||||
open_badpath(const char *path)
|
||||
{
|
||||
return open(path, O_RDONLY);
|
||||
static int open_badpath(const char *path) { return open(path, O_RDONLY); }
|
||||
|
||||
static int remove_badpath(const char *path) { return remove(path); }
|
||||
|
||||
static int rename_badpath1(const char *path) { return rename(path, TESTFILE); }
|
||||
|
||||
static int rename_badpath2(const char *path) { return rename(TESTFILE, path); }
|
||||
|
||||
static int link_badpath1(const char *path) { return link(path, TESTFILE); }
|
||||
|
||||
static int link_badpath2(const char *path) { return link(TESTFILE, path); }
|
||||
|
||||
static int mkdir_badpath(const char *path) { return mkdir(path, 0775); }
|
||||
|
||||
static int rmdir_badpath(const char *path) { return rmdir(path); }
|
||||
|
||||
static int chdir_badpath(const char *path) { return chdir(path); }
|
||||
|
||||
static int symlink_badpath1(const char *path) {
|
||||
return symlink(path, TESTFILE);
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
remove_badpath(const char *path)
|
||||
{
|
||||
return remove(path);
|
||||
static int symlink_badpath2(const char *path) {
|
||||
return symlink(TESTFILE, path);
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
rename_badpath1(const char *path)
|
||||
{
|
||||
return rename(path, TESTFILE);
|
||||
static int readlink_badpath(const char *path) {
|
||||
char buf[128];
|
||||
return readlink(path, buf, sizeof(buf));
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
rename_badpath2(const char *path)
|
||||
{
|
||||
return rename(TESTFILE, path);
|
||||
static int lstat_badpath(const char *name) {
|
||||
struct stat sb;
|
||||
return lstat(name, &sb);
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
link_badpath1(const char *path)
|
||||
{
|
||||
return link(path, TESTFILE);
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
link_badpath2(const char *path)
|
||||
{
|
||||
return link(TESTFILE, path);
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
mkdir_badpath(const char *path)
|
||||
{
|
||||
return mkdir(path, 0775);
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
rmdir_badpath(const char *path)
|
||||
{
|
||||
return rmdir(path);
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
chdir_badpath(const char *path)
|
||||
{
|
||||
return chdir(path);
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
symlink_badpath1(const char *path)
|
||||
{
|
||||
return symlink(path, TESTFILE);
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
symlink_badpath2(const char *path)
|
||||
{
|
||||
return symlink(TESTFILE, path);
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
readlink_badpath(const char *path)
|
||||
{
|
||||
char buf[128];
|
||||
return readlink(path, buf, sizeof(buf));
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
lstat_badpath(const char *name)
|
||||
{
|
||||
struct stat sb;
|
||||
return lstat(name, &sb);
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
stat_badpath(const char *name)
|
||||
{
|
||||
struct stat sb;
|
||||
return stat(name, &sb);
|
||||
static int stat_badpath(const char *name) {
|
||||
struct stat sb;
|
||||
return stat(name, &sb);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
static
|
||||
void
|
||||
common_badpath(int (*func)(const char *path), int mk, int rm, const char *path,
|
||||
const char *call, const char *pathdesc)
|
||||
{
|
||||
int rv;
|
||||
static void common_badpath(int (*func)(const char *path), int mk, int rm,
|
||||
const char *path, const char *call,
|
||||
const char *pathdesc) {
|
||||
int rv;
|
||||
|
||||
report_begin("%s with %s path", call, pathdesc);
|
||||
report_begin("%s with %s path", call, pathdesc);
|
||||
|
||||
if (mk) {
|
||||
if (create_testfile()<0) {
|
||||
report_aborted();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (mk) {
|
||||
if (create_testfile() < 0) {
|
||||
report_aborted();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
rv = func(path);
|
||||
report_check(rv, errno, EFAULT);
|
||||
rv = func(path);
|
||||
report_check(rv, errno, EFAULT);
|
||||
|
||||
if (mk || rm) {
|
||||
remove(TESTFILE);
|
||||
}
|
||||
if (mk || rm) {
|
||||
remove(TESTFILE);
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
any_badpath(int (*func)(const char *path), const char *call, int mk, int rm)
|
||||
{
|
||||
common_badpath(func, mk, rm, NULL, call, "NULL");
|
||||
common_badpath(func, mk, rm, INVAL_PTR, call, "invalid-pointer");
|
||||
common_badpath(func, mk, rm, KERN_PTR, call, "kernel-pointer");
|
||||
static void any_badpath(int (*func)(const char *path), const char *call, int mk,
|
||||
int rm) {
|
||||
common_badpath(func, mk, rm, NULL, call, "NULL");
|
||||
common_badpath(func, mk, rm, INVAL_PTR, call, "invalid-pointer");
|
||||
common_badpath(func, mk, rm, KERN_PTR, call, "kernel-pointer");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
/* functions with one pathname */
|
||||
#define T(call) \
|
||||
void \
|
||||
test_##call##_path(void) \
|
||||
{ \
|
||||
any_badpath(call##_badpath, #call, 0, 0); \
|
||||
}
|
||||
#define T(call) \
|
||||
void test_##call##_path(void) { any_badpath(call##_badpath, #call, 0, 0); }
|
||||
|
||||
T(open);
|
||||
T(remove);
|
||||
@@ -200,12 +132,10 @@ T(stat);
|
||||
T(lstat);
|
||||
|
||||
/* functions with two pathnames */
|
||||
#define T2(call) \
|
||||
void \
|
||||
test_##call##_paths(void) \
|
||||
{ \
|
||||
any_badpath(call##_badpath1, #call "(arg1)", 0, 1); \
|
||||
any_badpath(call##_badpath2, #call "(arg2)", 1, 1); \
|
||||
#define T2(call) \
|
||||
void test_##call##_paths(void) { \
|
||||
any_badpath(call##_badpath1, #call "(arg1)", 0, 1); \
|
||||
any_badpath(call##_badpath2, #call "(arg2)", 1, 1); \
|
||||
}
|
||||
|
||||
T2(rename);
|
||||
|
||||
@@ -35,8 +35,8 @@
|
||||
*/
|
||||
|
||||
#if defined(__mips__)
|
||||
#define KERN_PTR ((void *)0x80000000) /* addr within kernel */
|
||||
#define INVAL_PTR ((void *)0x40000000) /* addr not part of program */
|
||||
#define KERN_PTR ((void *)0x80000000) /* addr within kernel */
|
||||
#define INVAL_PTR ((void *)0x40000000) /* addr not part of program */
|
||||
#else
|
||||
#error "Please fix this"
|
||||
#endif
|
||||
@@ -45,16 +45,16 @@
|
||||
* We assume CLOSED_FD is a legal fd that won't be open when we're running.
|
||||
* CLOSED_FD+1 should also be legal and not open.
|
||||
*/
|
||||
#define CLOSED_FD 10
|
||||
#define CLOSED_FD 10
|
||||
|
||||
/* We assume IMPOSSIBLE_FD is a fd that is completely not allowed. */
|
||||
#define IMPOSSIBLE_FD 1234567890
|
||||
#define IMPOSSIBLE_FD 1234567890
|
||||
|
||||
/* We assume this pid won't exist while we're running. Change as needed. */
|
||||
#define NONEXIST_PID 34000
|
||||
#define NONEXIST_PID 34000
|
||||
|
||||
/* An arbitrary process exit code that hopefully won't occur by accident */
|
||||
#define MAGIC_STATUS 107
|
||||
#define MAGIC_STATUS 107
|
||||
|
||||
/* An ioctl that doesn't exist */
|
||||
#define NONEXIST_IOCTL 12345
|
||||
#define NONEXIST_IOCTL 12345
|
||||
|
||||
@@ -42,74 +42,68 @@
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
int
|
||||
open_testfile(const char *string)
|
||||
{
|
||||
int fd, rv;
|
||||
size_t len;
|
||||
int open_testfile(const char *string) {
|
||||
int fd, rv;
|
||||
size_t len;
|
||||
|
||||
fd = open(TESTFILE, O_RDWR|O_CREAT|O_TRUNC, 0664);
|
||||
if (fd<0) {
|
||||
report_warn("creating %s: failed", TESTFILE);
|
||||
return -1;
|
||||
}
|
||||
fd = open(TESTFILE, O_RDWR | O_CREAT | O_TRUNC, 0664);
|
||||
if (fd < 0) {
|
||||
report_warn("creating %s: failed", TESTFILE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (string) {
|
||||
len = strlen(string);
|
||||
rv = write(fd, string, len);
|
||||
if (rv<0) {
|
||||
report_warn("write to %s failed", TESTFILE);
|
||||
close(fd);
|
||||
remove(TESTFILE);
|
||||
return -1;
|
||||
}
|
||||
if ((unsigned)rv != len) {
|
||||
report_warn("write to %s got short count", TESTFILE);
|
||||
close(fd);
|
||||
remove(TESTFILE);
|
||||
return -1;
|
||||
}
|
||||
rv = lseek(fd, 0, SEEK_SET);
|
||||
if (rv<0) {
|
||||
report_warn("rewind of %s failed", TESTFILE);
|
||||
close(fd);
|
||||
remove(TESTFILE);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return fd;
|
||||
if (string) {
|
||||
len = strlen(string);
|
||||
rv = write(fd, string, len);
|
||||
if (rv < 0) {
|
||||
report_warn("write to %s failed", TESTFILE);
|
||||
close(fd);
|
||||
remove(TESTFILE);
|
||||
return -1;
|
||||
}
|
||||
if ((unsigned)rv != len) {
|
||||
report_warn("write to %s got short count", TESTFILE);
|
||||
close(fd);
|
||||
remove(TESTFILE);
|
||||
return -1;
|
||||
}
|
||||
rv = lseek(fd, 0, SEEK_SET);
|
||||
if (rv < 0) {
|
||||
report_warn("rewind of %s failed", TESTFILE);
|
||||
close(fd);
|
||||
remove(TESTFILE);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
int
|
||||
create_testfile(void)
|
||||
{
|
||||
int fd, rv;
|
||||
int create_testfile(void) {
|
||||
int fd, rv;
|
||||
|
||||
fd = open_testfile(NULL);
|
||||
if (fd<0) {
|
||||
return -1;
|
||||
}
|
||||
fd = open_testfile(NULL);
|
||||
if (fd < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
rv = close(fd);
|
||||
if (rv<0) {
|
||||
report_warn("closing %s failed", TESTFILE);
|
||||
return -1;
|
||||
}
|
||||
rv = close(fd);
|
||||
if (rv < 0) {
|
||||
report_warn("closing %s failed", TESTFILE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
reopen_testfile(int openflags)
|
||||
{
|
||||
int fd;
|
||||
int reopen_testfile(int openflags) {
|
||||
int fd;
|
||||
|
||||
fd = open(TESTFILE, openflags, 0664);
|
||||
if (fd < 0) {
|
||||
report_warn("reopening %s: failed", TESTFILE);
|
||||
return -1;
|
||||
}
|
||||
return fd;
|
||||
fd = open(TESTFILE, openflags, 0664);
|
||||
if (fd < 0) {
|
||||
report_warn("reopening %s: failed", TESTFILE);
|
||||
return -1;
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -117,173 +111,155 @@ reopen_testfile(int openflags)
|
||||
* otherwise it has to communicate to the caller which to call and
|
||||
* that's a pain.
|
||||
*/
|
||||
int
|
||||
create_testdir(void)
|
||||
{
|
||||
int rv;
|
||||
rv = mkdir(TESTDIR, 0775);
|
||||
if (rv<0) {
|
||||
if (errno == ENOSYS) {
|
||||
report_saw_enosys();
|
||||
report_warnx("mkdir unimplemented; cannot run test");
|
||||
report_skipped();
|
||||
}
|
||||
else {
|
||||
report_warn("mkdir %s failed", TESTDIR);
|
||||
report_aborted();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
int create_testdir(void) {
|
||||
int rv;
|
||||
rv = mkdir(TESTDIR, 0775);
|
||||
if (rv < 0) {
|
||||
if (errno == ENOSYS) {
|
||||
report_saw_enosys();
|
||||
report_warnx("mkdir unimplemented; cannot run test");
|
||||
report_skipped();
|
||||
} else {
|
||||
report_warn("mkdir %s failed", TESTDIR);
|
||||
report_aborted();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
create_testlink(void)
|
||||
{
|
||||
int rv;
|
||||
rv = symlink("blahblah", TESTLINK);
|
||||
if (rv<0) {
|
||||
report_warn("making symlink %s failed", TESTLINK);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
int create_testlink(void) {
|
||||
int rv;
|
||||
rv = symlink("blahblah", TESTLINK);
|
||||
if (rv < 0) {
|
||||
report_warn("making symlink %s failed", TESTLINK);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
static
|
||||
struct {
|
||||
int ch;
|
||||
int asst;
|
||||
const char *name;
|
||||
void (*f)(void);
|
||||
} ops[] = {
|
||||
{ 'a', 2, "execv", test_execv },
|
||||
{ 'b', 2, "waitpid", test_waitpid },
|
||||
{ 'c', 2, "open", test_open },
|
||||
{ 'd', 2, "read", test_read },
|
||||
{ 'e', 2, "write", test_write },
|
||||
{ 'f', 2, "close", test_close },
|
||||
{ 'g', 0, "reboot", test_reboot },
|
||||
{ 'h', 3, "sbrk", test_sbrk },
|
||||
{ 'i', 5, "ioctl", test_ioctl },
|
||||
{ 'j', 2, "lseek", test_lseek },
|
||||
{ 'k', 4, "fsync", test_fsync },
|
||||
{ 'l', 4, "ftruncate", test_ftruncate },
|
||||
{ 'm', 4, "fstat", test_fstat },
|
||||
{ 'n', 4, "remove", test_remove },
|
||||
{ 'o', 4, "rename", test_rename },
|
||||
{ 'p', 5, "link", test_link },
|
||||
{ 'q', 4, "mkdir", test_mkdir },
|
||||
{ 'r', 4, "rmdir", test_rmdir },
|
||||
{ 's', 2, "chdir", test_chdir },
|
||||
{ 't', 4, "getdirentry", test_getdirentry },
|
||||
{ 'u', 5, "symlink", test_symlink },
|
||||
{ 'v', 5, "readlink", test_readlink },
|
||||
{ 'w', 2, "dup2", test_dup2 },
|
||||
{ 'x', 5, "pipe", test_pipe },
|
||||
{ 'y', 5, "__time", test_time },
|
||||
{ 'z', 2, "__getcwd", test_getcwd },
|
||||
{ '{', 5, "stat", test_stat },
|
||||
{ '|', 5, "lstat", test_lstat },
|
||||
{ 0, 0, NULL, NULL }
|
||||
};
|
||||
static struct {
|
||||
int ch;
|
||||
int asst;
|
||||
const char *name;
|
||||
void (*f)(void);
|
||||
} ops[] = {{'a', 2, "execv", test_execv},
|
||||
{'b', 2, "waitpid", test_waitpid},
|
||||
{'c', 2, "open", test_open},
|
||||
{'d', 2, "read", test_read},
|
||||
{'e', 2, "write", test_write},
|
||||
{'f', 2, "close", test_close},
|
||||
{'g', 0, "reboot", test_reboot},
|
||||
{'h', 3, "sbrk", test_sbrk},
|
||||
{'i', 5, "ioctl", test_ioctl},
|
||||
{'j', 2, "lseek", test_lseek},
|
||||
{'k', 4, "fsync", test_fsync},
|
||||
{'l', 4, "ftruncate", test_ftruncate},
|
||||
{'m', 4, "fstat", test_fstat},
|
||||
{'n', 4, "remove", test_remove},
|
||||
{'o', 4, "rename", test_rename},
|
||||
{'p', 5, "link", test_link},
|
||||
{'q', 4, "mkdir", test_mkdir},
|
||||
{'r', 4, "rmdir", test_rmdir},
|
||||
{'s', 2, "chdir", test_chdir},
|
||||
{'t', 4, "getdirentry", test_getdirentry},
|
||||
{'u', 5, "symlink", test_symlink},
|
||||
{'v', 5, "readlink", test_readlink},
|
||||
{'w', 2, "dup2", test_dup2},
|
||||
{'x', 5, "pipe", test_pipe},
|
||||
{'y', 5, "__time", test_time},
|
||||
{'z', 2, "__getcwd", test_getcwd},
|
||||
{'{', 5, "stat", test_stat},
|
||||
{'|', 5, "lstat", test_lstat},
|
||||
{0, 0, NULL, NULL}};
|
||||
|
||||
#define LOWEST 'a'
|
||||
#define LOWEST 'a'
|
||||
#define HIGHEST '|'
|
||||
|
||||
static
|
||||
void
|
||||
menu(void)
|
||||
{
|
||||
int i;
|
||||
for (i=0; ops[i].name; i++) {
|
||||
printf("[%c] %-24s", ops[i].ch, ops[i].name);
|
||||
if (i%2==1) {
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
if (i%2==1) {
|
||||
printf("\n");
|
||||
}
|
||||
printf("[1] %-24s", "asst1");
|
||||
printf("[2] %-24s\n", "asst2");
|
||||
printf("[3] %-24s", "asst3");
|
||||
printf("[4] %-24s\n", "asst4");
|
||||
printf("[*] %-24s", "all");
|
||||
printf("[!] %-24s\n", "quit");
|
||||
static void menu(void) {
|
||||
int i;
|
||||
for (i = 0; ops[i].name; i++) {
|
||||
printf("[%c] %-24s", ops[i].ch, ops[i].name);
|
||||
if (i % 2 == 1) {
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
if (i % 2 == 1) {
|
||||
printf("\n");
|
||||
}
|
||||
printf("[1] %-24s", "asst1");
|
||||
printf("[2] %-24s\n", "asst2");
|
||||
printf("[3] %-24s", "asst3");
|
||||
printf("[4] %-24s\n", "asst4");
|
||||
printf("[*] %-24s", "all");
|
||||
printf("[!] %-24s\n", "quit");
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
runit(int op)
|
||||
{
|
||||
int i, k;
|
||||
static void runit(int op) {
|
||||
int i, k;
|
||||
|
||||
if (op=='!') {
|
||||
exit(0);
|
||||
}
|
||||
if (op == '!') {
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (op=='?') {
|
||||
menu();
|
||||
return;
|
||||
}
|
||||
if (op == '?') {
|
||||
menu();
|
||||
return;
|
||||
}
|
||||
|
||||
if (op=='*') {
|
||||
for (i=0; ops[i].name; i++) {
|
||||
printf("[%s]\n", ops[i].name);
|
||||
ops[i].f();
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (op == '*') {
|
||||
for (i = 0; ops[i].name; i++) {
|
||||
printf("[%s]\n", ops[i].name);
|
||||
ops[i].f();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (op>='1' && op <= '4') {
|
||||
k = op-'0';
|
||||
for (i=0; ops[i].name; i++) {
|
||||
if (ops[i].asst <= k) {
|
||||
printf("[%s]\n", ops[i].name);
|
||||
ops[i].f();
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (op >= '1' && op <= '4') {
|
||||
k = op - '0';
|
||||
for (i = 0; ops[i].name; i++) {
|
||||
if (ops[i].asst <= k) {
|
||||
printf("[%s]\n", ops[i].name);
|
||||
ops[i].f();
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (op < LOWEST || op > HIGHEST) {
|
||||
printf("Invalid request %c\n", op);
|
||||
return;
|
||||
}
|
||||
if (op < LOWEST || op > HIGHEST) {
|
||||
printf("Invalid request %c\n", op);
|
||||
return;
|
||||
}
|
||||
|
||||
ops[op-'a'].f();
|
||||
ops[op - 'a'].f();
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int op, i, j;
|
||||
int main(int argc, char **argv) {
|
||||
int op, i, j;
|
||||
|
||||
printf("[%c-%c, 1-4, *, ?=menu, !=quit]\n", LOWEST, HIGHEST);
|
||||
printf("[%c-%c, 1-4, *, ?=menu, !=quit]\n", LOWEST, HIGHEST);
|
||||
|
||||
if (argc > 1) {
|
||||
for (i=1; i<argc; i++) {
|
||||
for (j=0; argv[i][j]; j++) {
|
||||
printf("Choose: %c\n",
|
||||
argv[i][j]);
|
||||
runit(argv[i][j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
menu();
|
||||
while (1) {
|
||||
printf("Choose: ");
|
||||
op = getchar();
|
||||
if (op==EOF) {
|
||||
break;
|
||||
}
|
||||
printf("%c\n", op);
|
||||
runit(op);
|
||||
}
|
||||
}
|
||||
if (argc > 1) {
|
||||
for (i = 1; i < argc; i++) {
|
||||
for (j = 0; argv[i][j]; j++) {
|
||||
printf("Choose: %c\n", argv[i][j]);
|
||||
runit(argv[i][j]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
menu();
|
||||
while (1) {
|
||||
printf("Choose: ");
|
||||
op = getchar();
|
||||
if (op == EOF) {
|
||||
break;
|
||||
}
|
||||
printf("%c\n", op);
|
||||
runit(op);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -58,63 +58,50 @@ static size_t outbufpos;
|
||||
/*
|
||||
* Print things.
|
||||
*/
|
||||
static
|
||||
void
|
||||
vsay(const char *fmt, va_list ap)
|
||||
{
|
||||
size_t begin, i;
|
||||
static void vsay(const char *fmt, va_list ap) {
|
||||
size_t begin, i;
|
||||
|
||||
assert(outbufpos < sizeof(outbuf));
|
||||
assert(outbufpos < sizeof(outbuf));
|
||||
|
||||
begin = outbufpos;
|
||||
vsnprintf(outbuf + outbufpos, sizeof(outbuf) - outbufpos, fmt, ap);
|
||||
outbufpos = strlen(outbuf);
|
||||
begin = outbufpos;
|
||||
vsnprintf(outbuf + outbufpos, sizeof(outbuf) - outbufpos, fmt, ap);
|
||||
outbufpos = strlen(outbuf);
|
||||
|
||||
for (i=begin; i<outbufpos; i++) {
|
||||
if (outbuf[i] == '\n') {
|
||||
horizpos = 0;
|
||||
}
|
||||
else {
|
||||
horizpos++;
|
||||
}
|
||||
}
|
||||
for (i = begin; i < outbufpos; i++) {
|
||||
if (outbuf[i] == '\n') {
|
||||
horizpos = 0;
|
||||
} else {
|
||||
horizpos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
say(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
static void say(const char *fmt, ...) {
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
vsay(fmt, ap);
|
||||
va_end(ap);
|
||||
va_start(ap, fmt);
|
||||
vsay(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
/*
|
||||
* Indent to a given horizontal position.
|
||||
*/
|
||||
static
|
||||
void
|
||||
indent_to(size_t pos)
|
||||
{
|
||||
while (horizpos < pos) {
|
||||
assert(outbufpos < sizeof(outbuf) - 1);
|
||||
outbuf[outbufpos++] = ' ';
|
||||
outbuf[outbufpos] = 0;
|
||||
horizpos++;
|
||||
}
|
||||
static void indent_to(size_t pos) {
|
||||
while (horizpos < pos) {
|
||||
assert(outbufpos < sizeof(outbuf) - 1);
|
||||
outbuf[outbufpos++] = ' ';
|
||||
outbuf[outbufpos] = 0;
|
||||
horizpos++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Flush the output.
|
||||
*/
|
||||
static
|
||||
void
|
||||
flush(void)
|
||||
{
|
||||
write(STDOUT_FILENO, outbuf, outbufpos);
|
||||
outbufpos = 0;
|
||||
static void flush(void) {
|
||||
write(STDOUT_FILENO, outbuf, outbufpos);
|
||||
outbufpos = 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
@@ -123,28 +110,24 @@ flush(void)
|
||||
* Begin a test. This flushes the description so it can be seen before
|
||||
* the test happens, in case the test explodes or deadlocks the system.
|
||||
*/
|
||||
void
|
||||
report_begin(const char *descfmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
void report_begin(const char *descfmt, ...) {
|
||||
va_list ap;
|
||||
|
||||
say("badcall: ");
|
||||
va_start(ap, descfmt);
|
||||
vsay(descfmt, ap);
|
||||
va_end(ap);
|
||||
say("... ");
|
||||
flush();
|
||||
say("badcall: ");
|
||||
va_start(ap, descfmt);
|
||||
vsay(descfmt, ap);
|
||||
va_end(ap);
|
||||
say("... ");
|
||||
flush();
|
||||
}
|
||||
|
||||
/*
|
||||
* Prepare to be able to print subreports.
|
||||
*/
|
||||
void
|
||||
report_hassubs(void)
|
||||
{
|
||||
subpos = horizpos;
|
||||
say("\n");
|
||||
flush();
|
||||
void report_hassubs(void) {
|
||||
subpos = horizpos;
|
||||
say("\n");
|
||||
flush();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -152,17 +135,15 @@ report_hassubs(void)
|
||||
* subreports are in subprocesses and we want each one to print a
|
||||
* whole line at once to avoid output interleaving.
|
||||
*/
|
||||
void
|
||||
report_beginsub(const char *descfmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
void report_beginsub(const char *descfmt, ...) {
|
||||
va_list ap;
|
||||
|
||||
assert(horizpos == 0);
|
||||
say(" ");
|
||||
va_start(ap, descfmt);
|
||||
vsay(descfmt, ap);
|
||||
va_end(ap);
|
||||
indent_to(subpos);
|
||||
assert(horizpos == 0);
|
||||
say(" ");
|
||||
va_start(ap, descfmt);
|
||||
vsay(descfmt, ap);
|
||||
va_end(ap);
|
||||
indent_to(subpos);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -170,52 +151,45 @@ report_beginsub(const char *descfmt, ...)
|
||||
* extra line for the warning. The warnx form is the same but doesn't
|
||||
* add errno.
|
||||
*/
|
||||
void
|
||||
report_warn(const char *fmt, ...)
|
||||
{
|
||||
size_t pos;
|
||||
const char *errmsg;
|
||||
va_list ap;
|
||||
void report_warn(const char *fmt, ...) {
|
||||
size_t pos;
|
||||
const char *errmsg;
|
||||
va_list ap;
|
||||
|
||||
pos = horizpos;
|
||||
errmsg = strerror(errno);
|
||||
say("\n OOPS: ");
|
||||
va_start(ap, fmt);
|
||||
vsay(fmt, ap);
|
||||
va_end(ap);
|
||||
say(": %s\n", errmsg);
|
||||
indent_to(pos);
|
||||
flush();
|
||||
pos = horizpos;
|
||||
errmsg = strerror(errno);
|
||||
say("\n OOPS: ");
|
||||
va_start(ap, fmt);
|
||||
vsay(fmt, ap);
|
||||
va_end(ap);
|
||||
say(": %s\n", errmsg);
|
||||
indent_to(pos);
|
||||
flush();
|
||||
}
|
||||
|
||||
void
|
||||
report_warnx(const char *fmt, ...)
|
||||
{
|
||||
size_t pos;
|
||||
va_list ap;
|
||||
void report_warnx(const char *fmt, ...) {
|
||||
size_t pos;
|
||||
va_list ap;
|
||||
|
||||
pos = horizpos;
|
||||
say("\n oops: ");
|
||||
va_start(ap, fmt);
|
||||
vsay(fmt, ap);
|
||||
va_end(ap);
|
||||
say("\n");
|
||||
indent_to(pos);
|
||||
flush();
|
||||
pos = horizpos;
|
||||
say("\n oops: ");
|
||||
va_start(ap, fmt);
|
||||
vsay(fmt, ap);
|
||||
va_end(ap);
|
||||
say("\n");
|
||||
indent_to(pos);
|
||||
flush();
|
||||
}
|
||||
|
||||
/*
|
||||
* Report a system call result.
|
||||
*/
|
||||
void
|
||||
report_result(int rv, int error)
|
||||
{
|
||||
if (rv == -1) {
|
||||
say("%s ", strerror(error));
|
||||
}
|
||||
else {
|
||||
say("Success ");
|
||||
}
|
||||
void report_result(int rv, int error) {
|
||||
if (rv == -1) {
|
||||
say("%s ", strerror(error));
|
||||
} else {
|
||||
say("Success ");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -227,13 +201,11 @@ report_result(int rv, int error)
|
||||
*
|
||||
* XXX this is pretty gross.
|
||||
*/
|
||||
void
|
||||
report_saw_enosys(void)
|
||||
{
|
||||
size_t pos = horizpos;
|
||||
void report_saw_enosys(void) {
|
||||
size_t pos = horizpos;
|
||||
|
||||
horizpos = 0;
|
||||
indent_to(pos);
|
||||
horizpos = 0;
|
||||
indent_to(pos);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -241,38 +213,19 @@ report_saw_enosys(void)
|
||||
* in the result column, and add the final newline.
|
||||
*/
|
||||
|
||||
static
|
||||
void
|
||||
report_end(const char *msg)
|
||||
{
|
||||
indent_to(RESULT_COLUMN);
|
||||
say("%s\n", msg);
|
||||
flush();
|
||||
static void report_end(const char *msg) {
|
||||
indent_to(RESULT_COLUMN);
|
||||
say("%s\n", msg);
|
||||
flush();
|
||||
}
|
||||
|
||||
void
|
||||
report_passed(void)
|
||||
{
|
||||
report_end("passed");
|
||||
}
|
||||
void report_passed(void) { report_end("passed"); }
|
||||
|
||||
void
|
||||
report_failure(void)
|
||||
{
|
||||
report_end("FAILURE");
|
||||
}
|
||||
void report_failure(void) { report_end("FAILURE"); }
|
||||
|
||||
void
|
||||
report_skipped(void)
|
||||
{
|
||||
report_end("------");
|
||||
}
|
||||
void report_skipped(void) { report_end("------"); }
|
||||
|
||||
void
|
||||
report_aborted(void)
|
||||
{
|
||||
report_end("ABORTED");
|
||||
}
|
||||
void report_aborted(void) { report_end("ABORTED"); }
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -282,69 +235,56 @@ report_aborted(void)
|
||||
* matches one or more expected results.
|
||||
*/
|
||||
|
||||
void
|
||||
report_survival(int rv, int error)
|
||||
{
|
||||
/* allow any error as long as we survive */
|
||||
report_result(rv, error);
|
||||
report_passed();
|
||||
void report_survival(int rv, int error) {
|
||||
/* allow any error as long as we survive */
|
||||
report_result(rv, error);
|
||||
report_passed();
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
report_checkN(int rv, int error, int *right_errors, int right_num)
|
||||
{
|
||||
int i, goterror;
|
||||
static void report_checkN(int rv, int error, int *right_errors, int right_num) {
|
||||
int i, goterror;
|
||||
|
||||
if (rv==-1) {
|
||||
goterror = error;
|
||||
}
|
||||
else {
|
||||
goterror = 0;
|
||||
}
|
||||
if (rv == -1) {
|
||||
goterror = error;
|
||||
} else {
|
||||
goterror = 0;
|
||||
}
|
||||
|
||||
for (i=0; i<right_num; i++) {
|
||||
if (goterror == right_errors[i]) {
|
||||
report_result(rv, error);
|
||||
report_passed();
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < right_num; i++) {
|
||||
if (goterror == right_errors[i]) {
|
||||
report_result(rv, error);
|
||||
report_passed();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (goterror == ENOSYS) {
|
||||
report_saw_enosys();
|
||||
say("(unimplemented) ");
|
||||
report_skipped();
|
||||
}
|
||||
else {
|
||||
report_result(rv, error);
|
||||
report_failure();
|
||||
}
|
||||
if (goterror == ENOSYS) {
|
||||
report_saw_enosys();
|
||||
say("(unimplemented) ");
|
||||
report_skipped();
|
||||
} else {
|
||||
report_result(rv, error);
|
||||
report_failure();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
report_check(int rv, int error, int right_error)
|
||||
{
|
||||
report_checkN(rv, error, &right_error, 1);
|
||||
void report_check(int rv, int error, int right_error) {
|
||||
report_checkN(rv, error, &right_error, 1);
|
||||
}
|
||||
|
||||
void
|
||||
report_check2(int rv, int error, int okerr1, int okerr2)
|
||||
{
|
||||
int ok[2];
|
||||
void report_check2(int rv, int error, int okerr1, int okerr2) {
|
||||
int ok[2];
|
||||
|
||||
ok[0] = okerr1;
|
||||
ok[1] = okerr2;
|
||||
report_checkN(rv, error, ok, 2);
|
||||
ok[0] = okerr1;
|
||||
ok[1] = okerr2;
|
||||
report_checkN(rv, error, ok, 2);
|
||||
}
|
||||
|
||||
void
|
||||
report_check3(int rv, int error, int okerr1, int okerr2, int okerr3)
|
||||
{
|
||||
int ok[3];
|
||||
void report_check3(int rv, int error, int okerr1, int okerr2, int okerr3) {
|
||||
int ok[3];
|
||||
|
||||
ok[0] = okerr1;
|
||||
ok[1] = okerr2;
|
||||
ok[2] = okerr3;
|
||||
report_checkN(rv, error, ok, 3);
|
||||
ok[0] = okerr1;
|
||||
ok[1] = okerr2;
|
||||
ok[2] = okerr3;
|
||||
report_checkN(rv, error, ok, 3);
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
*/
|
||||
|
||||
#define TESTFILE "badcallfile"
|
||||
#define TESTDIR "badcalldir"
|
||||
#define TESTDIR "badcalldir"
|
||||
#define TESTLINK "badcalllink"
|
||||
|
||||
#if defined(__clang__) || defined(__GNUC__)
|
||||
@@ -106,7 +106,7 @@ void test_ioctl(void);
|
||||
void test_lseek(void);
|
||||
void test_fsync(void);
|
||||
void test_ftruncate(void);
|
||||
void test_fstat(void); /* in bad_stat.c */
|
||||
void test_fstat(void); /* in bad_stat.c */
|
||||
void test_remove(void);
|
||||
void test_rename(void);
|
||||
void test_link(void);
|
||||
@@ -121,4 +121,4 @@ void test_pipe(void);
|
||||
void test_time(void);
|
||||
void test_getcwd(void);
|
||||
void test_stat(void);
|
||||
void test_lstat(void); /* in bad_stat.c */
|
||||
void test_lstat(void); /* in bad_stat.c */
|
||||
|
||||
Reference in New Issue
Block a user