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_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 void mkdir_dotdot(void) { int rv; report_begin("mkdir .."); rv = mkdir("..", 0775); report_check(rv, errno, EEXIST); }
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_empty(void) { int rv; report_begin("rmdir empty string"); rv = rmdir(""); report_check(rv, errno, EINVAL); }
static void rmdir_dot(void) { int rv; report_begin("rmdir ."); rv = rmdir("."); report_check(rv, errno, EINVAL); }
static int symlink_empty2(void) { int rv; report_begin("symlink named empty string"); rv = symlink("foo", ""); return 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 void pipe_badptr(void *ptr, const char *desc) { int rv; report_begin("%s", desc); rv = pipe(ptr); report_check(rv, errno, EFAULT); }
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 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 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; }
static int exec_badprog(const void *prog, const char *desc) { int rv; int result; char *args[2]; args[0] = (char *)"foo"; args[1] = NULL; if (exec_common_fork(&result) != 0) { return result; } report_begin(desc); rv = execv(prog, args); result = report_check(rv, errno, EFAULT); int code = result ? result : MAGIC_STATUS; exit(code); }
static int remove_dir(void) { int rv; int result = FAILED; report_begin("remove() on a directory"); if (create_testdir() < 0) { /*report_aborted();*/ /* XXX in create_testdir */ return result; } rv = remove(TESTDIR); result = report_check(rv, errno, EISDIR); rmdir(TESTDIR); return result; }
static int lseek_whence_inval(void) { int fd, rv; int result; report_begin("lseek with invalid whence code"); fd = open_testfile(NULL); if (fd<0) { report_aborted(&result); return result; } rv = lseek(fd, 0, 3594); result = report_check(rv, errno, EINVAL); close(fd); remove(TESTFILE); return result; }
static int lseek_fd_device(void) { int fd, rv; int result; report_begin("lseek on device"); fd = open("null:", O_RDONLY); if (fd<0) { report_warn("opening null: failed"); report_aborted(&result); return result; } rv = lseek(fd, 309, SEEK_SET); result = report_check(rv, errno, ESPIPE); close(fd); return result; }
static int lseek_loc_negative(void) { int fd, rv; int result; report_begin("lseek to negative offset"); fd = open_testfile(NULL); if (fd<0) { report_aborted(&result); return result; } rv = lseek(fd, -309, SEEK_SET); result = report_check(rv, errno, EINVAL); close(fd); remove(TESTFILE); return result; }
static int exec_onearg(void *ptr, const char *desc) { int rv; int result; char *args[3]; args[0] = (char *)"foo"; args[1] = (char *)ptr; args[2] = NULL; 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 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; int result = 0; 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(&result); return result; } else if (pid!=0) { /* parent */ rv = waitpid(pid, &status, 0); if (rv<0) { report_warn("waitpid failed"); report_aborted(&result); } if (WIFSIGNALED(status)) { report_warnx("subprocess exited with signal %d", WTERMSIG(status)); report_aborted(&result); } else if (WIFEXITED(status) && WEXITSTATUS(status) != 0) { report_warnx("subprocess exited with code %d", WEXITSTATUS(status)); report_aborted(&result); } return result; } /* child */ 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); 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); } /* blah */ report_skipped(&result); rv = lseek(STDIN_FILENO, 0, SEEK_SET); report_begin("try 1: SEEK_SET"); result = report_check(rv, errno, 0); rv = lseek(STDIN_FILENO, 0, SEEK_END); report_begin("try 2: SEEK_END"); result = report_check(rv, errno, 0); remove(TESTFILE); _exit(0); }