source: trunk/minix/test/test8.c@ 20

Last change on this file since 20 was 9, checked in by Mattia Monga, 14 years ago

Minix 3.1.2a

File size: 6.4 KB
Line 
1/* test8: pipe() Author: Jan-Mark Wams (jms@cs.vu.nl) */
2
3#include <sys/types.h>
4#include <sys/stat.h>
5#include <sys/wait.h>
6#include <stdlib.h>
7#include <unistd.h>
8#include <string.h>
9#include <fcntl.h>
10#include <limits.h>
11#include <errno.h>
12#include <time.h>
13#include <stdio.h>
14
15#define MAX_ERROR 4
16#define ITERATIONS 60
17
18#define Fstat(a,b) if (fstat(a,b) != 0) printf("Can't fstat %d\n", a)
19#define Time(t) if (time(t) == (time_t)-1) printf("Time error\n")
20
21int errct = 0;
22int subtest = 1;
23char MaxName[NAME_MAX + 1]; /* Name of maximum length */
24char MaxPath[PATH_MAX]; /* Same for path */
25char ToLongName[NAME_MAX + 2]; /* Name of maximum +1 length */
26char ToLongPath[PATH_MAX + 1]; /* Same for path, both too long */
27
28_PROTOTYPE(void main, (int argc, char *argv[]));
29_PROTOTYPE(void test8a, (void));
30_PROTOTYPE(void test8b, (void));
31_PROTOTYPE(void e, (int number));
32_PROTOTYPE(void quit, (void));
33
34void main(argc, argv)
35int argc;
36char *argv[];
37{
38 int i, m = 0xFFFF;
39
40 sync();
41 if (argc == 2) m = atoi(argv[1]);
42 printf("Test 8 ");
43 fflush(stdout);
44
45 for (i = 0; i < ITERATIONS; i++) {
46 if (m & 0001) test8a();
47 if (m & 0002) test8b();
48 }
49 quit();
50}
51
52void test8a()
53{ /* Test fcntl flags. */
54 int tube[2], t1[2], t2[2], t3[2];
55 time_t time1, time2;
56 char buf[128];
57 struct stat st1, st2;
58 int stat_loc, flags;
59
60 subtest = 1;
61
62 /* Check if lowest fds are returned. */
63 if (pipe(tube) != 0) e(1);
64 if (tube[0] != 3 && tube[1] != 3) e(2);
65 if (tube[1] != 4 && tube[0] != 4) e(3);
66 if (tube[1] == tube[0]) e(4);
67 if (pipe(t1) != 0) e(5);
68 if (t1[0] != 5 && t1[1] != 5) e(6);
69 if (t1[1] != 6 && t1[0] != 6) e(7);
70 if (t1[1] == t1[0]) e(8);
71 if (close(t1[0]) != 0) e(9);
72 if (close(tube[0]) != 0) e(10);
73 if (pipe(t2) != 0) e(11);
74 if (t2[0] != tube[0] && t2[1] != tube[0]) e(12);
75 if (t2[1] != t1[0] && t2[0] != t1[0]) e(13);
76 if (t2[1] == t2[0]) e(14);
77 if (pipe(t3) != 0) e(15);
78 if (t3[0] != 7 && t3[1] != 7) e(16);
79 if (t3[1] != 8 && t3[0] != 8) e(17);
80 if (t3[1] == t3[0]) e(18);
81 if (close(tube[1]) != 0) e(19);
82 if (close(t1[1]) != 0) e(20);
83 if (close(t2[0]) != 0) e(21);
84 if (close(t2[1]) != 0) e(22);
85 if (close(t3[0]) != 0) e(23);
86 if (close(t3[1]) != 0) e(24);
87
88 /* All time fields should be marked for update. */
89 Time(&time1);
90 if (pipe(tube) != 0) e(25);
91 Fstat(tube[0], &st1);
92 Fstat(tube[1], &st2);
93 Time(&time2);
94 if (st1.st_atime < time1) e(26);
95 if (st1.st_ctime < time1) e(27);
96 if (st1.st_mtime < time1) e(28);
97 if (st1.st_atime > time2) e(29);
98 if (st1.st_ctime > time2) e(30);
99 if (st1.st_mtime > time2) e(31);
100 if (st2.st_atime < time1) e(32);
101 if (st2.st_ctime < time1) e(33);
102 if (st2.st_mtime < time1) e(34);
103 if (st2.st_atime > time2) e(35);
104 if (st2.st_ctime > time2) e(36);
105 if (st2.st_mtime > time2) e(37);
106
107 /* Check the file characteristics. */
108 if ((flags = fcntl(tube[0], F_GETFD)) != 0) e(38);
109 if ((flags & FD_CLOEXEC) != 0) e(39);
110 if ((flags = fcntl(tube[0], F_GETFL)) != 0) e(40);
111 if ((flags & O_RDONLY) != O_RDONLY) e(41);
112 if ((flags & O_NONBLOCK) != 0) e(42);
113 if ((flags & O_RDWR) != 0) e(43);
114 if ((flags & O_WRONLY) != 0) e(44);
115
116 if ((flags = fcntl(tube[1], F_GETFD)) != 0) e(45);
117 if ((flags & FD_CLOEXEC) != 0) e(46);
118 if ((flags = fcntl(tube[1], F_GETFL)) == -1) e(47);
119 if ((flags & O_WRONLY) != O_WRONLY) e(48);
120 if ((flags & O_NONBLOCK) != 0) e(49);
121 if ((flags & O_RDWR) != 0) e(50);
122 if ((flags & O_RDONLY) != 0) e(51);
123
124 /* Check if we can read and write. */
125 switch (fork()) {
126 case -1: printf("Can't fork\n"); break;
127 case 0:
128 alarm(20);
129 if (close(tube[0]) != 0) e(52);
130 if (write(tube[1], "Hello", 6) != 6) e(53);
131 if (close(tube[1]) != 0) e(54);
132 exit(0);
133 default:
134 if (read(tube[0], buf, sizeof(buf)) != 6) e(55);
135 if (strncmp(buf, "Hello", 6) != 0) e(56);
136 wait(&stat_loc);
137 if (stat_loc != 0) e(57); /* Alarm? */
138 }
139 if (close(tube[0]) != 0) e(58);
140 if (close(tube[1]) != 0) e(59);
141}
142
143void test8b()
144{
145 int tube[2], child2parent[2], parent2child[2];
146 int i, nchild = 0, nopen = 3, stat_loc;
147 int fd;
148 int forkfailed = 0;
149 char c;
150
151 subtest = 2;
152
153 /* Take all the pipes we can get. */
154 while (nopen < OPEN_MAX - 2) {
155 if (pipe(tube) != 0) {
156 /* We have not reached OPEN_MAX yet, so we have ENFILE. */
157 if (errno != ENFILE) e(1);
158 sleep(2); /* Wait for others to (maybe) closefiles. */
159 break;
160 }
161 nopen += 2;
162 }
163
164 if (nopen < OPEN_MAX - 2) {
165 if (pipe(tube) != -1) e(2);
166 switch (errno) {
167 case EMFILE: /* Errno value is ok. */
168 break;
169 case ENFILE: /* No process can open files any more. */
170 switch (fork()) {
171 case -1:
172 printf("Can't fork\n");
173 break;
174 case 0:
175 alarm(20);
176 if (open("/", O_RDONLY) != -1) e(3);
177 if (errno != ENFILE) e(4);
178 exit(0);
179 default:
180 wait(&stat_loc);
181 if (stat_loc != 0) e(5); /* Alarm? */
182 }
183 break;
184 default: /* Wrong value for errno. */
185 e(6);
186 }
187 }
188
189 /* Close all but stdin,out,err. */
190 for (i = 3; i < OPEN_MAX; i++) (void) close(i);
191
192 /* ENFILE test. Have children each grab OPEN_MAX fds. */
193 if (pipe(child2parent) != 0) e(7);
194 if (pipe(parent2child) != 0) e(8);
195 while (!forkfailed && (fd = open("/", O_RDONLY)) != -1) {
196 close(fd);
197 switch (fork()) {
198 case -1:
199 forkfailed = 1;
200 break;
201 case 0:
202 alarm(60);
203
204 /* Grab all the fds. */
205 while (pipe(tube) != -1);
206 while (open("/", O_RDONLY) != -1);
207
208 /* Signal parent OPEN_MAX fds gone. */
209 if (write(child2parent[1], "*", 1) != 1) e(9);
210
211 /* Wait for parent befor freeing all the fds. */
212 if (read(parent2child[0], &c, 1) != 1) e(10);
213 exit(0);
214 default:
215
216 /* Wait for child to grab OPEN_MAX fds. */
217 if (read(child2parent[0], &c, 1) != 1) e(11);
218 nchild++;
219 break;
220 }
221 }
222
223 if (!forkfailed) {
224 if (pipe(tube) != -1) e(12);
225 if (errno != ENFILE) e(13);
226 }
227
228 /* Signal children to die and wait for it. */
229 while (nchild-- > 0) {
230 if (write(parent2child[1], "*", 1) != 1) e(14);
231 wait(&stat_loc);
232 if (stat_loc != 0) e(15); /* Alarm? */
233 }
234
235 /* Close all but stdin,out,err. */
236 for (i = 3; i < OPEN_MAX; i++) (void) close(i);
237}
238
239void e(n)
240int n;
241{
242 int err_num = errno; /* Save in case printf clobbers it. */
243
244 printf("Subtest %d, error %d errno=%d: ", subtest, n, errno);
245 errno = err_num;
246 perror("");
247 if (errct++ > MAX_ERROR) {
248 printf("Too many errors; test aborted\n");
249 chdir("..");
250 system("rm -rf DIR*");
251 exit(1);
252 }
253 errno = 0;
254}
255
256void quit()
257{
258 if (errct == 0) {
259 printf("ok\n");
260 exit(0);
261 } else {
262 printf("%d errors\n", errct);
263 exit(1);
264 }
265}
Note: See TracBrowser for help on using the repository browser.