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