Path: blob/main/contrib/atf/atf-c/detail/fs_test.c
39507 views
/* Copyright (c) 2007 The NetBSD Foundation, Inc.1* All rights reserved.2*3* Redistribution and use in source and binary forms, with or without4* modification, are permitted provided that the following conditions5* are met:6* 1. Redistributions of source code must retain the above copyright7* notice, this list of conditions and the following disclaimer.8* 2. Redistributions in binary form must reproduce the above copyright9* notice, this list of conditions and the following disclaimer in the10* documentation and/or other materials provided with the distribution.11*12* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND13* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,14* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF15* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.16* IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY17* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL18* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE19* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS20* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER21* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR22* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN23* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */2425#include "atf-c/detail/fs.h"2627#include <sys/types.h>28#include <sys/stat.h>2930#include <errno.h>31#include <fcntl.h>32#include <stdio.h>33#include <stdlib.h>34#include <string.h>35#include <unistd.h>3637#include <atf-c.h>3839#include "atf-c/detail/test_helpers.h"40#include "atf-c/detail/user.h"4142/* ---------------------------------------------------------------------43* Auxiliary functions.44* --------------------------------------------------------------------- */4546static47void48create_dir(const char *p, int mode)49{50int ret;5152ret = mkdir(p, mode);53if (ret == -1)54atf_tc_fail("Could not create helper directory %s", p);55}5657static58void59create_file(const char *p, int mode)60{61int fd;6263fd = open(p, O_CREAT | O_WRONLY | O_TRUNC, mode);64if (fd == -1)65atf_tc_fail("Could not create helper file %s", p);66close(fd);67}6869static70bool71exists(const atf_fs_path_t *p)72{73return access(atf_fs_path_cstring(p), F_OK) == 0;74}7576static77atf_error_t78mkstemp_discard_fd(atf_fs_path_t *p)79{80int fd;81atf_error_t err = atf_fs_mkstemp(p, &fd);82if (!atf_is_error(err))83close(fd);84return err;85}8687/* ---------------------------------------------------------------------88* Test cases for the "atf_fs_path" type.89* --------------------------------------------------------------------- */9091ATF_TC(path_normalize);92ATF_TC_HEAD(path_normalize, tc)93{94atf_tc_set_md_var(tc, "descr", "Tests the path's normalization");95}96ATF_TC_BODY(path_normalize, tc)97{98struct test {99const char *in;100const char *out;101} tests[] = {102{ ".", ".", },103{ "..", "..", },104105{ "/", "/", },106{ "//", "/", }, /* NO_CHECK_STYLE */107{ "///", "/", }, /* NO_CHECK_STYLE */108109{ "foo", "foo", },110{ "foo/", "foo", },111{ "foo/bar", "foo/bar", },112{ "foo/bar/", "foo/bar", },113114{ "/foo", "/foo", },115{ "/foo/bar", "/foo/bar", },116{ "/foo/bar/", "/foo/bar", },117118{ "///foo", "/foo", }, /* NO_CHECK_STYLE */119{ "///foo///bar", "/foo/bar", }, /* NO_CHECK_STYLE */120{ "///foo///bar///", "/foo/bar", }, /* NO_CHECK_STYLE */121122{ NULL, NULL }123};124struct test *t;125126for (t = &tests[0]; t->in != NULL; t++) {127atf_fs_path_t p;128129printf("Input : >%s<\n", t->in);130printf("Expected output: >%s<\n", t->out);131132RE(atf_fs_path_init_fmt(&p, "%s", t->in));133printf("Output : >%s<\n", atf_fs_path_cstring(&p));134ATF_REQUIRE(strcmp(atf_fs_path_cstring(&p), t->out) == 0);135atf_fs_path_fini(&p);136137printf("\n");138}139}140141ATF_TC(path_copy);142ATF_TC_HEAD(path_copy, tc)143{144atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_path_copy constructor");145}146ATF_TC_BODY(path_copy, tc)147{148atf_fs_path_t str, str2;149150RE(atf_fs_path_init_fmt(&str, "foo"));151RE(atf_fs_path_copy(&str2, &str));152153ATF_REQUIRE(atf_equal_fs_path_fs_path(&str, &str2));154155RE(atf_fs_path_append_fmt(&str2, "bar"));156157ATF_REQUIRE(!atf_equal_fs_path_fs_path(&str, &str2));158159atf_fs_path_fini(&str2);160atf_fs_path_fini(&str);161}162163ATF_TC(path_is_absolute);164ATF_TC_HEAD(path_is_absolute, tc)165{166atf_tc_set_md_var(tc, "descr", "Tests the path::is_absolute function");167}168ATF_TC_BODY(path_is_absolute, tc)169{170struct test {171const char *in;172bool abs;173} tests[] = {174{ "/", true },175{ "////", true }, /* NO_CHECK_STYLE */176{ "////a", true }, /* NO_CHECK_STYLE */177{ "//a//", true }, /* NO_CHECK_STYLE */178{ "a////", false }, /* NO_CHECK_STYLE */179{ "../foo", false },180{ NULL, false },181};182struct test *t;183184for (t = &tests[0]; t->in != NULL; t++) {185atf_fs_path_t p;186187printf("Input : %s\n", t->in);188printf("Expected result: %s\n", t->abs ? "true" : "false");189190RE(atf_fs_path_init_fmt(&p, "%s", t->in));191printf("Result : %s\n",192atf_fs_path_is_absolute(&p) ? "true" : "false");193if (t->abs)194ATF_REQUIRE(atf_fs_path_is_absolute(&p));195else196ATF_REQUIRE(!atf_fs_path_is_absolute(&p));197atf_fs_path_fini(&p);198199printf("\n");200}201}202203ATF_TC(path_is_root);204ATF_TC_HEAD(path_is_root, tc)205{206atf_tc_set_md_var(tc, "descr", "Tests the path::is_root function");207}208ATF_TC_BODY(path_is_root, tc)209{210struct test {211const char *in;212bool root;213} tests[] = {214{ "/", true },215{ "////", true }, /* NO_CHECK_STYLE */216{ "////a", false }, /* NO_CHECK_STYLE */217{ "//a//", false }, /* NO_CHECK_STYLE */218{ "a////", false }, /* NO_CHECK_STYLE */219{ "../foo", false },220{ NULL, false },221};222struct test *t;223224for (t = &tests[0]; t->in != NULL; t++) {225atf_fs_path_t p;226227printf("Input : %s\n", t->in);228printf("Expected result: %s\n", t->root ? "true" : "false");229230RE(atf_fs_path_init_fmt(&p, "%s", t->in));231printf("Result : %s\n",232atf_fs_path_is_root(&p) ? "true" : "false");233if (t->root)234ATF_REQUIRE(atf_fs_path_is_root(&p));235else236ATF_REQUIRE(!atf_fs_path_is_root(&p));237atf_fs_path_fini(&p);238239printf("\n");240}241}242243ATF_TC(path_branch_path);244ATF_TC_HEAD(path_branch_path, tc)245{246atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_path_branch_path "247"function");248}249ATF_TC_BODY(path_branch_path, tc)250{251struct test {252const char *in;253const char *branch;254} tests[] = {255{ ".", "." },256{ "foo", "." },257{ "foo/bar", "foo" },258{ "/foo", "/" },259{ "/foo/bar", "/foo" },260{ NULL, NULL },261};262struct test *t;263264for (t = &tests[0]; t->in != NULL; t++) {265atf_fs_path_t p, bp;266267printf("Input : %s\n", t->in);268printf("Expected output: %s\n", t->branch);269270RE(atf_fs_path_init_fmt(&p, "%s", t->in));271RE(atf_fs_path_branch_path(&p, &bp));272printf("Output : %s\n", atf_fs_path_cstring(&bp));273ATF_REQUIRE(strcmp(atf_fs_path_cstring(&bp), t->branch) == 0);274atf_fs_path_fini(&bp);275atf_fs_path_fini(&p);276277printf("\n");278}279}280281ATF_TC(path_leaf_name);282ATF_TC_HEAD(path_leaf_name, tc)283{284atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_path_leaf_name "285"function");286}287ATF_TC_BODY(path_leaf_name, tc)288{289struct test {290const char *in;291const char *leaf;292} tests[] = {293{ ".", "." },294{ "foo", "foo" },295{ "foo/bar", "bar" },296{ "/foo", "foo" },297{ "/foo/bar", "bar" },298{ NULL, NULL },299};300struct test *t;301302for (t = &tests[0]; t->in != NULL; t++) {303atf_fs_path_t p;304atf_dynstr_t ln;305306printf("Input : %s\n", t->in);307printf("Expected output: %s\n", t->leaf);308309RE(atf_fs_path_init_fmt(&p, "%s", t->in));310RE(atf_fs_path_leaf_name(&p, &ln));311printf("Output : %s\n", atf_dynstr_cstring(&ln));312ATF_REQUIRE(atf_equal_dynstr_cstring(&ln, t->leaf));313atf_dynstr_fini(&ln);314atf_fs_path_fini(&p);315316printf("\n");317}318}319320ATF_TC(path_append);321ATF_TC_HEAD(path_append, tc)322{323atf_tc_set_md_var(tc, "descr", "Tests the concatenation of multiple "324"paths");325}326ATF_TC_BODY(path_append, tc)327{328struct test {329const char *in;330const char *ap;331const char *out;332} tests[] = {333{ "foo", "bar", "foo/bar" },334{ "foo/", "/bar", "foo/bar" },335{ "foo/", "/bar/baz", "foo/bar/baz" },336{ "foo/", "///bar///baz", "foo/bar/baz" }, /* NO_CHECK_STYLE */337338{ NULL, NULL, NULL }339};340struct test *t;341342for (t = &tests[0]; t->in != NULL; t++) {343atf_fs_path_t p;344345printf("Input : >%s<\n", t->in);346printf("Append : >%s<\n", t->ap);347printf("Expected output: >%s<\n", t->out);348349RE(atf_fs_path_init_fmt(&p, "%s", t->in));350351RE(atf_fs_path_append_fmt(&p, "%s", t->ap));352353printf("Output : >%s<\n", atf_fs_path_cstring(&p));354ATF_REQUIRE(strcmp(atf_fs_path_cstring(&p), t->out) == 0);355356atf_fs_path_fini(&p);357358printf("\n");359}360}361362ATF_TC(path_to_absolute);363ATF_TC_HEAD(path_to_absolute, tc)364{365atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_path_to_absolute "366"function");367}368ATF_TC_BODY(path_to_absolute, tc)369{370const char *names[] = { ".", "dir", NULL };371const char **n;372373ATF_REQUIRE(mkdir("dir", 0755) != -1);374375for (n = names; *n != NULL; n++) {376atf_fs_path_t p, p2;377atf_fs_stat_t st1, st2;378379RE(atf_fs_path_init_fmt(&p, "%s", *n));380RE(atf_fs_stat_init(&st1, &p));381printf("Relative path: %s\n", atf_fs_path_cstring(&p));382383RE(atf_fs_path_to_absolute(&p, &p2));384printf("Absolute path: %s\n", atf_fs_path_cstring(&p2));385386ATF_REQUIRE(atf_fs_path_is_absolute(&p2));387RE(atf_fs_stat_init(&st2, &p2));388389ATF_REQUIRE_EQ(atf_fs_stat_get_device(&st1),390atf_fs_stat_get_device(&st2));391ATF_REQUIRE_EQ(atf_fs_stat_get_inode(&st1),392atf_fs_stat_get_inode(&st2));393394atf_fs_stat_fini(&st2);395atf_fs_stat_fini(&st1);396atf_fs_path_fini(&p2);397atf_fs_path_fini(&p);398399printf("\n");400}401}402403ATF_TC(path_equal);404ATF_TC_HEAD(path_equal, tc)405{406atf_tc_set_md_var(tc, "descr", "Tests the equality operators for paths");407}408ATF_TC_BODY(path_equal, tc)409{410atf_fs_path_t p1, p2;411412RE(atf_fs_path_init_fmt(&p1, "foo"));413414RE(atf_fs_path_init_fmt(&p2, "foo"));415ATF_REQUIRE(atf_equal_fs_path_fs_path(&p1, &p2));416atf_fs_path_fini(&p2);417418RE(atf_fs_path_init_fmt(&p2, "bar"));419ATF_REQUIRE(!atf_equal_fs_path_fs_path(&p1, &p2));420atf_fs_path_fini(&p2);421422atf_fs_path_fini(&p1);423}424425/* ---------------------------------------------------------------------426* Test cases for the "atf_fs_stat" type.427* --------------------------------------------------------------------- */428429ATF_TC(stat_mode);430ATF_TC_HEAD(stat_mode, tc)431{432atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_stat_get_mode function "433"and, indirectly, the constructor");434}435ATF_TC_BODY(stat_mode, tc)436{437atf_fs_path_t p;438atf_fs_stat_t st;439440create_file("f1", 0400);441create_file("f2", 0644);442443RE(atf_fs_path_init_fmt(&p, "f1"));444RE(atf_fs_stat_init(&st, &p));445ATF_CHECK_EQ(0400, atf_fs_stat_get_mode(&st));446atf_fs_stat_fini(&st);447atf_fs_path_fini(&p);448449RE(atf_fs_path_init_fmt(&p, "f2"));450RE(atf_fs_stat_init(&st, &p));451ATF_CHECK_EQ(0644, atf_fs_stat_get_mode(&st));452atf_fs_stat_fini(&st);453atf_fs_path_fini(&p);454}455456ATF_TC(stat_type);457ATF_TC_HEAD(stat_type, tc)458{459atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_stat_get_type function "460"and, indirectly, the constructor");461}462ATF_TC_BODY(stat_type, tc)463{464atf_fs_path_t p;465atf_fs_stat_t st;466467create_dir("dir", 0755);468create_file("reg", 0644);469470RE(atf_fs_path_init_fmt(&p, "dir"));471RE(atf_fs_stat_init(&st, &p));472ATF_REQUIRE_EQ(atf_fs_stat_get_type(&st), atf_fs_stat_dir_type);473atf_fs_stat_fini(&st);474atf_fs_path_fini(&p);475476RE(atf_fs_path_init_fmt(&p, "reg"));477RE(atf_fs_stat_init(&st, &p));478ATF_REQUIRE_EQ(atf_fs_stat_get_type(&st), atf_fs_stat_reg_type);479atf_fs_stat_fini(&st);480atf_fs_path_fini(&p);481}482483ATF_TC(stat_perms);484ATF_TC_HEAD(stat_perms, tc)485{486atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_stat_is_* functions");487}488ATF_TC_BODY(stat_perms, tc)489{490atf_fs_path_t p;491atf_fs_stat_t st;492493create_file("reg", 0);494495RE(atf_fs_path_init_fmt(&p, "reg"));496497#define perms(ur, uw, ux, gr, gw, gx, othr, othw, othx) \498{ \499RE(atf_fs_stat_init(&st, &p)); \500ATF_REQUIRE(atf_fs_stat_is_owner_readable(&st) == ur); \501ATF_REQUIRE(atf_fs_stat_is_owner_writable(&st) == uw); \502ATF_REQUIRE(atf_fs_stat_is_owner_executable(&st) == ux); \503ATF_REQUIRE(atf_fs_stat_is_group_readable(&st) == gr); \504ATF_REQUIRE(atf_fs_stat_is_group_writable(&st) == gw); \505ATF_REQUIRE(atf_fs_stat_is_group_executable(&st) == gx); \506ATF_REQUIRE(atf_fs_stat_is_other_readable(&st) == othr); \507ATF_REQUIRE(atf_fs_stat_is_other_writable(&st) == othw); \508ATF_REQUIRE(atf_fs_stat_is_other_executable(&st) == othx); \509atf_fs_stat_fini(&st); \510}511512chmod("reg", 0000);513perms(false, false, false, false, false, false, false, false, false);514515chmod("reg", 0001);516perms(false, false, false, false, false, false, false, false, true);517518chmod("reg", 0010);519perms(false, false, false, false, false, true, false, false, false);520521chmod("reg", 0100);522perms(false, false, true, false, false, false, false, false, false);523524chmod("reg", 0002);525perms(false, false, false, false, false, false, false, true, false);526527chmod("reg", 0020);528perms(false, false, false, false, true, false, false, false, false);529530chmod("reg", 0200);531perms(false, true, false, false, false, false, false, false, false);532533chmod("reg", 0004);534perms(false, false, false, false, false, false, true, false, false);535536chmod("reg", 0040);537perms(false, false, false, true, false, false, false, false, false);538539chmod("reg", 0400);540perms(true, false, false, false, false, false, false, false, false);541542chmod("reg", 0644);543perms(true, true, false, true, false, false, true, false, false);544545chmod("reg", 0755);546perms(true, true, true, true, false, true, true, false, true);547548chmod("reg", 0777);549perms(true, true, true, true, true, true, true, true, true);550551#undef perms552553atf_fs_path_fini(&p);554}555556/* ---------------------------------------------------------------------557* Test cases for the free functions.558* --------------------------------------------------------------------- */559560ATF_TC(exists);561ATF_TC_HEAD(exists, tc)562{563atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_exists function");564}565ATF_TC_BODY(exists, tc)566{567atf_error_t err;568atf_fs_path_t pdir, pfile;569bool b;570571RE(atf_fs_path_init_fmt(&pdir, "dir"));572RE(atf_fs_path_init_fmt(&pfile, "dir/file"));573574create_dir(atf_fs_path_cstring(&pdir), 0755);575create_file(atf_fs_path_cstring(&pfile), 0644);576577printf("Checking existence of a directory\n");578RE(atf_fs_exists(&pdir, &b));579ATF_REQUIRE(b);580581printf("Checking existence of a file\n");582RE(atf_fs_exists(&pfile, &b));583ATF_REQUIRE(b);584585/* XXX: This should probably be a separate test case to let the user586* be aware that some tests were skipped because privileges were not587* correct. */588if (!atf_user_is_root()) {589printf("Checking existence of a file inside a directory without "590"permissions\n");591ATF_REQUIRE(chmod(atf_fs_path_cstring(&pdir), 0000) != -1);592err = atf_fs_exists(&pfile, &b);593ATF_REQUIRE(atf_is_error(err));594ATF_REQUIRE(atf_error_is(err, "libc"));595ATF_REQUIRE(chmod(atf_fs_path_cstring(&pdir), 0755) != -1);596atf_error_free(err);597}598599printf("Checking existence of a non-existent file\n");600ATF_REQUIRE(unlink(atf_fs_path_cstring(&pfile)) != -1);601RE(atf_fs_exists(&pfile, &b));602ATF_REQUIRE(!b);603604atf_fs_path_fini(&pfile);605atf_fs_path_fini(&pdir);606}607608ATF_TC(eaccess);609ATF_TC_HEAD(eaccess, tc)610{611atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_eaccess function");612}613ATF_TC_BODY(eaccess, tc)614{615const int modes[] = { atf_fs_access_f, atf_fs_access_r, atf_fs_access_w,616atf_fs_access_x, 0 };617const int *m;618struct tests {619mode_t fmode;620int amode;621int uerror;622int rerror;623} tests[] = {624{ 0000, atf_fs_access_r, EACCES, 0 },625{ 0000, atf_fs_access_w, EACCES, 0 },626{ 0000, atf_fs_access_x, EACCES, EACCES },627628{ 0001, atf_fs_access_r, EACCES, 0 },629{ 0001, atf_fs_access_w, EACCES, 0 },630{ 0001, atf_fs_access_x, EACCES, 0 },631{ 0002, atf_fs_access_r, EACCES, 0 },632{ 0002, atf_fs_access_w, EACCES, 0 },633{ 0002, atf_fs_access_x, EACCES, EACCES },634{ 0004, atf_fs_access_r, EACCES, 0 },635{ 0004, atf_fs_access_w, EACCES, 0 },636{ 0004, atf_fs_access_x, EACCES, EACCES },637638{ 0010, atf_fs_access_r, EACCES, 0 },639{ 0010, atf_fs_access_w, EACCES, 0 },640{ 0010, atf_fs_access_x, 0, 0 },641{ 0020, atf_fs_access_r, EACCES, 0 },642{ 0020, atf_fs_access_w, 0, 0 },643{ 0020, atf_fs_access_x, EACCES, EACCES },644{ 0040, atf_fs_access_r, 0, 0 },645{ 0040, atf_fs_access_w, EACCES, 0 },646{ 0040, atf_fs_access_x, EACCES, EACCES },647648{ 0100, atf_fs_access_r, EACCES, 0 },649{ 0100, atf_fs_access_w, EACCES, 0 },650{ 0100, atf_fs_access_x, 0, 0 },651{ 0200, atf_fs_access_r, EACCES, 0 },652{ 0200, atf_fs_access_w, 0, 0 },653{ 0200, atf_fs_access_x, EACCES, EACCES },654{ 0400, atf_fs_access_r, 0, 0 },655{ 0400, atf_fs_access_w, EACCES, 0 },656{ 0400, atf_fs_access_x, EACCES, EACCES },657658{ 0, 0, 0, 0 }659};660struct tests *t;661atf_fs_path_t p;662atf_error_t err;663664RE(atf_fs_path_init_fmt(&p, "the-file"));665666printf("Non-existent file checks\n");667for (m = &modes[0]; *m != 0; m++) {668err = atf_fs_eaccess(&p, *m);669ATF_REQUIRE(atf_is_error(err));670ATF_REQUIRE(atf_error_is(err, "libc"));671ATF_REQUIRE_EQ(atf_libc_error_code(err), ENOENT);672atf_error_free(err);673}674675create_file(atf_fs_path_cstring(&p), 0000);676ATF_REQUIRE(chown(atf_fs_path_cstring(&p), geteuid(), getegid()) != -1);677678for (t = &tests[0]; t->amode != 0; t++) {679const int experr = atf_user_is_root() ? t->rerror : t->uerror;680681printf("\n");682printf("File mode : %04o\n", (unsigned int)t->fmode);683printf("Access mode : 0x%02x\n", t->amode);684685ATF_REQUIRE(chmod(atf_fs_path_cstring(&p), t->fmode) != -1);686687/* First, existence check. */688err = atf_fs_eaccess(&p, atf_fs_access_f);689ATF_REQUIRE(!atf_is_error(err));690691/* Now do the specific test case. */692printf("Expected error: %d\n", experr);693err = atf_fs_eaccess(&p, t->amode);694if (atf_is_error(err)) {695if (atf_error_is(err, "libc"))696printf("Error : %d\n", atf_libc_error_code(err));697else698printf("Error : Non-libc error\n");699} else700printf("Error : None\n");701if (experr == 0) {702ATF_REQUIRE(!atf_is_error(err));703} else {704ATF_REQUIRE(atf_is_error(err));705ATF_REQUIRE(atf_error_is(err, "libc"));706ATF_REQUIRE_EQ(atf_libc_error_code(err), experr);707atf_error_free(err);708}709}710711atf_fs_path_fini(&p);712}713714ATF_TC(getcwd);715ATF_TC_HEAD(getcwd, tc)716{717atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_getcwd function");718}719ATF_TC_BODY(getcwd, tc)720{721atf_fs_path_t cwd1, cwd2;722723create_dir ("root", 0755);724725RE(atf_fs_getcwd(&cwd1));726ATF_REQUIRE(chdir("root") != -1);727RE(atf_fs_getcwd(&cwd2));728729RE(atf_fs_path_append_fmt(&cwd1, "root"));730731ATF_REQUIRE(atf_equal_fs_path_fs_path(&cwd1, &cwd2));732733atf_fs_path_fini(&cwd2);734atf_fs_path_fini(&cwd1);735}736737ATF_TC(rmdir_empty);738ATF_TC_HEAD(rmdir_empty, tc)739{740atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_rmdir function");741}742ATF_TC_BODY(rmdir_empty, tc)743{744atf_fs_path_t p;745746RE(atf_fs_path_init_fmt(&p, "test-dir"));747748ATF_REQUIRE(mkdir("test-dir", 0755) != -1);749ATF_REQUIRE(exists(&p));750RE(atf_fs_rmdir(&p));751ATF_REQUIRE(!exists(&p));752753atf_fs_path_fini(&p);754}755756ATF_TC(rmdir_enotempty);757ATF_TC_HEAD(rmdir_enotempty, tc)758{759atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_rmdir function");760}761ATF_TC_BODY(rmdir_enotempty, tc)762{763atf_fs_path_t p;764atf_error_t err;765766RE(atf_fs_path_init_fmt(&p, "test-dir"));767768ATF_REQUIRE(mkdir("test-dir", 0755) != -1);769ATF_REQUIRE(exists(&p));770create_file("test-dir/foo", 0644);771772err = atf_fs_rmdir(&p);773ATF_REQUIRE(atf_is_error(err));774ATF_REQUIRE(atf_error_is(err, "libc"));775ATF_REQUIRE_EQ(atf_libc_error_code(err), ENOTEMPTY);776atf_error_free(err);777778atf_fs_path_fini(&p);779}780781ATF_TC_WITH_CLEANUP(rmdir_eperm);782ATF_TC_HEAD(rmdir_eperm, tc)783{784atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_rmdir function");785}786ATF_TC_BODY(rmdir_eperm, tc)787{788atf_fs_path_t p;789atf_error_t err;790791RE(atf_fs_path_init_fmt(&p, "test-dir/foo"));792793ATF_REQUIRE(mkdir("test-dir", 0755) != -1);794ATF_REQUIRE(mkdir("test-dir/foo", 0755) != -1);795ATF_REQUIRE(chmod("test-dir", 0555) != -1);796ATF_REQUIRE(exists(&p));797798err = atf_fs_rmdir(&p);799if (atf_user_is_root()) {800ATF_REQUIRE(!atf_is_error(err));801} else {802ATF_REQUIRE(atf_is_error(err));803ATF_REQUIRE(atf_error_is(err, "libc"));804ATF_REQUIRE_EQ(atf_libc_error_code(err), EACCES);805atf_error_free(err);806}807808atf_fs_path_fini(&p);809}810ATF_TC_CLEANUP(rmdir_eperm, tc)811{812if (chmod("test-dir", 0755) == -1) {813fprintf(stderr, "Failed to unprotect test-dir; test directory "814"cleanup will fail\n");815}816}817818ATF_TC(mkdtemp_ok);819ATF_TC_HEAD(mkdtemp_ok, tc)820{821atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_mkdtemp function, "822"successful execution");823}824ATF_TC_BODY(mkdtemp_ok, tc)825{826atf_fs_path_t p1, p2;827atf_fs_stat_t s1, s2;828829RE(atf_fs_path_init_fmt(&p1, "testdir.XXXXXX"));830RE(atf_fs_path_init_fmt(&p2, "testdir.XXXXXX"));831RE(atf_fs_mkdtemp(&p1));832RE(atf_fs_mkdtemp(&p2));833ATF_REQUIRE(!atf_equal_fs_path_fs_path(&p1, &p2));834ATF_REQUIRE(exists(&p1));835ATF_REQUIRE(exists(&p2));836837RE(atf_fs_stat_init(&s1, &p1));838ATF_REQUIRE_EQ(atf_fs_stat_get_type(&s1), atf_fs_stat_dir_type);839ATF_REQUIRE( atf_fs_stat_is_owner_readable(&s1));840ATF_REQUIRE( atf_fs_stat_is_owner_writable(&s1));841ATF_REQUIRE( atf_fs_stat_is_owner_executable(&s1));842ATF_REQUIRE(!atf_fs_stat_is_group_readable(&s1));843ATF_REQUIRE(!atf_fs_stat_is_group_writable(&s1));844ATF_REQUIRE(!atf_fs_stat_is_group_executable(&s1));845ATF_REQUIRE(!atf_fs_stat_is_other_readable(&s1));846ATF_REQUIRE(!atf_fs_stat_is_other_writable(&s1));847ATF_REQUIRE(!atf_fs_stat_is_other_executable(&s1));848849RE(atf_fs_stat_init(&s2, &p2));850ATF_REQUIRE_EQ(atf_fs_stat_get_type(&s2), atf_fs_stat_dir_type);851ATF_REQUIRE( atf_fs_stat_is_owner_readable(&s2));852ATF_REQUIRE( atf_fs_stat_is_owner_writable(&s2));853ATF_REQUIRE( atf_fs_stat_is_owner_executable(&s2));854ATF_REQUIRE(!atf_fs_stat_is_group_readable(&s2));855ATF_REQUIRE(!atf_fs_stat_is_group_writable(&s2));856ATF_REQUIRE(!atf_fs_stat_is_group_executable(&s2));857ATF_REQUIRE(!atf_fs_stat_is_other_readable(&s2));858ATF_REQUIRE(!atf_fs_stat_is_other_writable(&s2));859ATF_REQUIRE(!atf_fs_stat_is_other_executable(&s2));860861atf_fs_stat_fini(&s2);862atf_fs_stat_fini(&s1);863atf_fs_path_fini(&p2);864atf_fs_path_fini(&p1);865}866867ATF_TC(mkdtemp_err);868ATF_TC_HEAD(mkdtemp_err, tc)869{870atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_mkdtemp function, "871"error conditions");872atf_tc_set_md_var(tc, "require.user", "unprivileged");873}874ATF_TC_BODY(mkdtemp_err, tc)875{876atf_error_t err;877atf_fs_path_t p;878879ATF_REQUIRE(mkdir("dir", 0555) != -1);880881RE(atf_fs_path_init_fmt(&p, "dir/testdir.XXXXXX"));882883err = atf_fs_mkdtemp(&p);884ATF_REQUIRE(atf_is_error(err));885ATF_REQUIRE(atf_error_is(err, "libc"));886ATF_CHECK_EQ(atf_libc_error_code(err), EACCES);887atf_error_free(err);888889ATF_CHECK(!exists(&p));890ATF_CHECK(strcmp(atf_fs_path_cstring(&p), "dir/testdir.XXXXXX") == 0);891892atf_fs_path_fini(&p);893}894895static896void897do_umask_check(atf_error_t (*const mk_func)(atf_fs_path_t *),898atf_error_t (*const rm_func)(const atf_fs_path_t *),899atf_fs_path_t *tmpl, const mode_t test_mask,900const char *exp_name)901{902atf_fs_path_t path;903int pre_mask, post_mask;904atf_error_t err;905906printf("Creating temporary %s with umask %05o\n", exp_name, test_mask);907908RE(atf_fs_path_copy(&path, tmpl));909910pre_mask = umask(test_mask);911err = mk_func(&path);912post_mask = umask(pre_mask);913914ATF_REQUIRE(!atf_is_error(err));915ATF_CHECK_EQ(post_mask, test_mask);916RE(rm_func(&path));917}918919ATF_TC(mkdtemp_umask);920ATF_TC_HEAD(mkdtemp_umask, tc)921{922atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_mkdtemp function "923"causing an error due to a too strict umask");924}925ATF_TC_BODY(mkdtemp_umask, tc)926{927atf_fs_path_t p;928929RE(atf_fs_path_init_fmt(&p, "testdir.XXXXXX"));930931do_umask_check(atf_fs_mkdtemp, atf_fs_rmdir, &p, 00100, "directory");932do_umask_check(atf_fs_mkdtemp, atf_fs_rmdir, &p, 00200, "directory");933do_umask_check(atf_fs_mkdtemp, atf_fs_rmdir, &p, 00400, "directory");934do_umask_check(atf_fs_mkdtemp, atf_fs_rmdir, &p, 00500, "directory");935do_umask_check(atf_fs_mkdtemp, atf_fs_rmdir, &p, 00600, "directory");936937atf_fs_path_fini(&p);938}939940ATF_TC(mkstemp_ok);941ATF_TC_HEAD(mkstemp_ok, tc)942{943atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_mkstemp function, "944"successful execution");945}946ATF_TC_BODY(mkstemp_ok, tc)947{948int fd1, fd2;949atf_fs_path_t p1, p2;950atf_fs_stat_t s1, s2;951952RE(atf_fs_path_init_fmt(&p1, "testfile.XXXXXX"));953RE(atf_fs_path_init_fmt(&p2, "testfile.XXXXXX"));954fd1 = fd2 = -1;955RE(atf_fs_mkstemp(&p1, &fd1));956RE(atf_fs_mkstemp(&p2, &fd2));957ATF_REQUIRE(!atf_equal_fs_path_fs_path(&p1, &p2));958ATF_REQUIRE(exists(&p1));959ATF_REQUIRE(exists(&p2));960961ATF_CHECK(fd1 != -1);962ATF_CHECK(fd2 != -1);963ATF_CHECK(write(fd1, "foo", 3) == 3);964ATF_CHECK(write(fd2, "bar", 3) == 3);965close(fd1);966close(fd2);967968RE(atf_fs_stat_init(&s1, &p1));969ATF_CHECK_EQ(atf_fs_stat_get_type(&s1), atf_fs_stat_reg_type);970ATF_CHECK( atf_fs_stat_is_owner_readable(&s1));971ATF_CHECK( atf_fs_stat_is_owner_writable(&s1));972ATF_CHECK(!atf_fs_stat_is_owner_executable(&s1));973ATF_CHECK(!atf_fs_stat_is_group_readable(&s1));974ATF_CHECK(!atf_fs_stat_is_group_writable(&s1));975ATF_CHECK(!atf_fs_stat_is_group_executable(&s1));976ATF_CHECK(!atf_fs_stat_is_other_readable(&s1));977ATF_CHECK(!atf_fs_stat_is_other_writable(&s1));978ATF_CHECK(!atf_fs_stat_is_other_executable(&s1));979980RE(atf_fs_stat_init(&s2, &p2));981ATF_CHECK_EQ(atf_fs_stat_get_type(&s2), atf_fs_stat_reg_type);982ATF_CHECK( atf_fs_stat_is_owner_readable(&s2));983ATF_CHECK( atf_fs_stat_is_owner_writable(&s2));984ATF_CHECK(!atf_fs_stat_is_owner_executable(&s2));985ATF_CHECK(!atf_fs_stat_is_group_readable(&s2));986ATF_CHECK(!atf_fs_stat_is_group_writable(&s2));987ATF_CHECK(!atf_fs_stat_is_group_executable(&s2));988ATF_CHECK(!atf_fs_stat_is_other_readable(&s2));989ATF_CHECK(!atf_fs_stat_is_other_writable(&s2));990ATF_CHECK(!atf_fs_stat_is_other_executable(&s2));991992atf_fs_stat_fini(&s2);993atf_fs_stat_fini(&s1);994atf_fs_path_fini(&p2);995atf_fs_path_fini(&p1);996}997998ATF_TC(mkstemp_err);999ATF_TC_HEAD(mkstemp_err, tc)1000{1001atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_mkstemp function, "1002"error conditions");1003atf_tc_set_md_var(tc, "require.user", "unprivileged");1004}1005ATF_TC_BODY(mkstemp_err, tc)1006{1007int fd;1008atf_error_t err;1009atf_fs_path_t p;10101011ATF_REQUIRE(mkdir("dir", 0555) != -1);10121013RE(atf_fs_path_init_fmt(&p, "dir/testfile.XXXXXX"));1014fd = 1234;10151016err = atf_fs_mkstemp(&p, &fd);1017ATF_REQUIRE(atf_is_error(err));1018ATF_REQUIRE(atf_error_is(err, "libc"));1019ATF_CHECK_EQ(atf_libc_error_code(err), EACCES);1020atf_error_free(err);10211022ATF_CHECK(!exists(&p));1023ATF_CHECK(strcmp(atf_fs_path_cstring(&p), "dir/testfile.XXXXXX") == 0);1024ATF_CHECK_EQ(fd, 1234);10251026atf_fs_path_fini(&p);1027}10281029ATF_TC(mkstemp_umask);1030ATF_TC_HEAD(mkstemp_umask, tc)1031{1032atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_mkstemp function "1033"causing an error due to a too strict umask");1034}1035ATF_TC_BODY(mkstemp_umask, tc)1036{1037atf_fs_path_t p;10381039RE(atf_fs_path_init_fmt(&p, "testfile.XXXXXX"));10401041do_umask_check(mkstemp_discard_fd, atf_fs_unlink, &p, 00100, "regular file");1042do_umask_check(mkstemp_discard_fd, atf_fs_unlink, &p, 00200, "regular file");1043do_umask_check(mkstemp_discard_fd, atf_fs_unlink, &p, 00400, "regular file");10441045atf_fs_path_fini(&p);1046}10471048/* ---------------------------------------------------------------------1049* Main.1050* --------------------------------------------------------------------- */10511052ATF_TP_ADD_TCS(tp)1053{1054/* Add the tests for the "atf_fs_path" type. */1055ATF_TP_ADD_TC(tp, path_normalize);1056ATF_TP_ADD_TC(tp, path_copy);1057ATF_TP_ADD_TC(tp, path_is_absolute);1058ATF_TP_ADD_TC(tp, path_is_root);1059ATF_TP_ADD_TC(tp, path_branch_path);1060ATF_TP_ADD_TC(tp, path_leaf_name);1061ATF_TP_ADD_TC(tp, path_append);1062ATF_TP_ADD_TC(tp, path_to_absolute);1063ATF_TP_ADD_TC(tp, path_equal);10641065/* Add the tests for the "atf_fs_stat" type. */1066ATF_TP_ADD_TC(tp, stat_mode);1067ATF_TP_ADD_TC(tp, stat_type);1068ATF_TP_ADD_TC(tp, stat_perms);10691070/* Add the tests for the free functions. */1071ATF_TP_ADD_TC(tp, eaccess);1072ATF_TP_ADD_TC(tp, exists);1073ATF_TP_ADD_TC(tp, getcwd);1074ATF_TP_ADD_TC(tp, rmdir_empty);1075ATF_TP_ADD_TC(tp, rmdir_enotempty);1076ATF_TP_ADD_TC(tp, rmdir_eperm);1077ATF_TP_ADD_TC(tp, mkdtemp_ok);1078ATF_TP_ADD_TC(tp, mkdtemp_err);1079ATF_TP_ADD_TC(tp, mkdtemp_umask);1080ATF_TP_ADD_TC(tp, mkstemp_ok);1081ATF_TP_ADD_TC(tp, mkstemp_err);1082ATF_TP_ADD_TC(tp, mkstemp_umask);10831084return atf_no_error();1085}108610871088