Home | History | Annotate | Download | only in mkdirat
      1 /*
      2  * Copyright (c) 2014 Fujitsu Ltd.
      3  * Author: Zeng Linggang <zenglg.jy (at) cn.fujitsu.com>
      4  *
      5  * This program is free software; you can redistribute it and/or modify it
      6  * under the terms of version 2 of the GNU General Public License as
      7  * published by the Free Software Foundation.
      8  *
      9  * This program is distributed in the hope that it would be useful, but
     10  * WITHOUT ANY WARRANTY; without even the implied warranty of
     11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
     12  *
     13  * You should have received a copy of the GNU General Public License along
     14  * with this program; if not, write the Free Software Foundation, Inc.,
     15  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
     16  */
     17 /*
     18  * DESCRIPTION
     19  *	check mkdirat() with various error conditions that should produce
     20  *	ELOOP and EROFS.
     21  */
     22 
     23 #define _GNU_SOURCE
     24 #include "tst_test.h"
     25 #include "lapi/mkdirat.h"
     26 
     27 #define MNT_POINT	"mntpoint"
     28 #define TEST_DIR	"mntpoint/test_dir"
     29 #define DIR_MODE	(S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP| \
     30 			 S_IXGRP|S_IROTH|S_IXOTH)
     31 
     32 static int dir_fd;
     33 static int cur_fd = AT_FDCWD;
     34 static char test_dir[PATH_MAX] = ".";
     35 
     36 static struct tcase {
     37 	int *dirfd;
     38 	char *pathname;
     39 	int exp_errno;
     40 } tcases[] = {
     41 	{&dir_fd, TEST_DIR, EROFS},
     42 	{&cur_fd, TEST_DIR, EROFS},
     43 	{&dir_fd, test_dir, ELOOP},
     44 	{&cur_fd, test_dir, ELOOP},
     45 };
     46 
     47 static void setup(void)
     48 {
     49 	unsigned int i;
     50 
     51 	dir_fd = SAFE_OPEN(".", O_DIRECTORY);
     52 
     53 	SAFE_MKDIR("test_eloop", DIR_MODE);
     54 	SAFE_SYMLINK("../test_eloop", "test_eloop/test_eloop");
     55 
     56 	/*
     57 	 * NOTE: the ELOOP test is written based on that the consecutive
     58 	 * symlinks limits in kernel is hardwired to 40.
     59 	 */
     60 	for (i = 0; i < 43; i++)
     61 		strcat(test_dir, "/test_eloop");
     62 }
     63 
     64 static void mkdirat_verify(unsigned int i)
     65 {
     66 	struct tcase *test = &tcases[i];
     67 
     68 	TEST(mkdirat(*test->dirfd, test->pathname, 0777));
     69 
     70 	if (TST_RET != -1) {
     71 		tst_res(TFAIL, "mkdirat() succeeded unexpectedly (%li)",
     72 			TST_RET);
     73 		return;
     74 	}
     75 
     76 	if (TST_ERR == test->exp_errno) {
     77 		tst_res(TPASS | TTERRNO, "mkdirat() failed as expected");
     78 		return;
     79 	}
     80 
     81 	tst_res(TFAIL | TTERRNO,
     82 		"mkdirat() failed unexpectedly; expected: %d - %s",
     83 		test->exp_errno, tst_strerrno(test->exp_errno));
     84 }
     85 
     86 static struct tst_test test = {
     87 	.setup = setup,
     88 	.test = mkdirat_verify,
     89 	.tcnt = ARRAY_SIZE(tcases),
     90 	.needs_root = 1,
     91 	.needs_rofs = 1,
     92 	.mntpoint = MNT_POINT,
     93 };
     94