1 /* test25: open (), close () (p) Jan-Mark Wams. email: jms@cs.vu.nl */
3 /* Not tested: O_NONBLOCK on special files, supporting it.
4 ** On a read-only file system, some error reports are to be expected.
25 #define System(cmd) if (system(cmd) != 0) printf("``%s'' failed\n", cmd)
26 #define Chdir(dir) if (chdir(dir) != 0) printf("Can't goto %s\n", dir)
27 #define Stat(a,b) if (stat(a,b) != 0) printf("Can't stat %s\n", a)
28 #define Creat(f) if (close(creat(f,0777))!=0) printf("Can't creat %s\n",f)
29 #define Report(s,n) printf("Subtest %d" s,subtest,(n))
33 char *MaxName
; /* Name of maximum length */
34 char MaxPath
[PATH_MAX
]; /* Same for path */
35 char *ToLongName
; /* Name of maximum +1 length */
36 char ToLongPath
[PATH_MAX
+ 1]; /* Same for path, both too long */
43 void makelongnames(void);
45 int main(int argc
, char *argv
[])
52 if (argc
== 2) m
= atoi(argv
[1]);
54 superuser
= (geteuid() == 0);
56 /* Close all files, the parent might have opened. */
57 for (i
= 3; i
< 100; i
++) close(i
);
59 for (i
= 0; i
< ITERATIONS
; i
++) {
60 if (m
& 001) test25a();
61 if (m
& 002) test25b();
62 if (m
& 004) test25c();
63 if (m
& 010) test25d();
64 if (m
& 020) test25e();
68 return(-1); /* Unreachable */
72 { /* Test fcntl flags. */
75 #define EXCLUDE(a,b) (((a)^(b)) == ((a)|(b)))
76 #define ADDIT (O_APPEND | O_CREAT | O_EXCL | O_NONBLOCK | O_TRUNC)
78 /* If this compiles all flags are defined but they have to be or-able. */
79 if (!(EXCLUDE(O_NONBLOCK
, O_TRUNC
))) e(1);
80 if (!(EXCLUDE(O_EXCL
, O_NONBLOCK
| O_TRUNC
))) e(2);
81 if (!(EXCLUDE(O_CREAT
, O_EXCL
| O_NONBLOCK
| O_TRUNC
))) e(3);
82 if (!(EXCLUDE(O_APPEND
, O_CREAT
| O_EXCL
| O_NONBLOCK
| O_TRUNC
))) e(4);
83 if (!(EXCLUDE(O_RDONLY
, ADDIT
))) e(5);
84 if (!(EXCLUDE(O_WRONLY
, ADDIT
))) e(6);
85 if (!(EXCLUDE(O_RDWR
, ADDIT
))) e(7);
89 { /* Test normal operation. */
93 int fd1
, fd2
, fd3
, fd4
, fd5
;
95 struct stat st1
, st2
, st3
;
101 System("rm -rf ../DIR_25/*");
103 System("echo Hello > he"); /* make test files */
104 System("echo Hello > ha"); /* size 6 bytes */
105 System("echo Hello > hi");
106 System("echo Hello > ho");
108 /* Check path resolution. Check if lowest fds are returned */
109 if ((fd1
= open("he", O_RDONLY
)) != 3) e(1);
110 if (read(fd1
, buf
, BUF_SIZE
) != 6) e(2);
111 if ((fd2
= open("./ha", O_RDONLY
)) != 4) e(3);
112 if ((fd3
= open("../DIR_25/he", O_RDWR
)) != 5) e(4);
113 if ((fd4
= open("ho", O_WRONLY
)) != 6) e(5);
114 if (close(fd4
) != 0) e(6);
115 if (close(fd1
) != 0) e(7);
116 if ((fd1
= open("./././ho", O_RDWR
)) != 3) e(8);
117 if ((fd4
= open("../DIR_25/he", O_RDONLY
)) != 6) e(9);
118 if (close(fd2
) != 0) e(10);
119 if (close(fd3
) != 0) e(11);
120 if ((fd2
= open("ha", O_RDONLY
)) != 4) e(12);
121 if ((fd3
= open("/etc/passwd", O_RDONLY
)) != 5) e(13);
122 if (close(fd4
) != 0) e(14); /* close all */
123 if (close(fd1
) != 0) e(15);
124 if (close(fd3
) != 0) e(16);
126 /* Check if processes share fd2, and if they have independent new fds */
127 System("rm -rf /tmp/sema.25");
129 case -1: printf("Can't fork\n"); break;
132 if ((fd1
= open("he", O_WRONLY
)) != 3) e(17);
133 if ((fd3
= open("../././DIR_25/ha", O_WRONLY
)) != 5) e(18);
134 if ((fd4
= open("../DIR_25/hi", O_WRONLY
)) != 6) e(19);
135 if ((fd5
= open("ho", O_WRONLY
)) != 7) e(20);
136 system("while test ! -f /tmp/sema.25; do sleep 1; done"); /* parent */
137 if (read(fd2
, buf
, BUF_SIZE
) != 3) e(21); /* gets Hel */
138 if (strncmp(buf
, "lo\n", 3) != 0) e(22); /* we get lo */
139 if (close(fd1
) != 0) e(23);
140 if (close(fd2
) != 0) e(24);
141 if (close(fd3
) != 0) e(25);
142 if (close(fd4
) != 0) e(26);
143 if (close(fd5
) != 0) e(27);
147 if ((fd1
= open("ha", O_RDONLY
)) != 3) e(28);
148 if ((fd3
= open("./he", O_RDONLY
)) != 5) e(29);
149 if ((fd4
= open("../DIR_25/hi", O_RDWR
)) != 6) e(30);
150 if ((fd5
= open("ho", O_WRONLY
)) != 7) e(31);
151 if (close(fd1
) != 0) e(32);
152 if (read(fd2
, buf
, 3) != 3) e(33); /* get Hel */
153 Creat("/tmp/sema.25");
154 if (strncmp(buf
, "Hel", 3) != 0) e(34);
155 if (close(fd2
) != 0) e(35);
156 if (close(fd3
) != 0) e(36);
157 if (close(fd4
) != 0) e(37);
158 if (close(fd5
) != 0) e(38);
159 if (wait(&stat_loc
) == -1) e(39);
160 if (stat_loc
!= 0) e(40);
162 System("rm -f /tmp/sema.25");
164 /* Check if the file status information is updated correctly */
165 Stat("hi", &st1
); /* get info */
166 Stat("ha", &st2
); /* of files */
168 while (time1
>= time((time_t *)0))
170 if ((fd1
= open("hi", O_RDONLY
)) != 3) e(41); /* open files */
171 if ((fd2
= open("ha", O_WRONLY
)) != 4) e(42);
172 if (read(fd1
, buf
, 1) != 1) e(43); /* read one */
173 if (close(fd1
) != 0) e(44); /* close one */
174 Stat("hi", &st3
); /* get info */
175 if (st1
.st_uid
!= st3
.st_uid
) e(45);
176 if (st1
.st_gid
!= st3
.st_gid
) e(46); /* should be same */
177 if (st1
.st_mode
!= st3
.st_mode
) e(47);
178 if (st1
.st_size
!= st3
.st_size
) e(48);
179 if (st1
.st_nlink
!= st3
.st_nlink
) e(49);
180 if (st1
.st_mtime
!= st3
.st_mtime
) e(50);
181 if (st1
.st_ctime
!= st3
.st_ctime
) e(51);
182 #ifndef V1_FILESYSTEM
183 if (st1
.st_atime
>= st3
.st_atime
) e(52); /* except for atime. */
185 if (write(fd2
, "Howdy\n", 6) != 6) e(53); /* Update c & mtime. */
186 if ((fd1
= open("ha", O_RDWR
)) != 3) e(54);
187 if (read(fd1
, buf
, 6) != 6) e(55); /* Update atime. */
188 if (strncmp(buf
, "Howdy\n", 6) != 0) e(56);
189 if (close(fd1
) != 0) e(57);
191 if (st2
.st_uid
!= st3
.st_uid
) e(58);
192 if (st2
.st_gid
!= st3
.st_gid
) e(59); /* should be same */
193 if (st2
.st_mode
!= st3
.st_mode
) e(60);
194 if (st2
.st_nlink
!= st3
.st_nlink
) e(61);
195 if (st2
.st_ctime
>= st3
.st_ctime
) e(62);
196 #ifndef V1_FILESYSTEM
197 if (st2
.st_atime
>= st3
.st_atime
) e(63);
199 if (st2
.st_mtime
>= st3
.st_mtime
) e(64);
200 if (st2
.st_size
!= st3
.st_size
) e(65);
201 if (close(fd2
) != 0) e(66);
203 /* Let's see if RDONLY files are read only. */
204 if ((fd1
= open("hi", O_RDONLY
)) != 3) e(67);
205 if (write(fd1
, " again", 7) != -1) e(68); /* we can't write */
206 if (errno
!= EBADF
) e(69); /* a read only fd */
207 if (read(fd1
, buf
, 7) != 6) e(70); /* but we can read */
208 if (close(fd1
) != 0) e(71);
210 /* Let's see if WRONLY files are write only. */
211 if ((fd1
= open("hi", O_WRONLY
)) != 3) e(72);
212 if (read(fd1
, buf
, 7) != -1) e(73); /* we can't read */
213 if (errno
!= EBADF
) e(74); /* a write only fd */
214 if (write(fd1
, "hELLO", 6) != 6) e(75); /* but we can write */
215 if (close(fd1
) != 0) e(76);
217 /* Let's see if files are closable only once. */
218 if (close(fd1
) != -1) e(77);
219 if (errno
!= EBADF
) e(78);
221 /* Let's see how calling close() with bad fds is handled. */
222 if (close(10) != -1) e(79);
223 if (errno
!= EBADF
) e(80);
224 if (close(111) != -1) e(81);
225 if (errno
!= EBADF
) e(82);
226 if (close(-432) != -1) e(83);
227 if (errno
!= EBADF
) e(84);
229 /* Let's see if RDWR files are read & write able. */
230 if ((fd1
= open("hi", O_RDWR
)) != 3) e(85);
231 if (read(fd1
, buf
, 6) != 6) e(86); /* we can read */
232 if (strncmp(buf
, "hELLO", 6) != 0) e(87); /* and we can write */
233 if (write(fd1
, "Hello", 6) != 6) e(88); /* a read write fd */
234 if (close(fd1
) != 0) e(89);
236 /* Check if APPENDed files are realy appended */
237 if ((fd1
= open("hi", O_RDWR
| O_APPEND
)) != 3) e(90); /* open hi */
239 /* An open should set the file offset to 0. */
240 if (lseek(fd1
, (off_t
) 0, SEEK_CUR
) != 0) e(91);
242 /* Writing 0 bytes should not have an effect. */
243 if (write(fd1
, "", 0) != 0) e(92);
244 if (lseek(fd1
, (off_t
) 0, SEEK_CUR
) != 0) e(93); /* the end? */
246 /* A seek befor a wirte should not matter with O_APPEND. */
248 if (lseek(fd1
, (off_t
) - 3, SEEK_END
) != st1
.st_size
- 3) e(94);
250 /* By writing 1 byte, we force the offset to the end of the file */
251 if (write(fd1
, "1", 1) != 1) e(95);
253 if (lseek(fd1
, (off_t
) 0, SEEK_CUR
) != st1
.st_size
) e(96);
254 if (write(fd1
, "2", 1) != 1) e(97);
256 if (lseek(fd1
, (off_t
) 0, SEEK_CUR
) != st1
.st_size
) e(98);
257 if (write(fd1
, "3", 1) != 1) e(99);
259 if (lseek(fd1
, (off_t
) 0, SEEK_CUR
) != st1
.st_size
) e(100);
260 if (lseek(fd1
, (off_t
) - 2, SEEK_CUR
) <= 0) e(101);
261 if (write(fd1
, "4", 1) != 1) e(102);
263 /* Since the mode was O_APPEND, the offset should be reset to EOF */
265 if (lseek(fd1
, (off_t
) 0, SEEK_CUR
) != st1
.st_size
) e(103);
266 if (lseek(fd1
, (off_t
) - 4, SEEK_CUR
) != st1
.st_size
- 4) e(104);
267 if (read(fd1
, buf
, BUF_SIZE
) != 4) e(105);
268 if (strncmp(buf
, "1234", 4) != 0) e(106);
269 if (close(fd1
) != 0) e(107);
271 /* Check the effect of O_CREAT */
273 fd1
= open("ho", O_RDWR
| O_CREAT
, 0000);
274 if (fd1
!= 3) e(108);
276 if (memcmp(&st1
, &st2
, sizeof(struct stat
)) != 0) e(109);
277 if (read(fd1
, buf
, 6) != 6) e(110);
278 if (strncmp(buf
, "Hello\n", 6) != 0) e(111);
279 if (write(fd1
, "@", 1) != 1) e(112);
280 if (close(fd1
) != 0) e(113);
282 fd1
= open("ho", O_RDWR
| O_CREAT
| O_EXCL
, 0777);
283 if (fd1
!= -1) e(114); /* ho exists */
284 System("rm -rf new");
286 while (time1
>= time((time_t *)0))
288 fd1
= open("new", O_RDWR
| O_CREAT
, 0716);
289 if (fd1
!= 3) e(115); /* new file */
292 while (time2
>= time((time_t *)0))
295 if (st1
.st_uid
!= geteuid()) e(116); /* try this as superuser. */
296 if (st1
.st_gid
!= getegid()) e(117);
297 if ((st1
.st_mode
& 0777) != 0716) e(118);
298 if (st1
.st_nlink
!= 1) e(119);
299 if (st1
.st_mtime
<= time1
) e(120);
300 if (st1
.st_mtime
>= time2
) e(121);
301 #ifndef V1_FILESYSTEM
302 if (st1
.st_atime
!= st1
.st_mtime
) e(122);
304 if (st1
.st_ctime
!= st1
.st_mtime
) e(123);
305 if (st1
.st_size
!= 0) e(124);
306 if (write(fd1
, "I'm new in town", 16) != 16) e(125);
307 if (lseek(fd1
, (off_t
) - 5, SEEK_CUR
) != 11) e(126);
308 if (read(fd1
, buf
, 5) != 5) e(127);
309 if (strncmp(buf
, "town", 5) != 0) e(128);
310 if (close(fd1
) != 0) e(129);
312 /* Let's test the O_TRUNC flag on this new file. */
314 while (time1
>= time((time_t *)0));
315 if ((fd1
= open("new", O_RDWR
| O_TRUNC
)) != 3) e(130);
318 while (time2
>= time((time_t *)0));
320 if ((st1
.st_mode
& 0777) != 0716) e(131);
321 if (st1
.st_size
!= (size_t) 0) e(132); /* TRUNCed ? */
322 if (st1
.st_mtime
<= time1
) e(133);
323 if (st1
.st_mtime
>= time2
) e(134);
324 if (st1
.st_ctime
!= st1
.st_mtime
) e(135);
325 if (close(fd1
) != 0) e(136);
327 /* Test if file permission bits and the file ownership are unchanged. */
328 /* So we will see if `O_CREAT' has no effect if the file exists. */
330 System("echo > bar; chmod 077 bar"); /* Make bar 077 */
331 System("chown daemon bar");
332 System("chgrp daemon bar"); /* Daemon's bar */
333 fd1
= open("bar", O_RDWR
| O_CREAT
| O_TRUNC
, 0777); /* knock knock */
334 if (fd1
== -1) e(137);
335 if (write(fd1
, "foo", 3) != 3) e(138); /* rewrite bar */
336 if (close(fd1
) != 0) e(139);
338 if (st1
.st_uid
!= 1) e(140); /* bar is still */
339 if (st1
.st_gid
!= 1) e(141); /* owned by daemon */
340 if ((st1
.st_mode
& 0777) != 077) e(142); /* mode still is 077 */
341 if (st1
.st_size
!= (size_t) 3) e(143); /* 3 bytes long */
343 /* We do the whole thing again, but with O_WRONLY */
344 fd1
= open("bar", O_WRONLY
| O_CREAT
| O_TRUNC
, 0777);
345 if (fd1
== -1) e(144);
346 if (write(fd1
, "foobar", 6) != 6) e(145); /* rewrite bar */
347 if (close(fd1
) != 0) e(146);
349 if (st1
.st_uid
!= 1) e(147); /* bar is still */
350 if (st1
.st_gid
!= 1) e(148); /* owned by daemon */
351 if ((st1
.st_mode
& 0777) != 077) e(149); /* mode still is 077 */
352 if (st1
.st_size
!= (size_t) 6) e(150); /* 6 bytes long */
357 { /* Test normal operation Part two. */
362 static int iteration
=0;
367 System("rm -rf ../DIR_25/*");
369 /* Fifo file test here. */
370 if (mkfifo("fifo", 0777) != 0) e(1);
372 case -1: printf("Can't fork\n"); break;
374 alarm(20); /* Give child 20 seconds to live. */
375 if ((fd1
= open("fifo", O_RDONLY
)) != 3) e(2);
376 if (read(fd1
, buf
, BUF_SIZE
) != 23) e(3);
377 if (strncmp(buf
, "1 2 3 testing testing\n", 23) != 0) e(4);
378 if (close(fd1
) != 0) e(5);
381 if ((fd1
= open("fifo", O_WRONLY
)) != 3) e(6);
382 if (write(fd1
, "1 2 3 testing testing\n", 23) != 23) e(7);
383 if (close(fd1
) != 0) e(8);
384 if (wait(&stat_loc
) == -1) e(9);
385 if (stat_loc
!= 0) e(10); /* The alarm went off? */
388 /* Try opening for writing with O_NONBLOCK. */
389 fd1
= open("fifo", O_WRONLY
| O_NONBLOCK
);
390 if (fd1
!= -1) e(11);
391 if (errno
!= ENXIO
) e(12);
394 /* Try opening for writing with O_NONBLOCK and O_CREAT. */
395 fd1
= open("fifo", O_WRONLY
| O_CREAT
| O_NONBLOCK
, 0777);
396 if (fd1
!= -1) e(13);
397 if (errno
!= ENXIO
) e(14);
400 /* Both the NONBLOCK and the EXCLusive give raise to error. */
401 fd1
= open("fifo", O_WRONLY
| O_CREAT
| O_EXCL
| O_NONBLOCK
, 0777);
402 if (fd1
!= -1) e(15);
403 if (errno
!= EEXIST
&& errno
!= ENXIO
) e(16);
404 close(fd1
); /* Just in case. */
406 /* Try opening for reading with O_NONBLOCK. */
407 fd1
= open("fifo", O_RDONLY
| O_NONBLOCK
);
409 if (close(fd1
) != 0) e(18);
411 /* Nopt runs out of memory. ;-< We just cut out some valid code */
412 /* FIFO's should always append. (They have no file position.) */
414 case -1: printf("Can't fork\n"); break;
416 alarm(20); /* Give child 20 seconds to live. */
417 if ((fd1
= open("fifo", O_WRONLY
)) != 3) e(19);
418 if ((fd2
= open("fifo", O_WRONLY
)) != 4) e(20);
419 if (write(fd1
, "I did see Elvis.\n", 18) != 18) e(21);
420 if (write(fd2
, "I DID.\n", 8) != 8) e(22);
421 if (close(fd2
) != 0) e(23);
422 if (close(fd1
) != 0) e(24);
425 if ((fd1
= open("fifo", O_RDONLY
)) != 3) e(25);
426 if (read(fd1
, buf
, 18) != 18) e(26);
427 if (strncmp(buf
, "I did see Elvis.\n", 18) != 0) e(27);
428 if (read(fd1
, buf
, BUF_SIZE
) != 8) e(28);
429 if (strncmp(buf
, "I DID.\n", 8) != 0) e(29);
430 if (close(fd1
) != 0) e(30);
431 if (wait(&stat_loc
) == -1) e(31);
432 if (stat_loc
!= 0) e(32); /* The alarm went off? */
435 /* O_TRUNC should have no effect on FIFO files. */
437 case -1: printf("Can't fork\n"); break;
439 alarm(20); /* Give child 20 seconds to live. */
440 if ((fd1
= open("fifo", O_WRONLY
)) != 3) e(33);
441 if (write(fd1
, "I did see Elvis.\n", 18) != 18) e(34);
442 if ((fd2
= open("fifo", O_WRONLY
| O_TRUNC
)) != 4) e(35);
443 if (write(fd2
, "I DID.\n", 8) != 8) e(36);
444 if (close(fd2
) != 0) e(37);
445 if (close(fd1
) != 0) e(38);
448 if ((fd1
= open("fifo", O_RDONLY
)) != 3) e(39);
449 if (read(fd1
, buf
, 18) != 18) e(40);
450 if (strncmp(buf
, "I did see Elvis.\n", 18) != 0) e(41);
451 if (read(fd1
, buf
, BUF_SIZE
) != 8) e(42);
452 if (strncmp(buf
, "I DID.\n", 8) != 0) e(43);
453 if (close(fd1
) != 0) e(44);
454 if (wait(&stat_loc
) == -1) e(45);
455 if (stat_loc
!= 0) e(46); /* The alarm went off? */
458 /* Closing the last fd should flush all data to the bitbucket. */
459 System("rm -rf /tmp/sema.25");
461 case -1: printf("Can't fork\n"); break;
464 alarm(20); /* Give child 20 seconds to live. */
465 if ((fd1
= open("fifo", O_WRONLY
)) != 3) e(47);
466 if (write(fd1
, "I did see Elvis.\n", 18) != 18) e(48);
467 Creat("/tmp/sema.25");
468 sleep(2); /* give parent a chance to open */
469 /* this was sleep(1), but that's too short: child also sleeps(1) */
470 if (close(fd1
) != 0) e(49);
474 if ((fd1
= open("fifo", O_RDONLY
)) != 3) e(50);
475 /* Make `sure' write has closed. */
476 while (stat("/tmp/sema.25", &st
) != 0) sleep(1);
477 if (close(fd1
) != 0) e(51);
478 if ((fd1
= open("fifo", O_RDONLY
| O_NONBLOCK
)) != 3) e(52);
479 if (read(fd1
, buf
, BUF_SIZE
) != 18) e(53);
480 if (close(fd1
) != 0) e(54);
481 if (wait(&stat_loc
) == -1) e(55);
482 if (stat_loc
!= 0) e(56); /* The alarm went off? */
485 /* Let's try one too many. */
486 System("rm -rf /tmp/sema.25");
488 case -1: printf("Can't fork\n"); break;
490 alarm(20); /* Give child 20 seconds to live. */
491 if ((fd1
= open("fifo", O_WRONLY
)) != 3) e(57);
492 if (write(fd1
, "I did see Elvis.\n", 18) != 18) e(58);
494 /* Keep open till third reader is opened. */
495 while (stat("/tmp/sema.25", &st
) != 0) sleep(1);
496 if (close(fd1
) != 0) e(59);
499 if ((fd1
= open("fifo", O_RDONLY
)) != 3) e(60);
500 if (read(fd1
, buf
, 2) != 2) e(61);
501 if (strncmp(buf
, "I ", 2) != 0) e(62);
502 if (close(fd1
) != 0) e(63);
503 if ((fd1
= open("fifo", O_RDONLY
)) != 3) e(64);
504 if (read(fd1
, buf
, 4) != 4) e(65);
505 if (strncmp(buf
, "did ", 4) != 0) e(66);
506 if ((fd2
= open("fifo", O_RDONLY
)) != 4) e(67);
508 /* Signal third reader is open. */
509 Creat("/tmp/sema.25");
510 if (read(fd2
, buf
, BUF_SIZE
) != 12) e(68);
511 if (strncmp(buf
, "see Elvis.\n", 12) != 0) e(69);
512 if (close(fd2
) != 0) e(70);
513 if (close(fd1
) != 0) e(71);
514 if (wait(&stat_loc
) == -1) e(72);
515 if (stat_loc
!= 0) e(73); /* The alarm went off? */
517 System("rm -rf fifo /tmp/sema.25");
519 /* O_TRUNC should have no effect on directroys. */
520 System("mkdir dir; touch dir/f1 dir/f2 dir/f3");
521 if ((fd1
= open("dir", O_WRONLY
| O_TRUNC
)) != -1) e(74);
522 if (errno
!= EISDIR
) e(75);
525 /* Opening a directory for reading should be possible. */
526 if ((fd1
= open("dir", O_RDONLY
)) != 3) e(76);
527 if (close(fd1
) != 0) e(77);
528 if (unlink("dir/f1") != 0) e(78); /* Should still be there. */
529 if (unlink("dir/f2") != 0) e(79);
530 if (unlink("dir/f3") != 0) e(80);
531 if (rmdir("dir") != 0) e(81);
534 /* Test if O_CREAT is not usable to open files with the wrong mode */
535 (void) umask(0200); /* nono has no */
536 System("touch nono"); /* write bit */
538 fd1
= open("nono", O_RDWR
| O_CREAT
, 0777); /* try to open */
539 if (fd1
!= -1) e(82);
540 if (errno
!= EACCES
) e(83); /* but no access */
550 System("rm -rf ../DIR_25/*");
552 /* Test maximal file name length. */
553 if ((fd
= open(MaxName
, O_RDWR
| O_CREAT
, 0777)) != 3) e(1);
554 if (close(fd
) != 0) e(2);
555 MaxPath
[strlen(MaxPath
) - 2] = '/';
556 MaxPath
[strlen(MaxPath
) - 1] = 'a'; /* make ././.../a */
557 if ((fd
= open(MaxPath
, O_RDWR
| O_CREAT
, 0777)) != 3) e(3);
558 if (close(fd
) != 0) e(4);
559 MaxPath
[strlen(MaxPath
) - 1] = '/'; /* make ././.../a */
564 int fd
, does_truncate
;
565 char *noread
= "noread"; /* Name for unreadable file. */
566 char *nowrite
= "nowrite"; /* Same for unwritable. */
571 System("rm -rf ../DIR_25/*");
573 mkdir("bar", 0777); /* make bar */
575 /* Check if no access on part of path generates the correct error. */
576 System("chmod 677 bar"); /* rw-rwxrwx */
577 if (open("bar/nono", O_RDWR
| O_CREAT
, 0666) != -1) e(1);
578 if (errno
!= EACCES
) e(2);
580 /* Ditto for no write permission. */
581 System("chmod 577 bar"); /* r-xrwxrwx */
582 if (open("bar/nono", O_RDWR
| O_CREAT
, 0666) != -1) e(3);
583 if (errno
!= EACCES
) e(4);
586 System("rm -rf bar");
588 /* Improper flags set on existing file. */
589 System("touch noread; chmod 377 noread"); /* noread */
590 if (open(noread
, O_RDONLY
) != -1) e(5);
591 if (open(noread
, O_RDWR
) != -1) e(6);
592 if (open(noread
, O_RDWR
| O_CREAT
, 0777) != -1) e(7);
593 if (open(noread
, O_RDWR
| O_CREAT
| O_TRUNC
, 0777) != -1) e(8);
594 if ((fd
= open(noread
, O_WRONLY
)) != 3) e(9);
595 if (close(fd
) != 0) e(10);
596 System("touch nowrite; chmod 577 nowrite"); /* nowrite */
597 if (open(nowrite
, O_WRONLY
) != -1) e(11);
598 if (open(nowrite
, O_RDWR
) != -1) e(12);
599 if (open(nowrite
, O_RDWR
| O_CREAT
, 0777) != -1) e(13);
600 if (open(nowrite
, O_RDWR
| O_CREAT
| O_TRUNC
, 0777) != -1) e(14);
601 if ((fd
= open(nowrite
, O_RDONLY
)) != 3) e(15);
602 if (close(fd
) != 0) e(16);
604 /* If we can make a file ownd by some one else, test access again. */
605 System("chmod 733 noread");
606 System("chown bin noread");
607 System("chgrp system noread");
608 System("chmod 755 nowrite");
609 System("chown bin nowrite");
610 System("chgrp system nowrite");
612 case -1: printf("Can't fork\n"); break;
615 setgid(1); /* become daemon */
616 if (open(noread
, O_RDONLY
) != -1) e(17);
617 if (open(noread
, O_RDWR
) != -1) e(18);
618 if (open(noread
, O_RDWR
| O_CREAT
, 0777) != -1) e(19);
619 fd
= open(noread
, O_RDWR
| O_CREAT
| O_TRUNC
, 0777);
621 if ((fd
= open(noread
, O_WRONLY
)) != 3) e(21);
622 if (close(fd
) != 0) e(22);
623 if (open(nowrite
, O_WRONLY
) != -1) e(23);
624 if (open(nowrite
, O_RDWR
) != -1) e(24);
625 if (open(nowrite
, O_RDWR
| O_CREAT
, 0777) != -1) e(25);
626 fd
= open(nowrite
, O_RDWR
| O_CREAT
| O_TRUNC
, 0777);
628 if ((fd
= open(nowrite
, O_RDONLY
)) != 3) e(27);
629 if (close(fd
) != 0) e(28);
632 if (wait(&stat_loc
) == -1) e(29);
636 /* Clean up the noread and nowrite files. */
637 System("rm -rf noread nowrite");
639 /* Test the O_EXCL flag. */
640 System("echo > exists");
641 if (open("exists", O_RDWR
| O_CREAT
| O_EXCL
, 0777) != -1) e(30);
642 if (errno
!= EEXIST
) e(31);
643 if (open("exists", O_RDONLY
| O_CREAT
| O_EXCL
, 0777) != -1) e(32);
644 if (errno
!= EEXIST
) e(33);
645 if (open("exists", O_WRONLY
| O_CREAT
| O_EXCL
, 0777) != -1) e(34);
646 if (errno
!= EEXIST
) e(35);
647 fd
= open("exists", O_RDWR
| O_CREAT
| O_EXCL
| O_TRUNC
, 0777);
649 if (errno
!= EEXIST
) e(37);
650 fd
= open("exists", O_RDONLY
| O_CREAT
| O_EXCL
| O_TRUNC
, 0777);
652 if (errno
!= EEXIST
) e(39);
653 fd
= open("exists", O_WRONLY
| O_CREAT
| O_EXCL
| O_TRUNC
, 0777);
655 if (errno
!= EEXIST
) e(41);
657 /* open should fail when O_CREAT|O_EXCL are set and a symbolic link names
658 a file with EEXIST (regardless of link actually works or not) */
659 if (symlink("exists", "slinktoexists") == -1) e(42);
660 if (open("slinktoexists", O_RDWR
| O_CREAT
| O_EXCL
, 0777) != -1) e(43);
661 if (unlink("exists") == -1) e(44);
662 /* "slinktoexists has become a dangling symlink. open(2) should still fail
664 if (open("slinktoexists", O_RDWR
| O_CREAT
| O_EXCL
, 0777) != -1) e(45);
665 if (errno
!= EEXIST
) e(46);
668 /* Test ToLongName and ToLongPath */
669 does_truncate
= does_fs_truncate();
670 fd
= open(ToLongName
, O_RDWR
| O_CREAT
, 0777);
673 if (close(fd
) != 0) e(48);
676 (void) close(fd
); /* Just in case */
679 ToLongPath
[PATH_MAX
- 2] = '/';
680 ToLongPath
[PATH_MAX
- 1] = 'a';
681 if ((fd
= open(ToLongPath
, O_RDWR
| O_CREAT
, 0777)) != -1) e(50);
682 if (errno
!= ENAMETOOLONG
) e(51);
683 if (close(fd
) != -1) e(52);
684 ToLongPath
[PATH_MAX
- 1] = '/';
692 max_name_length
= name_max("."); /* Aka NAME_MAX, but not every FS supports
693 * the same length, hence runtime check */
694 MaxName
= malloc(max_name_length
+ 1);
695 ToLongName
= malloc(max_name_length
+ 1 + 1); /* Name of maximum +1 length */
696 memset(MaxName
, 'a', max_name_length
);
697 MaxName
[max_name_length
] = '\0';
699 for (i
= 0; i
< PATH_MAX
- 1; i
++) { /* idem path */
703 MaxPath
[PATH_MAX
- 1] = '\0';
705 strcpy(ToLongName
, MaxName
); /* copy them Max to ToLong */
706 strcpy(ToLongPath
, MaxPath
);
708 ToLongName
[max_name_length
] = 'a';
709 ToLongName
[max_name_length
+1] = '\0';/* extend ToLongName by one too many */
710 ToLongPath
[PATH_MAX
- 1] = '/';
711 ToLongPath
[PATH_MAX
] = '\0'; /* inc ToLongPath by one */