<sys/syslimits.h>
[minix3.git] / test / test58.c
blob0988ab399c2dcca53f2289e24fd808526896fa4f
1 /* This tests the behavior of Minix when the current working dir (cwd) doesn't
2 * actually exist and we either:
3 * - create a new file
4 * - make a new directory
5 * - make a special file (mknod)
6 * - create a hard link
7 * - create a symbolic link, or
8 * - rename a file
9 * In each case, `a component of the path does not name an existing file', and
10 * the operation should fail with ENOENT. These tests should actually be
11 * distributed over the other tests that actually test the specific system
12 * calls.
15 #include <stdio.h>
16 #include <errno.h>
17 #include <fcntl.h>
18 #include <unistd.h>
19 #include <sys/socket.h>
20 #include <sys/types.h>
21 #include <sys/wait.h>
22 #include <sys/stat.h>
23 #include <sys/syslimits.h>
25 int subtest = -1;
26 int max_error = 999; /* Effectively no limit. This is necessary as this
27 * test tries to undo errors and should therefore not
28 * preemptively exit, as that would leave the FS
29 * in a corrupted state. */
31 #include "common.h"
33 #define TEST_PATH "a/b/c"
34 #define INTEGR_MSG "You might want to check fs integrity\n"
36 void do_test(void);
38 void do_test(void)
40 int r, fd;
41 int s[2];
42 char buf[1], testroot[PATH_MAX+1], renamebuf[PATH_MAX+1];
44 subtest = 1;
45 if (socketpair(PF_UNIX, SOCK_STREAM, 0, s) == -1) e(1);
46 if (system("mkdir -p " TEST_PATH) == -1) e(2);
47 if (realpath(".", testroot) == NULL) e(3);
49 r = fork();
50 if (r == -1) e(4);
51 else if (r == 0) { /* Child */
52 /* Change child's cwd to TEST_PATH */
53 if (chdir(TEST_PATH) == -1) e(5);
55 /* Signal parent we're ready for the test */
56 buf[0] = 'a';
57 if (write(s[0], buf, sizeof(buf)) != sizeof(buf)) e(6);
59 /* Wait for parent to remove my cwd */
60 if (read(s[0], buf, sizeof(buf)) != sizeof(buf)) e(7);
62 /* Try to create a file */
63 if ((fd = open("testfile", O_RDWR | O_CREAT)) != -1) {
64 e(8);
65 /* Uh oh. We created a file?! Try to remove it. */
66 (void) close(fd);
67 if (unlink("testfile") != 0) {
68 /* This is not good. We created a file, but we can
69 * never access it; we have a spurious inode.
71 e(9);
72 printf(INTEGR_MSG);
73 exit(errct);
76 if (errno != ENOENT) e(10);
78 /* Try to create a dir */
79 errno = 0;
80 if (mkdir("testdir", 0777) == 0) {
81 e(11);
82 /* Uh oh. This shouldn't have been possible. Try to undo. */
83 if (rmdir("testdir") != 0) {
84 /* Not good. */
85 e(12);
86 printf(INTEGR_MSG);
87 exit(errct);
90 if (errno != ENOENT) e(13);
92 /* Try to create a special file */
93 errno = 0;
94 if (mknod("testnode", 0777 | S_IFIFO, 0) == 0) {
95 e(14);
96 /* Impossible. Try to make it unhappen. */
97 if (unlink("testnode") != 0) {
98 /* Not good. */
99 e(15);
100 printf(INTEGR_MSG);
101 exit(errct);
104 if (errno != ENOENT) e(16);
106 /* Try to rename a file */
107 errno = 0;
108 /* First create a file in the test dir */
109 snprintf(renamebuf, PATH_MAX, "%s/oldname", testroot);
110 if ((fd = open(renamebuf, O_RDWR | O_CREAT)) == -1) e(17);
111 if (close(fd) != 0) e(18);
113 /* Now try to rename that file to an entry in the current, non-existing
114 * working directory.
116 if (rename(renamebuf, "testrename") == 0) {
117 e(19);
118 /* This shouldn't have been possible. Revert the name change.
120 if (rename("testrename", renamebuf) != 0) {
121 /* Failed */
122 e(20);
123 printf(INTEGR_MSG);
124 exit(errct);
128 /* Try to create a hard link to that file */
129 errno = 0;
130 if (link(renamebuf, "testhlink") == 0) {
131 e(21);
132 /* Try to undo the hard link to prevent fs corruption. */
133 if (unlink("testhlink") != 0) {
134 /* Failed. */
135 e(22);
136 printf(INTEGR_MSG);
137 exit(errct);
140 if (errno != ENOENT) e(23);
142 /* Try to create a symlink */
143 errno = 0;
144 if (symlink(testroot, "testslink") == 0) {
145 e(24);
146 /* Try to remove the symlink to prevent fs corruption. */
147 if (unlink("testslink") != 0) {
148 /* Failed. */
149 e(25);
150 printf(INTEGR_MSG);
151 exit(errct);
154 if (errno != ENOENT) e(26);
156 exit(errct);
157 } else { /* Parent */
158 int status;
160 /* Wait for the child to enter the TEST_PATH dir */
161 if (read(s[1], buf, sizeof(buf)) != sizeof(buf)) e(27);
163 /* Delete TEST_PATH */
164 if (rmdir(TEST_PATH) != 0) e(28);
166 /* Tell child we removed its cwd */
167 buf[0] = 'b';
168 if (write(s[1], buf, sizeof(buf)) != sizeof(buf)) e(29);
170 wait(&status);
171 errct += WEXITSTATUS(status); /* Count errors */
175 int main(int argc, char* argv[])
177 start(58);
178 do_test();
179 quit();
180 return(-1); /* Unreachable */