Module Name: src Committed By: christos Date: Sat Nov 20 14:28:29 UTC 2021
Modified Files: src/tests/lib/libc/gen/posix_spawn: t_spawn.c Log Message: Merge common code for the chdir cases (Piyush Sachdeva) I also deduplicated some more code To generate a diff of this commit: cvs rdiff -u -r1.5 -r1.6 src/tests/lib/libc/gen/posix_spawn/t_spawn.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/tests/lib/libc/gen/posix_spawn/t_spawn.c diff -u src/tests/lib/libc/gen/posix_spawn/t_spawn.c:1.5 src/tests/lib/libc/gen/posix_spawn/t_spawn.c:1.6 --- src/tests/lib/libc/gen/posix_spawn/t_spawn.c:1.5 Mon Nov 15 08:59:16 2021 +++ src/tests/lib/libc/gen/posix_spawn/t_spawn.c Sat Nov 20 09:28:29 2021 @@ -1,7 +1,7 @@ -/* $NetBSD: t_spawn.c,v 1.5 2021/11/15 13:59:16 christos Exp $ */ +/* $NetBSD: t_spawn.c,v 1.6 2021/11/20 14:28:29 christos Exp $ */ /*- - * Copyright (c) 2012 The NetBSD Foundation, Inc. + * Copyright (c) 2012, 2021 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation @@ -30,7 +30,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ #include <sys/cdefs.h> -__RCSID("$NetBSD: t_spawn.c,v 1.5 2021/11/15 13:59:16 christos Exp $"); +__RCSID("$NetBSD: t_spawn.c,v 1.6 2021/11/20 14:28:29 christos Exp $"); #include <atf-c.h> @@ -87,6 +87,20 @@ ATF_TC_BODY(t_spawnp_ls, tc) ATF_REQUIRE(err == 0); } +static void +spawn_error(const atf_tc_t *tc, const char *name, int error) +{ + char buf[FILENAME_MAX]; + char * const args[] = { __UNCONST(name), NULL }; + int err; + + snprintf(buf, sizeof buf, "%s/%s", + atf_tc_get_config_var(tc, "srcdir"), name); + err = posix_spawn(NULL, buf, NULL, NULL, args, NULL); + ATF_REQUIRE_MSG(err == error, "expected error %d, " + "got %d when spawning %s", error, err, buf); +} + ATF_TC(t_spawn_zero); ATF_TC_HEAD(t_spawn_zero, tc) @@ -97,13 +111,7 @@ ATF_TC_HEAD(t_spawn_zero, tc) ATF_TC_BODY(t_spawn_zero, tc) { - char buf[FILENAME_MAX]; - char * const args[] = { __UNCONST("h_zero"), NULL }; - int err; - - snprintf(buf, sizeof buf, "%s/h_zero", atf_tc_get_config_var(tc, "srcdir")); - err = posix_spawn(NULL, buf, NULL, NULL, args, NULL); - ATF_REQUIRE_MSG(err == ENOEXEC, "expected error %d, got %d when spawning %s", ENOEXEC, err, buf); + spawn_error(tc, "h_zero", ENOEXEC); } ATF_TC(t_spawn_missing); @@ -116,14 +124,7 @@ ATF_TC_HEAD(t_spawn_missing, tc) ATF_TC_BODY(t_spawn_missing, tc) { - char buf[FILENAME_MAX]; - char * const args[] = { __UNCONST("h_nonexist"), NULL }; - int err; - - snprintf(buf, sizeof buf, "%s/h_nonexist", - atf_tc_get_config_var(tc, "srcdir")); - err = posix_spawn(NULL, buf, NULL, NULL, args, NULL); - ATF_REQUIRE_MSG(err == ENOENT, "expected error %d, got %d when spawning %s", ENOENT, err, buf); + spawn_error(tc, "h_nonexist", ENOENT); } ATF_TC(t_spawn_nonexec); @@ -136,14 +137,7 @@ ATF_TC_HEAD(t_spawn_nonexec, tc) ATF_TC_BODY(t_spawn_nonexec, tc) { - char buf[FILENAME_MAX]; - char * const args[] = { __UNCONST("h_nonexec"), NULL }; - int err; - - snprintf(buf, sizeof buf, "%s/h_nonexec", - atf_tc_get_config_var(tc, "srcdir")); - err = posix_spawn(NULL, buf, NULL, NULL, args, NULL); - ATF_REQUIRE_MSG(err == ENOENT, "expected error %d, got %d when spawning %s", ENOENT, err, buf); + spawn_error(tc, "h_nonexec", ENOENT); } ATF_TC(t_spawn_child); @@ -157,38 +151,33 @@ ATF_TC_HEAD(t_spawn_child, tc) ATF_TC_BODY(t_spawn_child, tc) { char buf[FILENAME_MAX]; - char * const args0[] = { __UNCONST("h_spawn"), __UNCONST("0"), NULL }; - char * const args1[] = { __UNCONST("h_spawn"), __UNCONST("1"), NULL }; - char * const args7[] = { __UNCONST("h_spawn"), __UNCONST("7"), NULL }; + char rv[2] = { '0', '\0' }; + char * const args0[] = { __UNCONST("h_spawn"), rv, NULL }; + int rets[] = { 0, 1, 7 }; int err, status; pid_t pid; snprintf(buf, sizeof buf, "%s/h_spawn", atf_tc_get_config_var(tc, "srcdir")); - err = posix_spawn(&pid, buf, NULL, NULL, args0, NULL); - ATF_REQUIRE(err == 0); - ATF_REQUIRE(pid > 0); - waitpid(pid, &status, 0); - ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == 0); - - err = posix_spawn(&pid, buf, NULL, NULL, args1, NULL); - ATF_REQUIRE(err == 0); - ATF_REQUIRE(pid > 0); - waitpid(pid, &status, 0); - ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == 1); - - err = posix_spawn(&pid, buf, NULL, NULL, args7, NULL); - ATF_REQUIRE(err == 0); - ATF_REQUIRE(pid > 0); - waitpid(pid, &status, 0); - ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == 7); + for (size_t i = 0; i < __arraycount(rets); i++) { + rv[0] = rets[i] + '0'; + err = posix_spawn(&pid, buf, NULL, NULL, args0, NULL); + ATF_REQUIRE(err == 0); + ATF_REQUIRE(pid > 0); + waitpid(pid, &status, 0); + ATF_REQUIRE(WIFEXITED(status) && + WEXITSTATUS(status) == rets[i]); + } } #define CHDIRPATH "/tmp" #define FILENAME "output" #define FILEPATH "/tmp/output" +#define CHDIR 1 +#define FCHDIR 2 + static void check_success(const char *file, int argc, ...) { @@ -216,14 +205,15 @@ check_success(const char *file, int argc dir = CHDIRPATH; fd = open(file, O_RDONLY); - ATF_REQUIRE_MSG(fd != -1, "Can't open `%s' (%s)", file, strerror(errno)); + ATF_REQUIRE_MSG(fd != -1, "Can't open `%s' (%s)", file, + strerror(errno)); /* * file contains form feed i.e ASCII - 10 at the end. * Therefore sizeOfFile - 1 */ sizeOfStr = strlen(dir); - ATF_CHECK_MSG(sizeOfStr == sizeOfFile - 1, "%zu (%s) != %zu (%s)", + ATF_CHECK_MSG(sizeOfStr == sizeOfFile - 1, "%zu (%s) != %zu (%s)", sizeOfStr, dir, sizeOfFile - 1, file); bytesRead = read(fd, contents, sizeOfFile - 1); @@ -241,43 +231,100 @@ check_success(const char *file, int argc ATF_REQUIRE((size_t)bytesRead == sizeOfStr); } -ATF_TC(t_spawn_chdir_abs); - -ATF_TC_HEAD(t_spawn_chdir_abs, tc) -{ - atf_tc_set_md_var(tc, "descr", - "Test posix_spawn_fa_addchdir for absolute path"); - atf_tc_set_md_var(tc, "require.progs", "/bin/pwd"); -} - -ATF_TC_BODY(t_spawn_chdir_abs, tc) +static void +spawn_chdir(const char *dirpath, const char *filepath, int operation, + int expected_error) { + int error, fd=-1, status; char * const args[2] = { __UNCONST("pwd"), NULL }; - int error, status; pid_t pid; + posix_spawnattr_t attr, *attr_p; posix_spawn_file_actions_t fa; - empty_outfile(FILEPATH); + if (filepath) + empty_outfile(filepath); error = posix_spawn_file_actions_init(&fa); ATF_REQUIRE(error == 0); - error = posix_spawn_file_actions_addchdir(&fa, CHDIRPATH); + switch(operation) { + case CHDIR: + error = posix_spawn_file_actions_addchdir(&fa, dirpath); + break; + + case FCHDIR: + fd = open(dirpath, O_RDONLY); + ATF_REQUIRE(fd != -1); + + error = posix_spawn_file_actions_addfchdir(&fa, fd); + break; + } ATF_REQUIRE(error == 0); - error = posix_spawn_file_actions_addopen(&fa, STDOUT_FILENO, FILENAME, - O_WRONLY, 0); - ATF_REQUIRE(error == 0); - - error = posix_spawn(&pid, "/bin/pwd", &fa, NULL, args, NULL); - ATF_REQUIRE(error == 0); + /* + * if POSIX_SPAWN_RETURNERROR is expected, then no need to open the + * file + */ + if (expected_error == 0) { + error = posix_spawn_file_actions_addopen(&fa, STDOUT_FILENO, + FILENAME, O_WRONLY, 0); + ATF_REQUIRE(error == 0); + attr_p = NULL; + } else { + error = posix_spawnattr_init(&attr); + ATF_REQUIRE(error == 0); + + /* + * POSIX_SPAWN_RETURNERROR is a NetBSD specific flag that + * will cause a "proper" return value from posix_spawn(2) + * instead of a (potential) success there and a 127 exit + * status from the child process (c.f. the non-diag variant + * of this test). + */ + error = posix_spawnattr_setflags(&attr, + POSIX_SPAWN_RETURNERROR); + ATF_REQUIRE(error == 0); + attr_p = &attr; + } + + error = posix_spawn(&pid, "/bin/pwd", &fa, attr_p, args, NULL); + ATF_REQUIRE(error == expected_error); + + /* wait for the child to finish only when no spawnattr */ + if (attr_p) { + posix_spawnattr_destroy(&attr); + } else { + waitpid(pid, &status, 0); + ATF_REQUIRE_MSG(WIFEXITED(status) && + WEXITSTATUS(status) == EXIT_SUCCESS, + "%s", "[f]chdir failed"); + } - /* wait for the child to finish */ - waitpid(pid, &status, 0); - ATF_REQUIRE_MSG(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS, - "%s", "chdir failed"); posix_spawn_file_actions_destroy(&fa); + /* + * The file incase of fchdir(), + * should be closed before reopening in 'check_success' + */ + if (fd != -1) { + error = close(fd); + ATF_REQUIRE(error == 0); + } +} + +ATF_TC(t_spawn_chdir_abs); + +ATF_TC_HEAD(t_spawn_chdir_abs, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test posix_spawn_fa_addchdir for absolute path"); + atf_tc_set_md_var(tc, "require.progs", "/bin/pwd"); +} + +ATF_TC_BODY(t_spawn_chdir_abs, tc) +{ + spawn_chdir(CHDIRPATH, FILEPATH, 1, 0); + /* finally cross check the output of "pwd" directory */ check_success(FILEPATH, 0); } @@ -294,21 +341,18 @@ ATF_TC_HEAD(t_spawn_chdir_rel, tc) ATF_TC_BODY(t_spawn_chdir_rel, tc) { + int error; const char *relative_dir = "ch-dir"; const char *testdir = getcwd(NULL, 0); - char * const args[2] = { __UNCONST("pwd"), NULL }; char *chdirwd, *filepath; - int error, status; - pid_t pid; - posix_spawn_file_actions_t fa; /* cleanup previous */ error = asprintf(&filepath, "%s/%s", relative_dir, FILENAME); ATF_CHECK(error != -1); unlink(filepath); free(filepath); - rmdir(relative_dir); + rmdir(relative_dir); error = mkdir(relative_dir, 0777); ATF_REQUIRE_MSG(error == 0, "mkdir `%s' (%s)", relative_dir, strerror(errno)); @@ -325,33 +369,12 @@ ATF_TC_BODY(t_spawn_chdir_rel, tc) printf("filepath: %s\n", filepath); #endif - empty_outfile(filepath); - - error = posix_spawn_file_actions_init(&fa); - ATF_REQUIRE(error == 0); - - error = posix_spawn_file_actions_addchdir(&fa, relative_dir); - ATF_REQUIRE(error == 0); - - error = posix_spawn_file_actions_addopen(&fa, STDOUT_FILENO, FILENAME, - O_WRONLY, 0); - ATF_REQUIRE(error == 0); - - error = posix_spawn(&pid, "/bin/pwd", &fa, NULL, args, NULL); - ATF_REQUIRE(error == 0); - - /* wait for the child to finish */ - waitpid(pid, &status, 0); - ATF_REQUIRE_MSG(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS, - "%s", "chdir failed"); - posix_spawn_file_actions_destroy(&fa); + spawn_chdir(relative_dir, filepath, 1, 0); /* finally cross check the directory */ check_success(filepath, 1, chdirwd); free(chdirwd); free(filepath); - - rmdir(relative_dir); } ATF_TC(t_spawn_chdir_file); @@ -365,37 +388,7 @@ ATF_TC_HEAD(t_spawn_chdir_file, tc) ATF_TC_BODY(t_spawn_chdir_file, tc) { - int error; - pid_t pid; - char * const args[2] = { __UNCONST("pwd"), NULL }; - posix_spawnattr_t attr; - posix_spawn_file_actions_t fa; - - empty_outfile(FILEPATH); - - error = posix_spawnattr_init(&attr); - ATF_REQUIRE(error == 0); - /* - * POSIX_SPAWN_RETURNERROR is a NetBSD specific flag that - * will cause a "proper" return value from posix_spawn(2) - * instead of a (potential) success there and a 127 exit - * status from the child process (c.f. the non-diag variant - * of this test). - */ - error = posix_spawnattr_setflags(&attr, POSIX_SPAWN_RETURNERROR); - ATF_REQUIRE(error == 0); - - error = posix_spawn_file_actions_init(&fa); - ATF_REQUIRE(error == 0); - - error = posix_spawn_file_actions_addchdir(&fa, FILEPATH); - ATF_REQUIRE(error == 0); - - error = posix_spawn(&pid, "/bin/pwd", &fa, &attr, args, NULL); - ATF_REQUIRE(error == ENOTDIR); - - posix_spawn_file_actions_destroy(&fa); - posix_spawnattr_destroy(&attr); + spawn_chdir(FILEPATH, FILEPATH, 1, ENOTDIR); unlink(FILEPATH); } @@ -411,36 +404,8 @@ ATF_TC_HEAD(t_spawn_chdir_invalid, tc) ATF_TC_BODY(t_spawn_chdir_invalid, tc) { - int error; - pid_t pid; - const char *dirpath = "/not/a/valid/dir"; - char * const args[2] = { __UNCONST("pwd"), NULL }; - posix_spawnattr_t attr; - posix_spawn_file_actions_t fa; + spawn_chdir("/not/a/valid/dir", NULL, 1, ENOENT); - error = posix_spawnattr_init(&attr); - ATF_REQUIRE(error == 0); - /* - * POSIX_SPAWN_RETURNERROR is a NetBSD specific flag that - * will cause a "proper" return value from posix_spawn(2) - * instead of a (potential) success there and a 127 exit - * status from the child process (c.f. the non-diag variant - * of this test). - */ - error = posix_spawnattr_setflags(&attr, POSIX_SPAWN_RETURNERROR); - ATF_REQUIRE(error == 0); - - error = posix_spawn_file_actions_init(&fa); - ATF_REQUIRE(error == 0); - - error = posix_spawn_file_actions_addchdir(&fa, dirpath); - ATF_REQUIRE(error == 0); - - error = posix_spawn(&pid, "/bin/pwd", &fa, &attr, args, NULL); - ATF_REQUIRE(error == ENOENT); - - posix_spawn_file_actions_destroy(&fa); - posix_spawnattr_destroy(&attr); } ATF_TC(t_spawn_chdir_permissions); @@ -456,43 +421,16 @@ ATF_TC_HEAD(t_spawn_chdir_permissions, t ATF_TC_BODY(t_spawn_chdir_permissions, tc) { int error; - pid_t pid; const char *restrRelDir = "prohibited"; - char * const args[2] = { __UNCONST("pwd"), NULL }; - posix_spawnattr_t attr; - posix_spawn_file_actions_t fa; + rmdir(restrRelDir); error = mkdir(restrRelDir, 0055); ATF_REQUIRE(error == 0); - posix_spawnattr_init(&attr); - ATF_REQUIRE(error == 0); - /* - * POSIX_SPAWN_RETURNERROR is a NetBSD specific flag that - * will cause a "proper" return value from posix_spawn(2) - * instead of a (potential) success there and a 127 exit - * status from the child process (c.f. the non-diag variant - * of this test). - */ - error = posix_spawnattr_setflags(&attr, POSIX_SPAWN_RETURNERROR); - ATF_REQUIRE(error == 0); - - error = posix_spawn_file_actions_init(&fa); - ATF_REQUIRE(error == 0); - - error = posix_spawn_file_actions_addchdir(&fa, restrRelDir); - ATF_REQUIRE(error == 0); - - error = posix_spawn(&pid, "/bin/pwd", &fa, &attr, args, NULL); - ATF_CHECK(error == EACCES); - - posix_spawn_file_actions_destroy(&fa); - posix_spawnattr_destroy(&attr); - - rmdir(restrRelDir); + spawn_chdir(restrRelDir, NULL, 1, EACCES); } - + ATF_TC(t_spawn_fchdir_abs); ATF_TC_HEAD(t_spawn_fchdir_abs, tc) @@ -503,38 +441,7 @@ ATF_TC_HEAD(t_spawn_fchdir_abs, tc) ATF_TC_BODY(t_spawn_fchdir_abs, tc) { - int error, fd, status; - pid_t pid; - char * const args[2] = { __UNCONST("pwd"), NULL }; - posix_spawn_file_actions_t fa; - - empty_outfile(FILEPATH); - - fd = open(CHDIRPATH, O_RDONLY); - ATF_REQUIRE(fd != -1); - - error = posix_spawn_file_actions_init(&fa); - ATF_REQUIRE(error == 0); - - error = posix_spawn_file_actions_addfchdir(&fa, fd); - ATF_REQUIRE(error == 0); - - error = posix_spawn_file_actions_addopen(&fa, STDOUT_FILENO, FILENAME, - O_WRONLY, 0); - ATF_REQUIRE(error == 0); - - error = posix_spawn(&pid, "/bin/pwd", &fa, NULL, args, NULL); - ATF_REQUIRE(error == 0); - - /* wait for the child to finish */ - waitpid(pid, &status, 0); - ATF_REQUIRE_MSG(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS, - "%s", "chdir failed"); - posix_spawn_file_actions_destroy(&fa); - - /* The file should be closed before reopening in 'check_success' */ - error = close(fd); - ATF_REQUIRE(error == 0); + spawn_chdir(CHDIRPATH, FILEPATH, 2, 0); /* finally cross check the directory */ check_success(FILEPATH, 0); @@ -552,14 +459,12 @@ ATF_TC_HEAD(t_spawn_fchdir_rel, tc) ATF_TC_BODY(t_spawn_fchdir_rel, tc) { - int error, fd, status; - pid_t pid; + int error; const char *relative_dir = "ch-dir"; const char *testdir = getcwd(NULL, 0); - char * const args[2] = { __UNCONST("pwd"), NULL }; char *chdirwd, *filepath; - posix_spawn_file_actions_t fa; + rmdir(relative_dir); error = mkdir(relative_dir, 0755); ATF_REQUIRE(error == 0); @@ -574,39 +479,12 @@ ATF_TC_BODY(t_spawn_fchdir_rel, tc) error = asprintf(&filepath, "%s/%s", chdirwd, FILENAME); ATF_CHECK(error != -1); - empty_outfile(filepath); - - fd = open(relative_dir, O_RDONLY); - ATF_REQUIRE(fd != -1); - - error = posix_spawn_file_actions_init(&fa); - ATF_REQUIRE(error == 0); - - error = posix_spawn_file_actions_addfchdir(&fa, fd); - ATF_REQUIRE(error == 0); - - error = posix_spawn_file_actions_addopen(&fa, STDOUT_FILENO, FILENAME, - O_WRONLY, 0); - ATF_REQUIRE(error == 0); - - error = posix_spawn(&pid, "/bin/pwd", &fa, NULL, args, NULL); - ATF_REQUIRE(error == 0); - - /* wait for the child to finish */ - waitpid(pid, &status, 0); - ATF_REQUIRE_MSG(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS, - "%s", "chdir failed"); - - posix_spawn_file_actions_destroy(&fa); - - error = close(fd); - ATF_REQUIRE(error == 0); + spawn_chdir(relative_dir, filepath, 2, 0); /* finally cross check the directory */ check_success(filepath, 1, chdirwd); free(chdirwd); free(filepath); - rmdir(relative_dir); } ATF_TC(t_spawn_fchdir_file); @@ -621,43 +499,17 @@ ATF_TC_HEAD(t_spawn_fchdir_file, tc) ATF_TC_BODY(t_spawn_fchdir_file, tc) { - int error, fd; - pid_t pid; - char * const args[2] = { __UNCONST("pwd"), NULL }; - posix_spawnattr_t attr; - posix_spawn_file_actions_t fa; + int error, fd; fd = open(FILEPATH, O_WRONLY | O_CREAT | O_TRUNC, 0644); ATF_REQUIRE_MSG(fd != -1, "Can't open `%s' (%s)", FILEPATH, strerror(errno)); - error = posix_spawnattr_init(&attr); - ATF_REQUIRE(error == 0); - /* - * POSIX_SPAWN_RETURNERROR is a NetBSD specific flag that - * will cause a "proper" return value from posix_spawn(2) - * instead of a (potential) success there and a 127 exit - * status from the child process (c.f. the non-diag variant - * of this test). - */ - error = posix_spawnattr_setflags(&attr, POSIX_SPAWN_RETURNERROR); - ATF_REQUIRE(error == 0); - - error = posix_spawn_file_actions_init(&fa); - ATF_REQUIRE(error == 0); - - error = posix_spawn_file_actions_addfchdir(&fa, fd); - ATF_REQUIRE(error == 0); - - error = posix_spawn(&pid, "/bin/pwd", &fa, &attr, args, NULL); - ATF_CHECK(error == ENOTDIR); - - posix_spawn_file_actions_destroy(&fa); - posix_spawnattr_destroy(&attr); - error = close(fd); ATF_REQUIRE(error == 0); + spawn_chdir(FILEPATH, NULL, 2, ENOTDIR); + unlink(FILEPATH); }