1 #include <sys/types.h> 2 #include <sys/stat.h> 3 #include <sys/wait.h> 4 #include <sys/syslimits.h> 5 #include <fcntl.h> 6 #include <stdio.h> 7 #include <unistd.h> 8 9 int max_error = 5; 10 #include "common.h" 11 12 13 void dangling_slink(int sub_test, char const slink_to[PATH_MAX]); 14 15 void dangling_slink(int sub_test, char const slink_to[PATH_MAX]) 16 { 17 pid_t child; 18 19 subtest = sub_test; 20 21 child = fork(); 22 if (child == (pid_t) -1) { 23 e(1); 24 return; 25 } else if (child == (pid_t) 0) { 26 /* I'm the child. Create a dangling symlink with an absolute path */ 27 int fd; 28 char buf[4]; 29 30 31 /* We don't want to actually write to '/', so instead we pretend */ 32 if (chroot(".") != 0) e(2); 33 34 /* Create file 'slink_to' with contents "bar" */ 35 if ((fd = open(slink_to, O_CREAT|O_WRONLY)) == -1) e(3); 36 if (write(fd, "bar", strlen("bar")) != strlen("bar")) e(4); 37 close(fd); 38 39 if (symlink(slink_to, "a") == -1) e(5); /* Create the symlink */ 40 if (rename(slink_to, "c") == -1) e(6); /* Make it a dangling symlink */ 41 42 /* Write "foo" to symlink; this should recreate file 'slink_to' with 43 * contents "foo" */ 44 if ((fd = open("a", O_CREAT|O_WRONLY)) == -1) e(7); 45 if (write(fd, "foo", strlen("foo")) != strlen("foo")) e(8); 46 close(fd); 47 48 /* Verify 'a' and 'slink_to' contain "foo" */ 49 memset(buf, '\0', sizeof(buf)); 50 if ((fd = open("a", O_RDONLY)) == -1) e(9); 51 if (read(fd, buf, 3) != 3) e(10); 52 if (strncmp(buf, "foo", strlen("foo"))) e(11); 53 close(fd); 54 memset(buf, '\0', sizeof(buf)); 55 if ((fd = open(slink_to, O_RDONLY)) == -1) e(12); 56 if (read(fd, buf, 3) != 3) e(13); 57 if (strncmp(buf, "foo", strlen("foo"))) e(14); 58 close(fd); 59 60 /* Verify 'c' contains 'bar' */ 61 memset(buf, '\0', sizeof(buf)); 62 if ((fd = open("c", O_RDONLY)) == -1) e(15); 63 if (read(fd, buf, 3) != 3) e(16); 64 if (strncmp(buf, "bar", strlen("bar"))) e(17); 65 close(fd); 66 67 /* Cleanup created files */ 68 if (unlink(slink_to) == -1) e(18); 69 if (unlink("c") == -1) e(19); 70 71 /* Use the dangling symlink to test mknod(2) following symlinks */ 72 if (mknod("a", S_IFCHR | 0777, makedev(1, 1)) != -1) e(20); 73 if (errno != EEXIST) e(21); 74 if (unlink("a") == -1) e(22); 75 76 exit(EXIT_SUCCESS); 77 } else { 78 int status; 79 if (wait(&status) == -1) e(7); 80 } 81 82 83 } 84 85 int main(int argc, char *argv[]) 86 { 87 start(61); 88 dangling_slink(1, "/abs"); /* Create dangling symlink with absolute path */ 89 dangling_slink(2, "rel"); /* Create dangling symlink with relative path */ 90 quit(); 91 return(-1); /* Unreachable */ 92 } 93 94