static int exec_common_fork(int *result) { 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. */ pid = fork(); if (pid<0) { err = errno; report_begin("forking for test"); report_result(pid, err); report_aborted(result); return -1; } 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(result); return -1; } if (WIFEXITED(status) && WEXITSTATUS(status) == MAGIC_STATUS) { *result = SUCCESS; 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(result); return -1; }
static int wait_unaligned(void) { pid_t pid, rv; int x; int status[2]; /* will have integer alignment */ char *ptr; int result; report_begin("wait with unaligned status"); pid = fork(); if (pid<0) { report_warn("fork failed"); report_aborted(&result); return result; } if (pid==0) { exit(0); } /* start with proper integer alignment */ ptr = (char *)(&status[0]); /* generate improper alignment on platforms with restrictions */ ptr++; rv = waitpid(pid, (int *)ptr, 0); report_survival(rv, errno, &result); if (rv<0) { waitpid(pid, &x, 0); } return result; }
static int wait_badflags(void) { pid_t pid, rv; int x; int result; report_begin("wait with bad flags"); pid = fork(); if (pid<0) { report_warn("fork failed"); report_aborted(&result); return result; } if (pid==0) { exit(0); } rv = waitpid(pid, &x, 309429); result = report_check(rv, errno, EINVAL); waitpid(pid, &x, 0); return result; }
static int wait_parent(void) { pid_t mypid, childpid, rv; int x; int result; report_begin("wait for parent"); report_hassubs(); mypid = getpid(); childpid = fork(); if (childpid<0) { report_warn("can't fork"); report_aborted(&result); return result; } if (childpid==0) { /* Child. Wait for parent. */ rv = waitpid(mypid, &x, 0); report_beginsub("from child:"); report_survival(rv, errno, &result); _exit(0); } rv = waitpid(mypid, &x, 0); report_beginsub("from parent:"); report_survival(rv, errno, &result); return result; }
static int wait_nullstatus(void) { pid_t pid, rv; int x; int result; report_begin("wait with NULL status"); pid = fork(); if (pid<0) { report_warn("fork failed"); report_aborted(&result); return result; } if (pid==0) { exit(0); } /* POSIX explicitly says passing NULL for status is allowed */ rv = waitpid(pid, NULL, 0); result = report_check(rv, errno, 0); waitpid(pid, &x, 0); return result; }
static int wait_badstatus(void *ptr, const char *desc) { pid_t pid, rv; int x; int result; report_begin(desc); pid = fork(); if (pid<0) { report_warn("fork failed"); report_aborted(&result); return result; } if (pid==0) { exit(0); } rv = waitpid(pid, ptr, 0); result = report_check(rv, errno, EFAULT); waitpid(pid, &x, 0); return result; }
static int remove_dotdot(void) { int rv; report_begin("remove() on .."); rv = remove(".."); return report_check2(rv, errno, EISDIR, EINVAL); }
static int remove_empty(void) { int rv; report_begin("remove() on empty string"); rv = remove(""); return report_check2(rv, errno, EISDIR, EINVAL); }
static void pipe_badptr(void *ptr, const char *desc) { int rv; report_begin("%s", desc); rv = pipe(ptr); report_check(rv, errno, EFAULT); }
static int symlink_empty2(void) { int rv; report_begin("symlink named empty string"); rv = symlink("foo", ""); return report_check(rv, errno, EINVAL); }
static int link_empty1(void) { int rv; report_begin("hard link of empty string"); rv = link("", TESTDIR); return report_check(rv, errno, EINVAL); }
static void mkdir_empty(void) { int rv; report_begin("mkdir of empty string"); rv = mkdir("", 0775); report_check(rv, errno, EINVAL); }
static void rmdir_dotdot(void) { int rv; report_begin("rmdir .."); rv = rmdir(".."); report_check2(rv, errno, EINVAL, ENOTEMPTY); }
static void rmdir_dot(void) { int rv; report_begin("rmdir ."); rv = rmdir("."); report_check(rv, errno, EINVAL); }
static int open_badflags(void) { int fd; report_begin("open null: with bad flags"); fd = open("null:", 309842); return report_check(fd, errno, EINVAL); }
static int sbrk_unalignedpos(void) { int result; report_begin("sbrk unaligned positive"); result = try_sbrk(17); return report_check2(result, errno, 0, EINVAL); }
static void mkdir_dotdot(void) { int rv; report_begin("mkdir .."); rv = mkdir("..", 0775); report_check(rv, errno, EEXIST); }
static void rmdir_empty(void) { int rv; report_begin("rmdir empty string"); rv = rmdir(""); report_check(rv, errno, EINVAL); }
static int enforce_sbrk(long val, const char *desc, int err) { int result; report_begin("sbrk %s", desc); result = try_sbrk(val); return report_check(result, errno, err); }
static int ioctl_badcode(void) { int rv; int result; report_begin("invalid ioctl"); rv = ioctl(STDIN_FILENO, NONEXIST_IOCTL, NULL); result = report_check(rv, errno, EIOCTL); return result; }
static int one_ioctl_badbuf(int fd, int code, const char *codename, void *ptr, const char *ptrdesc) { int rv; int result; report_begin("ioctl %s with %s", codename, ptrdesc); rv = ioctl(fd, code, ptr); result = report_check(rv, errno, EFAULT); return result; }
static int symlink_empty1(void) { int rv; int result; report_begin("symlink -> empty string"); rv = symlink("", TESTLINK); result = report_check2(rv, errno, 0, EINVAL); remove(TESTLINK); return result; }
static int wait_self(void) { pid_t rv; int x; int result; report_begin("wait for self"); rv = waitpid(getpid(), &x, 0); report_survival(rv, errno, &result); return result; }
static void chdir_empty(void) { int rv; /* * This is actually valid by some interpretations. */ report_begin("chdir to empty string"); rv = chdir(""); report_check2(rv, errno, EINVAL, 0); }
static int open_empty(void) { int rv; int result; report_begin("open empty string"); rv = open("", O_RDONLY); result = report_check2(rv, errno, 0, EINVAL); if (rv>=0) { close(rv); } return result; }
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); }
static void pipe_unaligned(void) { int fds[3], rv; char *ptr; report_begin("pipe with unaligned pointer"); ptr = (char *)&fds[0]; ptr++; rv = pipe((int *)ptr); report_survival(rv, errno); }
static int exec_badargs(void *args, const char *desc) { int rv; int result; if (exec_common_fork(&result) != 0) { return result; } report_begin(desc); rv = execv("/bin/true", args); result = report_check(rv, errno, EFAULT); int code = result ? result : MAGIC_STATUS; exit(code); }
static int link_dir(void) { int rv; int result; report_begin("hard link of ."); rv = link(".", TESTDIR); result = report_check(rv, errno, EINVAL); if (rv==0) { /* this might help recover... maybe */ remove(TESTDIR); } return result; }
static int link_empty2(void) { int rv; int result = FAILED; report_begin("hard link to empty string"); if (create_testdir()<0) { /*report_aborted();*/ /* XXX in create_testdir */ return result; } rv = link(TESTDIR, ""); result = report_check(rv, errno, EINVAL); rmdir(TESTDIR); return result; }