Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:31

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /*
0004  *  COPYRIGHT (c) 1989-2011.
0005  *  On-Line Applications Research Corporation (OAR).
0006  *
0007  * Redistribution and use in source and binary forms, with or without
0008  * modification, are permitted provided that the following conditions
0009  * are met:
0010  * 1. Redistributions of source code must retain the above copyright
0011  *    notice, this list of conditions and the following disclaimer.
0012  * 2. Redistributions in binary form must reproduce the above copyright
0013  *    notice, this list of conditions and the following disclaimer in the
0014  *    documentation and/or other materials provided with the distribution.
0015  *
0016  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0017  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0018  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0019  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0020  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0021  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0022  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0023  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0024  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0025  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0026  * POSSIBILITY OF SUCH DAMAGE.
0027  */
0028 
0029 #ifdef HAVE_CONFIG_H
0030 #include "config.h"
0031 #endif
0032 
0033 #include <sys/stat.h>
0034 #include <fcntl.h>
0035 #include <errno.h>
0036 #include <stdio.h>
0037 #include <stdint.h>
0038 #include <unistd.h>
0039 #include <stdlib.h>
0040 #include <string.h>
0041 #include <unistd.h>
0042 #include <dirent.h>
0043 
0044 #include "fstest.h"
0045 #include "fs_config.h"
0046 #include <tmacros.h>
0047 
0048 const char rtems_test_name[] = "FSSYMLINK " FILESYSTEM;
0049 const RTEMS_TEST_STATE rtems_test_state = TEST_STATE;
0050 
0051 /*
0052  * Test the function of symlink
0053  */
0054 
0055 static void symlink_test01(void )
0056 {
0057   int   fd;
0058   char* file01="file";
0059   char* symlink_file01="symlink";
0060   char name[20];
0061   int   status;
0062   struct stat statbuf;
0063   size_t   len=strlen(file01);
0064   size_t   name_len;
0065 
0066 
0067   printf("Create a file named %s\n",file01);
0068   fd=creat(file01,0777);
0069   status=close(fd);
0070   rtems_test_assert(status==0);
0071 
0072   printf("Create a symlink named %s to %s\n",symlink_file01,file01);
0073   status=symlink(file01,symlink_file01);
0074   rtems_test_assert(status==0);
0075 
0076   status=stat(file01,&statbuf);
0077   rtems_test_assert(status==0);
0078   rtems_test_assert(S_ISREG(statbuf.st_mode));
0079   rtems_test_assert(0==statbuf.st_size);
0080 
0081   status=lstat(symlink_file01,&statbuf);
0082   rtems_test_assert(status==0);
0083   rtems_test_assert(S_ISLNK(statbuf.st_mode));
0084   rtems_test_assert(len==statbuf.st_size);
0085 
0086 
0087   puts("call readlink ");
0088   name_len=readlink(symlink_file01,name,sizeof(name)-1);
0089   rtems_test_assert(name_len!=-1);
0090   name[name_len]='\0';
0091   rtems_test_assert(!strncmp(name,file01,name_len));
0092   puts(name);
0093 
0094   puts("Unlink the file");
0095 
0096   status=unlink(file01);
0097   rtems_test_assert(status==0);
0098 
0099   status=lstat(symlink_file01,&statbuf);
0100   rtems_test_assert(status==0);
0101   rtems_test_assert(S_ISLNK(statbuf.st_mode));
0102   rtems_test_assert(len==statbuf.st_size);
0103 
0104   puts("call readlink ");
0105   name_len=readlink(symlink_file01,name,sizeof(name)-1);
0106   rtems_test_assert(name_len!=-1);
0107   name[name_len]='\0';
0108   rtems_test_assert(!strncmp(name,file01,name_len));
0109   status=unlink(symlink_file01);
0110   rtems_test_assert(status==0);
0111 
0112   printf("Create a dir named %s\n",file01);
0113   status=mkdir (file01,0777);
0114 
0115   printf("Create a symlink named %s to %s\n",symlink_file01,file01);
0116   status=symlink(file01,symlink_file01);
0117   rtems_test_assert(status==0);
0118 
0119   status=lstat(symlink_file01,&statbuf);
0120   rtems_test_assert(status==0);
0121   rtems_test_assert(S_ISLNK(statbuf.st_mode));
0122   rtems_test_assert(len==statbuf.st_size);
0123 
0124 
0125   puts("call readlink ");
0126   name_len=readlink(symlink_file01,name,sizeof(name)-1);
0127   rtems_test_assert(name_len!=-1);
0128   name[name_len]='\0';
0129   rtems_test_assert(!strncmp(name,file01,name_len));
0130 
0131   name_len=readlink(symlink_file01,name,3);
0132   rtems_test_assert(name_len!=-1);
0133   name[name_len]='\0';
0134   rtems_test_assert(!strncmp(name,file01,name_len));
0135 
0136   puts("rmdir the dir");
0137   status=rmdir(file01);
0138   rtems_test_assert(status==0);
0139 
0140   status=lstat(symlink_file01,&statbuf);
0141   rtems_test_assert(status==0);
0142   rtems_test_assert(S_ISLNK(statbuf.st_mode));
0143 
0144   status=unlink(symlink_file01);
0145   rtems_test_assert(status==0);
0146 
0147 }
0148 /*
0149  *  symlink loop error test
0150  */
0151 static void symlink_loop_error_test(void )
0152 {
0153   char* file01="file01";
0154   char* file02="file02";
0155 
0156   char* file04="file04";
0157   char* path="file01/t";
0158 
0159   int   status;
0160 
0161   mode_t mode = S_IRWXU | S_IRWXG | S_IRWXO;
0162 
0163   puts("symlink loop error test");
0164 
0165   status=symlink(file01,file02);
0166   rtems_test_assert(status==0);
0167   status=symlink(file02,file01);
0168   rtems_test_assert(status==0);
0169 
0170 
0171   EXPECT_ERROR(ELOOP,creat,path,mode);
0172   EXPECT_ERROR(ELOOP,open,path,O_CREAT|O_WRONLY,mode);
0173   EXPECT_ERROR(ELOOP,truncate,path,0);
0174   EXPECT_ERROR(ELOOP,rename,path,file04);
0175   EXPECT_ERROR(ELOOP,unlink,path);
0176   EXPECT_ERROR(ELOOP,mkdir,path,mode);
0177   EXPECT_ERROR(ELOOP,rmdir,path);
0178 }
0179 
0180 static void symlink_rename_test (void)
0181 {
0182   int fd;
0183   int status;
0184   int rv;
0185 
0186   const char *name01 = "name01";
0187   const char *name02 = "name02";
0188 
0189   const char *symlink01 = "slink01";
0190   const char *symlink02 = "slink02";
0191 
0192   char path01[20];
0193 
0194   mode_t mode = S_IRWXU | S_IRWXG | S_IRWXO;
0195   const char *wd = __func__;
0196 
0197   struct stat statbuf;
0198 
0199   /*
0200    * Create a new directory and change the current directory to this
0201    */
0202 
0203   status = mkdir (wd, mode);
0204   rtems_test_assert (status == 0);
0205   status = chdir (wd);
0206   rtems_test_assert (status == 0);
0207 
0208   /*
0209    * The new argument points to a file and
0210    * the old argument points to a symbolic link to another file.
0211    */
0212 
0213   puts ("\nOld is a simbolic link and rename operates on the simbolic link itself\n");
0214 
0215   fd = creat (name01, mode);
0216   rtems_test_assert (fd >= 0);
0217   status = close (fd);
0218   rtems_test_assert (status == 0);
0219 
0220   fd = creat (name02, mode);
0221   rtems_test_assert (fd >= 0);
0222   status = close (fd);
0223   rtems_test_assert (status == 0);
0224 
0225   status = symlink (name01, symlink01);
0226   rtems_test_assert (status == 0);
0227 
0228   EXPECT_EQUAL (0, rename, symlink01, name02);
0229   EXPECT_EQUAL (0, lstat, name02, &statbuf);
0230 
0231   puts ("Testing if name02 is now a symlink");
0232 
0233   if (S_ISLNK(statbuf.st_mode) != 0) {
0234     FS_PASS ();
0235   } else {
0236     FS_FAIL ();
0237   }
0238 
0239   /*
0240    * Clear directory
0241    */
0242 
0243   EXPECT_EQUAL (0, unlink, name01);
0244   EXPECT_EQUAL (0, unlink, name02);
0245   EXPECT_EQUAL (-1, unlink, symlink01);
0246 
0247   /*
0248    * The new argument points to a symbolic link to another file and
0249    * the old argument points to a file.
0250    */
0251 
0252   puts ("\nNew is a simbolic link and rename operates on the simbolic link itself\n");
0253 
0254   fd = creat (name01, mode);
0255   rtems_test_assert (fd >= 0);
0256   status = close (fd);
0257   rtems_test_assert (status == 0);
0258 
0259   fd = creat (name02, mode);
0260   rtems_test_assert (fd >= 0);
0261   status = close (fd);
0262   rtems_test_assert (status == 0);
0263 
0264   status = symlink (name01, symlink01);
0265   rtems_test_assert (status == 0);
0266 
0267   EXPECT_EQUAL (0, rename, name02, symlink01);
0268   EXPECT_EQUAL (0, lstat, symlink01, &statbuf);
0269 
0270   puts ("Testing that symlink01 is not a symlink");
0271 
0272   if (S_ISLNK(statbuf.st_mode) == 0) {
0273     FS_PASS ();
0274   } else {
0275     FS_FAIL ();
0276   }
0277 
0278   /*
0279    * Clear directory
0280    */
0281 
0282   EXPECT_EQUAL (0, unlink, name01);
0283   EXPECT_EQUAL (-1, unlink, name02);
0284   EXPECT_EQUAL (0, unlink, symlink01);
0285 
0286   /*
0287    * The new argument points to a file inside a directory and
0288    * the old argument points to a file which filepath contains
0289    * a symbolic link loop.
0290    */
0291 
0292   puts ("\nTesting with symbolic link loop's\n");
0293 
0294   status = symlink (symlink01, symlink02);
0295   rtems_test_assert (status == 0);
0296 
0297   status = symlink (symlink02, symlink01);
0298   rtems_test_assert (status == 0);
0299 
0300   rv = snprintf (path01, sizeof(path01), "%s/test", symlink01);
0301   rtems_test_assert (rv < sizeof(path01));
0302   EXPECT_ERROR (ELOOP, rename, path01, name01);
0303 
0304   rv = snprintf (path01, sizeof(path01), "%s/test", symlink02);
0305   rtems_test_assert (rv < sizeof(path01));
0306   EXPECT_ERROR (ELOOP, rename, path01, name01);
0307 
0308   /*
0309    * Clear directory
0310    */
0311 
0312   EXPECT_EQUAL (-1, unlink, name01);
0313   EXPECT_EQUAL (0, unlink, symlink01);
0314   EXPECT_EQUAL (0, unlink, symlink02);
0315 
0316   /*
0317    * The new argument points to a file, which filepath contains
0318    * a symbolic link loop, and
0319    * the old argument points to a file inside a directory
0320    */
0321 
0322   fd = creat (name01, mode);
0323   rtems_test_assert (fd >= 0);
0324   status = close (fd);
0325   rtems_test_assert (status == 0);
0326 
0327   status = symlink (symlink01, symlink02);
0328   rtems_test_assert (status == 0);
0329 
0330   status = symlink (symlink02, symlink01);
0331   rtems_test_assert (status == 0);
0332 
0333   rv = snprintf (path01, sizeof(path01), "%s/test", symlink01);
0334   rtems_test_assert (rv < sizeof(path01));
0335   EXPECT_ERROR (ELOOP, rename, name01, path01);
0336 
0337   rv = snprintf (path01, sizeof(path01), "%s/test", symlink02);
0338   rtems_test_assert (rv < sizeof(path01));
0339   EXPECT_ERROR (ELOOP, rename, name01, path01);
0340 
0341   /*
0342    * Clear directory
0343    */
0344 
0345   EXPECT_EQUAL (0, unlink, name01);
0346   EXPECT_EQUAL (0, unlink, symlink01);
0347   EXPECT_EQUAL (0, unlink, symlink02);
0348 
0349   /*
0350    * Go back to parent directory
0351    */
0352 
0353   status = chdir ("..");
0354   rtems_test_assert (status == 0);
0355 
0356   /*
0357    * Remove test directory
0358    */
0359 
0360   status = rmdir (wd);
0361   rtems_test_assert (status == 0);
0362 }
0363 
0364 static void symlink_rename_self (void)
0365 {
0366   int fd;
0367   int status;
0368   int rv;
0369 
0370   const char *name01 = "name01";
0371   const char *name02 = "name02";
0372 
0373   const char *dir01 = "dir01";
0374 
0375   char path01[30];
0376 
0377   mode_t mode = S_IRWXU | S_IRWXG | S_IRWXO;
0378   const char *wd = __func__;
0379 
0380   /*
0381    * Create a new directory and change the current directory to this
0382    */
0383 
0384   status = mkdir (wd, mode);
0385   rtems_test_assert (status == 0);
0386   status = chdir (wd);
0387   rtems_test_assert (status == 0);
0388 
0389   /*
0390   * The new argument points to a file and
0391   * the old argument points to the same file from another directory.
0392   */
0393 
0394   puts ("\nRename file with itself through a hard link in another directory\n");
0395 
0396   fd = creat (name01, mode);
0397   rtems_test_assert (fd >= 0);
0398   status = close (fd);
0399   rtems_test_assert (status == 0);
0400 
0401   status = mkdir (dir01, mode);
0402   rtems_test_assert (status == 0);
0403 
0404   rv = snprintf (path01, sizeof(path01), "%s/%s", dir01, name02);
0405   rtems_test_assert (rv < sizeof(path01));
0406   status = link (name01, path01);
0407   rtems_test_assert (status == 0);
0408 
0409   EXPECT_EQUAL (0, rename, name01, path01);
0410 
0411   /*
0412   * Clear directory
0413   */
0414 
0415   EXPECT_EQUAL (0, unlink, name01);
0416   EXPECT_EQUAL (0, unlink, path01);
0417   EXPECT_EQUAL (0, rmdir, dir01);
0418 
0419   /*
0420    * Go back to parent directory
0421    */
0422 
0423   status = chdir ("..");
0424   rtems_test_assert (status == 0);
0425 
0426   /*
0427    * Remove test directory
0428    */
0429 
0430   status = rmdir (wd);
0431   rtems_test_assert (status == 0);
0432 }
0433 
0434 void test(void )
0435 {
0436 
0437   symlink_test01();
0438   symlink_loop_error_test();
0439   symlink_rename_test();
0440   symlink_rename_self();
0441 }
0442