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