xref: /minix3/minix/tests/test61.c (revision a758ec672ed282a06b16d4ff9c990e6cf336a18f)
1433d6423SLionel Sambuc #include <sys/types.h>
2433d6423SLionel Sambuc #include <sys/stat.h>
3433d6423SLionel Sambuc #include <sys/wait.h>
4433d6423SLionel Sambuc #include <sys/syslimits.h>
5433d6423SLionel Sambuc #include <fcntl.h>
6433d6423SLionel Sambuc #include <stdio.h>
7433d6423SLionel Sambuc #include <unistd.h>
8433d6423SLionel Sambuc 
9433d6423SLionel Sambuc int max_error = 5;
10433d6423SLionel Sambuc #include "common.h"
11433d6423SLionel Sambuc 
12433d6423SLionel Sambuc 
13433d6423SLionel Sambuc void dangling_slink(int sub_test, char const slink_to[PATH_MAX]);
14433d6423SLionel Sambuc 
dangling_slink(int sub_test,char const slink_to[PATH_MAX])15433d6423SLionel Sambuc void dangling_slink(int sub_test, char const slink_to[PATH_MAX])
16433d6423SLionel Sambuc {
17433d6423SLionel Sambuc   pid_t child;
18433d6423SLionel Sambuc 
19433d6423SLionel Sambuc   subtest = sub_test;
20433d6423SLionel Sambuc 
21433d6423SLionel Sambuc   child = fork();
22433d6423SLionel Sambuc   if (child == (pid_t) -1) {
23433d6423SLionel Sambuc 	e(1);
24433d6423SLionel Sambuc 	return;
25433d6423SLionel Sambuc   } else if (child == (pid_t) 0) {
26433d6423SLionel Sambuc 	/* I'm the child. Create a dangling symlink with an absolute path */
27433d6423SLionel Sambuc 	int fd;
28433d6423SLionel Sambuc 	char buf[4];
29433d6423SLionel Sambuc 
30433d6423SLionel Sambuc 
31433d6423SLionel Sambuc 	/* We don't want to actually write to '/', so instead we pretend */
32433d6423SLionel Sambuc 	if (chroot(".") != 0) e(2);
33433d6423SLionel Sambuc 
34433d6423SLionel Sambuc 	/* Create file 'slink_to' with contents "bar" */
35433d6423SLionel Sambuc 	if ((fd = open(slink_to, O_CREAT|O_WRONLY)) == -1) e(3);
36433d6423SLionel Sambuc 	if (write(fd, "bar", strlen("bar")) != strlen("bar")) e(4);
37433d6423SLionel Sambuc 	close(fd);
38433d6423SLionel Sambuc 
39433d6423SLionel Sambuc 	if (symlink(slink_to, "a") == -1) e(5); /* Create the symlink */
40433d6423SLionel Sambuc 	if (rename(slink_to, "c") == -1) e(6); /* Make it a dangling symlink */
41433d6423SLionel Sambuc 
42433d6423SLionel Sambuc 	/* Write "foo" to symlink; this should recreate file 'slink_to' with
43433d6423SLionel Sambuc 	 * contents "foo" */
44433d6423SLionel Sambuc 	if ((fd = open("a", O_CREAT|O_WRONLY)) == -1) e(7);
45433d6423SLionel Sambuc 	if (write(fd, "foo", strlen("foo")) != strlen("foo")) e(8);
46433d6423SLionel Sambuc 	close(fd);
47433d6423SLionel Sambuc 
48433d6423SLionel Sambuc 	/* Verify 'a' and 'slink_to' contain "foo" */
49433d6423SLionel Sambuc 	memset(buf, '\0', sizeof(buf));
50433d6423SLionel Sambuc 	if ((fd = open("a", O_RDONLY)) == -1) e(9);
51433d6423SLionel Sambuc 	if (read(fd, buf, 3) != 3) e(10);
52433d6423SLionel Sambuc 	if (strncmp(buf, "foo", strlen("foo"))) e(11);
53433d6423SLionel Sambuc 	close(fd);
54433d6423SLionel Sambuc 	memset(buf, '\0', sizeof(buf));
55433d6423SLionel Sambuc 	if ((fd = open(slink_to, O_RDONLY)) == -1) e(12);
56433d6423SLionel Sambuc 	if (read(fd, buf, 3) != 3) e(13);
57433d6423SLionel Sambuc 	if (strncmp(buf, "foo", strlen("foo"))) e(14);
58433d6423SLionel Sambuc 	close(fd);
59433d6423SLionel Sambuc 
60433d6423SLionel Sambuc 	/* Verify 'c' contains 'bar' */
61433d6423SLionel Sambuc 	memset(buf, '\0', sizeof(buf));
62433d6423SLionel Sambuc 	if ((fd = open("c", O_RDONLY)) == -1) e(15);
63433d6423SLionel Sambuc 	if (read(fd, buf, 3) != 3) e(16);
64433d6423SLionel Sambuc 	if (strncmp(buf, "bar", strlen("bar"))) e(17);
65433d6423SLionel Sambuc 	close(fd);
66433d6423SLionel Sambuc 
67433d6423SLionel Sambuc 	/* Cleanup created files */
68433d6423SLionel Sambuc 	if (unlink(slink_to) == -1) e(18);
69*a758ec67SDavid van Moolenbroek 	if (unlink("c") == -1) e(19);
70*a758ec67SDavid van Moolenbroek 
71*a758ec67SDavid van Moolenbroek 	/* Use the dangling symlink to test mknod(2) following symlinks */
72*a758ec67SDavid van Moolenbroek 	if (mknod("a", S_IFCHR | 0777, makedev(1, 1)) != -1) e(20);
73*a758ec67SDavid van Moolenbroek 	if (errno != EEXIST) e(21);
74*a758ec67SDavid van Moolenbroek 	if (unlink("a") == -1) e(22);
75433d6423SLionel Sambuc 
76433d6423SLionel Sambuc 	exit(EXIT_SUCCESS);
77433d6423SLionel Sambuc   } else {
78433d6423SLionel Sambuc 	int status;
79433d6423SLionel Sambuc 	if (wait(&status) == -1) e(7);
80433d6423SLionel Sambuc   }
81433d6423SLionel Sambuc 
82433d6423SLionel Sambuc 
83433d6423SLionel Sambuc }
84433d6423SLionel Sambuc 
main(int argc,char * argv[])85433d6423SLionel Sambuc int main(int argc, char *argv[])
86433d6423SLionel Sambuc {
87433d6423SLionel Sambuc   start(61);
88433d6423SLionel Sambuc   dangling_slink(1, "/abs"); /* Create dangling symlink with absolute path */
89433d6423SLionel Sambuc   dangling_slink(2, "rel"); /* Create dangling symlink with relative path */
90433d6423SLionel Sambuc   quit();
91433d6423SLionel Sambuc   return(-1);	/* Unreachable */
92433d6423SLionel Sambuc }
93433d6423SLionel Sambuc 
94