Home | History | Annotate | Download | only in link
      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
      6  * it under the terms of the GNU General Public License as published by
      7  * the Free Software Foundation; either version 2 of the License, or
      8  * (at your option) any later version.
      9  *
     10  * This program is distributed in the hope that it will be useful,
     11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13  * GNU Library General Public License for more details.
     14  *
     15  * You should have received a copy of the GNU General Public License
     16  * along with this program; if not, write to the Free Software
     17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
     18  */
     19 /*
     20  * Test Description:
     21  *  Verify that,
     22  *   1. link() fails with -1 return value and sets errno to EPERM
     23  *      if oldpath is a directory.
     24  *   2. link() fails with -1 return value and sets errno to EXDEV
     25  *      if oldpath and newpath are not on the same mounted file system( Linux
     26  *      permits a file system to be mounted at multiple points, but link()
     27  *      does not work across different mount points, even if the same
     28  *      file system is mounted on both. ).
     29  *   3. link() fails with -1 return value and sets errno to EROFS
     30  *      if the file is on a read-only file system.
     31  *   4. link() fails with -1 return value and sets errno to ELOOP
     32  *      if too many symbolic links were encountered in resolving path.
     33  */
     34 #include <errno.h>
     35 #include "tst_test.h"
     36 
     37 #define DIR_MODE	(S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP| \
     38 			 S_IXGRP|S_IROTH|S_IXOTH)
     39 #define MNT_POINT	"mntpoint"
     40 #define TEST_FILE	"testfile"
     41 #define TEST_FILE1	"testfile1"
     42 #define TEST_FILE2	"mntpoint/file"
     43 #define TEST_FILE3	"mntpoint/testfile4"
     44 
     45 static char test_file4[PATH_MAX] = ".";
     46 static void setup(void);
     47 
     48 static struct tcase {
     49 	char *oldpath;
     50 	char *newpath;
     51 	int exp_errno;
     52 } tcases[] = {
     53 	{TEST_FILE1, TEST_FILE, EPERM},
     54 	{TEST_FILE2, TEST_FILE, EXDEV},
     55 	{TEST_FILE2, TEST_FILE3, EROFS},
     56 	{test_file4, TEST_FILE, ELOOP},
     57 };
     58 
     59 static void link_verify(unsigned int i)
     60 {
     61 	struct tcase *tc = &tcases[i];
     62 
     63 	TEST(link(tc->oldpath, tc->newpath));
     64 
     65 	if (TST_RET != -1) {
     66 		tst_res(TFAIL, "link() succeeded unexpectedly (%li)",
     67 			TST_RET);
     68 		return;
     69 	}
     70 
     71 	if (TST_ERR == tc->exp_errno) {
     72 		tst_res(TPASS | TTERRNO, "link() failed as expected");
     73 		return;
     74 	}
     75 
     76 	tst_res(TFAIL | TTERRNO,
     77 		"link() failed unexpectedly; expected: %d - %s",
     78 		tc->exp_errno, tst_strerrno(tc->exp_errno));
     79 }
     80 
     81 static void setup(void)
     82 {
     83 	int i;
     84 
     85 	SAFE_MKDIR(TEST_FILE1, DIR_MODE);
     86 
     87 	SAFE_MKDIR("test_eloop", DIR_MODE);
     88 	SAFE_SYMLINK("../test_eloop", "test_eloop/test_eloop");
     89 	for (i = 0; i < 43; i++)
     90 		strcat(test_file4, "/test_eloop");
     91 }
     92 
     93 static struct tst_test test = {
     94 	.setup = setup,
     95 	.test = link_verify,
     96 	.tcnt = ARRAY_SIZE(tcases),
     97 	.needs_root = 1,
     98 	.needs_rofs = 1,
     99 	.mntpoint = MNT_POINT,
    100 };
    101