1*433d6423SLionel Sambuc /* test 18 */
2*433d6423SLionel Sambuc
3*433d6423SLionel Sambuc /* Comment on usage and program: ark!/mnt/rene/prac/os/unix/comment.changes */
4*433d6423SLionel Sambuc
5*433d6423SLionel Sambuc /* "const.h", created by Rene Montsma and Menno Wilcke */
6*433d6423SLionel Sambuc
7*433d6423SLionel Sambuc #include <sys/types.h> /* needed in struct stat */
8*433d6423SLionel Sambuc #include <sys/stat.h> /* struct stat */
9*433d6423SLionel Sambuc #include <sys/wait.h>
10*433d6423SLionel Sambuc #include <errno.h> /* the error-numbers */
11*433d6423SLionel Sambuc #include <fcntl.h>
12*433d6423SLionel Sambuc #include <stdlib.h>
13*433d6423SLionel Sambuc #include <unistd.h>
14*433d6423SLionel Sambuc #include <string.h>
15*433d6423SLionel Sambuc #include <stdio.h>
16*433d6423SLionel Sambuc #include <limits.h>
17*433d6423SLionel Sambuc #include <assert.h>
18*433d6423SLionel Sambuc #include <sys/uio.h>
19*433d6423SLionel Sambuc
20*433d6423SLionel Sambuc #define NOCRASH 1 /* test11(), 2nd pipe */
21*433d6423SLionel Sambuc #define PDPNOHANG 1 /* test03(), write_standards() */
22*433d6423SLionel Sambuc #define MAXERR 5
23*433d6423SLionel Sambuc
24*433d6423SLionel Sambuc #define USER_ID 12
25*433d6423SLionel Sambuc #define GROUP_ID 1
26*433d6423SLionel Sambuc #define FF 3 /* first free filedes. */
27*433d6423SLionel Sambuc #define USER 1 /* uid */
28*433d6423SLionel Sambuc #define GROUP 0 /* gid */
29*433d6423SLionel Sambuc
30*433d6423SLionel Sambuc #define ARSIZE 256 /* array size */
31*433d6423SLionel Sambuc #define PIPESIZE 3584 /* maxnumber of bytes to be written on pipe */
32*433d6423SLionel Sambuc #define MAXOPEN (OPEN_MAX-3) /* maximum number of extra open files */
33*433d6423SLionel Sambuc #define MAXLINK 0177 /* maximum number of links per file */
34*433d6423SLionel Sambuc #define MASK 0777 /* selects lower nine bits */
35*433d6423SLionel Sambuc #define READ_EOF 0 /* returned by read-call at eof */
36*433d6423SLionel Sambuc
37*433d6423SLionel Sambuc #define OK 0
38*433d6423SLionel Sambuc #define FAIL -1
39*433d6423SLionel Sambuc
40*433d6423SLionel Sambuc #define R 0 /* read (open-call) */
41*433d6423SLionel Sambuc #define W 1 /* write (open-call) */
42*433d6423SLionel Sambuc #define RW 2 /* read & write (open-call) */
43*433d6423SLionel Sambuc
44*433d6423SLionel Sambuc #define RWX 7 /* read & write & execute (mode) */
45*433d6423SLionel Sambuc
46*433d6423SLionel Sambuc #define NIL ""
47*433d6423SLionel Sambuc #define UMASK "umask"
48*433d6423SLionel Sambuc #define CREAT "creat"
49*433d6423SLionel Sambuc #define WRITE "write"
50*433d6423SLionel Sambuc #define WRITEV "writev"
51*433d6423SLionel Sambuc #define READ "read"
52*433d6423SLionel Sambuc #define READV "readv"
53*433d6423SLionel Sambuc #define OPEN "open"
54*433d6423SLionel Sambuc #define CLOSE "close"
55*433d6423SLionel Sambuc #define LSEEK "lseek"
56*433d6423SLionel Sambuc #define ACCESS "access"
57*433d6423SLionel Sambuc #define CHDIR "chdir"
58*433d6423SLionel Sambuc #define CHMOD "chmod"
59*433d6423SLionel Sambuc #define LINK "link"
60*433d6423SLionel Sambuc #define UNLINK "unlink"
61*433d6423SLionel Sambuc #define PIPE "pipe"
62*433d6423SLionel Sambuc #define STAT "stat"
63*433d6423SLionel Sambuc #define FSTAT "fstat"
64*433d6423SLionel Sambuc #define DUP "dup"
65*433d6423SLionel Sambuc #define UTIME "utime"
66*433d6423SLionel Sambuc
67*433d6423SLionel Sambuc int max_error = 2;
68*433d6423SLionel Sambuc #include "common.h"
69*433d6423SLionel Sambuc
70*433d6423SLionel Sambuc
71*433d6423SLionel Sambuc /* "decl.c", created by Rene Montsma and Menno Wilcke */
72*433d6423SLionel Sambuc
73*433d6423SLionel Sambuc /* Used in open_alot, close_alot */
74*433d6423SLionel Sambuc char *file[MAXOPEN];
75*433d6423SLionel Sambuc char *fnames[8] = {"---", "--x", "-w-", "-wx", "r--", "r-x", "rw-", "rwx"},
76*433d6423SLionel Sambuc *dir[8] = {"d---", "d--x", "d-w-", "d-wx", "dr--", "dr-x", "drw-", "drwx"};
77*433d6423SLionel Sambuc
78*433d6423SLionel Sambuc /* Needed for easy creating and deleting of directories */
79*433d6423SLionel Sambuc
80*433d6423SLionel Sambuc /* "test.c", created by Rene Montsma and Menno Wilcke */
81*433d6423SLionel Sambuc
82*433d6423SLionel Sambuc
83*433d6423SLionel Sambuc int main(int argc, char **argv);
84*433d6423SLionel Sambuc void test(void);
85*433d6423SLionel Sambuc void test01(void);
86*433d6423SLionel Sambuc void test02(void);
87*433d6423SLionel Sambuc void test03(void);
88*433d6423SLionel Sambuc void write_standards(int filedes, char a []);
89*433d6423SLionel Sambuc void test04(void);
90*433d6423SLionel Sambuc void read_standards(int filedes, char a []);
91*433d6423SLionel Sambuc void read_more(int filedes, char a []);
92*433d6423SLionel Sambuc void test05(void);
93*433d6423SLionel Sambuc void try_open(char *fname, int mode, int test);
94*433d6423SLionel Sambuc void test06(void);
95*433d6423SLionel Sambuc void test07(void);
96*433d6423SLionel Sambuc void access_standards(void);
97*433d6423SLionel Sambuc void test08(void);
98*433d6423SLionel Sambuc static int iovec_is_equal(struct iovec *x, struct iovec *y, size_t
99*433d6423SLionel Sambuc size);
100*433d6423SLionel Sambuc static size_t iovec_setup(int pattern, struct iovec *iovec, char
101*433d6423SLionel Sambuc *buffer, int count);
102*433d6423SLionel Sambuc static int power(int base, int exponent);
103*433d6423SLionel Sambuc void try_access(char *fname, int mode, int test);
104*433d6423SLionel Sambuc void make_and_fill_dirs(void);
105*433d6423SLionel Sambuc void put_file_in_dir(char *dirname, int mode);
106*433d6423SLionel Sambuc void init_array(char *a);
107*433d6423SLionel Sambuc void clear_array(char *b);
108*433d6423SLionel Sambuc int comp_array(char *a, char *b, int range);
109*433d6423SLionel Sambuc void try_close(int filedes, char *name);
110*433d6423SLionel Sambuc void try_unlink(char *fname);
111*433d6423SLionel Sambuc void Remove(int fdes, char *fname);
112*433d6423SLionel Sambuc int get_mode(char *name);
113*433d6423SLionel Sambuc void check(char *scall, int number);
114*433d6423SLionel Sambuc void put(int nr);
115*433d6423SLionel Sambuc int open_alot(void);
116*433d6423SLionel Sambuc int close_alot(int number);
117*433d6423SLionel Sambuc void clean_up_the_mess(void);
118*433d6423SLionel Sambuc void chmod_8_dirs(int sw);
119*433d6423SLionel Sambuc
120*433d6423SLionel Sambuc /*****************************************************************************
121*433d6423SLionel Sambuc * TEST *
122*433d6423SLionel Sambuc ****************************************************************************/
main(int argc,char ** argv)123*433d6423SLionel Sambuc int main(int argc, char **argv)
124*433d6423SLionel Sambuc {
125*433d6423SLionel Sambuc int n, i;
126*433d6423SLionel Sambuc pid_t child;
127*433d6423SLionel Sambuc
128*433d6423SLionel Sambuc start(18);
129*433d6423SLionel Sambuc
130*433d6423SLionel Sambuc /* Create filenames for MAXOPEN files, the *file[] array. */
131*433d6423SLionel Sambuc for(i = 0; i < MAXOPEN; i++) {
132*433d6423SLionel Sambuc if(asprintf(&file[i], "file%d", i) == -1) {
133*433d6423SLionel Sambuc fprintf(stderr, "asprintf failed\n");
134*433d6423SLionel Sambuc quit();
135*433d6423SLionel Sambuc }
136*433d6423SLionel Sambuc }
137*433d6423SLionel Sambuc
138*433d6423SLionel Sambuc subtest = 0;
139*433d6423SLionel Sambuc child = fork();
140*433d6423SLionel Sambuc if (child == -1) {
141*433d6423SLionel Sambuc e(1);
142*433d6423SLionel Sambuc quit();
143*433d6423SLionel Sambuc } else if (child == 0) {
144*433d6423SLionel Sambuc test();
145*433d6423SLionel Sambuc return(0);
146*433d6423SLionel Sambuc } else {
147*433d6423SLionel Sambuc wait(&n);
148*433d6423SLionel Sambuc clean_up_the_mess();
149*433d6423SLionel Sambuc quit();
150*433d6423SLionel Sambuc }
151*433d6423SLionel Sambuc
152*433d6423SLionel Sambuc return(-1);
153*433d6423SLionel Sambuc }
154*433d6423SLionel Sambuc
test()155*433d6423SLionel Sambuc void test()
156*433d6423SLionel Sambuc {
157*433d6423SLionel Sambuc umask(0); /* not honest, but i always forget */
158*433d6423SLionel Sambuc
159*433d6423SLionel Sambuc test01();
160*433d6423SLionel Sambuc make_and_fill_dirs();
161*433d6423SLionel Sambuc test02();
162*433d6423SLionel Sambuc test03();
163*433d6423SLionel Sambuc test04();
164*433d6423SLionel Sambuc test05();
165*433d6423SLionel Sambuc test06();
166*433d6423SLionel Sambuc test07();
167*433d6423SLionel Sambuc test08();
168*433d6423SLionel Sambuc umask(022);
169*433d6423SLionel Sambuc } /* test */
170*433d6423SLionel Sambuc
171*433d6423SLionel Sambuc /* "t1.c" created by Rene Montsma and Menno Wilcke */
172*433d6423SLionel Sambuc
173*433d6423SLionel Sambuc /*****************************************************************************
174*433d6423SLionel Sambuc * test UMASK *
175*433d6423SLionel Sambuc ****************************************************************************/
test01()176*433d6423SLionel Sambuc void test01()
177*433d6423SLionel Sambuc {
178*433d6423SLionel Sambuc int oldvalue, newvalue, tempvalue;
179*433d6423SLionel Sambuc int nr;
180*433d6423SLionel Sambuc
181*433d6423SLionel Sambuc subtest = 1;
182*433d6423SLionel Sambuc
183*433d6423SLionel Sambuc if ((oldvalue = umask(0777)) != 0) e(1);
184*433d6423SLionel Sambuc
185*433d6423SLionel Sambuc /* Special test: only the lower 9 bits (protection bits) may part- *
186*433d6423SLionel Sambuc * icipate. ~0777 means: 111 000 000 000. Giving this to umask must*
187*433d6423SLionel Sambuc * not change any value. */
188*433d6423SLionel Sambuc
189*433d6423SLionel Sambuc if ((newvalue = umask(~0777)) != 0777) e(2);
190*433d6423SLionel Sambuc if (oldvalue == newvalue) e(3);
191*433d6423SLionel Sambuc
192*433d6423SLionel Sambuc if ((tempvalue = umask(0)) != 0) e(4);
193*433d6423SLionel Sambuc
194*433d6423SLionel Sambuc /* Now test all possible modes of umask on a file */
195*433d6423SLionel Sambuc for (newvalue = MASK; newvalue >= 0; newvalue -= 0111) {
196*433d6423SLionel Sambuc tempvalue = umask(newvalue);
197*433d6423SLionel Sambuc if (tempvalue != oldvalue) {
198*433d6423SLionel Sambuc e(5);
199*433d6423SLionel Sambuc break; /* no use trying more */
200*433d6423SLionel Sambuc } else if ((nr = creat("file01", 0777)) < 0)
201*433d6423SLionel Sambuc e(6);
202*433d6423SLionel Sambuc else {
203*433d6423SLionel Sambuc try_close(nr, "'file01'");
204*433d6423SLionel Sambuc if (get_mode("file01") != (MASK & ~newvalue)) e(7);
205*433d6423SLionel Sambuc try_unlink("file01");
206*433d6423SLionel Sambuc }
207*433d6423SLionel Sambuc oldvalue = newvalue;
208*433d6423SLionel Sambuc }
209*433d6423SLionel Sambuc
210*433d6423SLionel Sambuc /* The loop has terminated with umask(0) */
211*433d6423SLionel Sambuc if ((tempvalue = umask(0)) != 0) e(8);
212*433d6423SLionel Sambuc } /* test01 */
213*433d6423SLionel Sambuc
214*433d6423SLionel Sambuc /*****************************************************************************
215*433d6423SLionel Sambuc * test CREAT *
216*433d6423SLionel Sambuc ****************************************************************************/
test02()217*433d6423SLionel Sambuc void test02()
218*433d6423SLionel Sambuc {
219*433d6423SLionel Sambuc int n, n1, mode;
220*433d6423SLionel Sambuc char a[ARSIZE], b[ARSIZE];
221*433d6423SLionel Sambuc struct stat stbf1;
222*433d6423SLionel Sambuc
223*433d6423SLionel Sambuc subtest = 2;
224*433d6423SLionel Sambuc mode = 0;
225*433d6423SLionel Sambuc /* Create MAXOPEN files, check filedes */
226*433d6423SLionel Sambuc for (n = 0; n < MAXOPEN; n++) {
227*433d6423SLionel Sambuc if (creat(file[n], mode) != FF + n)
228*433d6423SLionel Sambuc e(1);
229*433d6423SLionel Sambuc else {
230*433d6423SLionel Sambuc if (get_mode(file[n]) != mode) e(2);
231*433d6423SLionel Sambuc
232*433d6423SLionel Sambuc /* Change mode of file to standard mode, we want to *
233*433d6423SLionel Sambuc * use a lot (20) of files to be opened later, see *
234*433d6423SLionel Sambuc * open_alot(), close_alot(). */
235*433d6423SLionel Sambuc if (chmod(file[n], 0700) != OK) e(3);
236*433d6423SLionel Sambuc
237*433d6423SLionel Sambuc }
238*433d6423SLionel Sambuc mode = (mode + 0100) % 01000;
239*433d6423SLionel Sambuc }
240*433d6423SLionel Sambuc
241*433d6423SLionel Sambuc /* Already twenty files opened; opening another has to fail */
242*433d6423SLionel Sambuc if (creat("file02", 0777) != FAIL) e(4);
243*433d6423SLionel Sambuc else
244*433d6423SLionel Sambuc if (errno != EMFILE) e(5);;
245*433d6423SLionel Sambuc
246*433d6423SLionel Sambuc
247*433d6423SLionel Sambuc /* Close all files: seems blunt, but it isn't because we've *
248*433d6423SLionel Sambuc * checked all fd's already */
249*433d6423SLionel Sambuc if ((n = close_alot(MAXOPEN)) < MAXOPEN) e(6);
250*433d6423SLionel Sambuc
251*433d6423SLionel Sambuc /* Creat 1 file twice; check */
252*433d6423SLionel Sambuc if ((n = creat("file02", 0777)) < 0) e(7);
253*433d6423SLionel Sambuc else {
254*433d6423SLionel Sambuc init_array(a);
255*433d6423SLionel Sambuc if (write(n, a, ARSIZE) != ARSIZE) e(8);
256*433d6423SLionel Sambuc
257*433d6423SLionel Sambuc if ((n1 = creat("file02", 0755)) < 0) e(9);
258*433d6423SLionel Sambuc else {
259*433d6423SLionel Sambuc /* Fd should be at the top after recreation */
260*433d6423SLionel Sambuc if (lseek(n1, 0L, SEEK_END) != 0) e(10);
261*433d6423SLionel Sambuc else {
262*433d6423SLionel Sambuc /* Try to write on recreated file */
263*433d6423SLionel Sambuc clear_array(b);
264*433d6423SLionel Sambuc
265*433d6423SLionel Sambuc if (lseek(n1, 0L, SEEK_SET) != 0) e(11);
266*433d6423SLionel Sambuc if (write(n1, a, ARSIZE) != ARSIZE) e(12);
267*433d6423SLionel Sambuc
268*433d6423SLionel Sambuc /* In order to read we've to close and open again */
269*433d6423SLionel Sambuc try_close(n1, "'file02' (2nd creation)");
270*433d6423SLionel Sambuc if ((n1 = open("file02", RW)) < 0) e(13);
271*433d6423SLionel Sambuc
272*433d6423SLionel Sambuc /* Continue */
273*433d6423SLionel Sambuc if (lseek(n1, 0L, SEEK_SET) != 0) e(14);
274*433d6423SLionel Sambuc if (read(n1, b, ARSIZE) != ARSIZE) e(15);
275*433d6423SLionel Sambuc
276*433d6423SLionel Sambuc if (comp_array(a, b, ARSIZE) != OK) e(16);
277*433d6423SLionel Sambuc }
278*433d6423SLionel Sambuc if (get_mode("file02") != 0777) e(17);
279*433d6423SLionel Sambuc try_close(n1, "recreated 'file02'");
280*433d6423SLionel Sambuc
281*433d6423SLionel Sambuc }
282*433d6423SLionel Sambuc Remove(n, "file02");
283*433d6423SLionel Sambuc }
284*433d6423SLionel Sambuc
285*433d6423SLionel Sambuc /* Give 'creat' wrong input: dir not searchable */
286*433d6423SLionel Sambuc if (creat("drw-/file02", 0777) != FAIL) e(18);
287*433d6423SLionel Sambuc else
288*433d6423SLionel Sambuc if (errno != EACCES) e(19);
289*433d6423SLionel Sambuc
290*433d6423SLionel Sambuc /* Dir not writable */
291*433d6423SLionel Sambuc if (creat("dr-x/file02", 0777) != FAIL) e(20);
292*433d6423SLionel Sambuc else
293*433d6423SLionel Sambuc if (errno != EACCES) e(21);
294*433d6423SLionel Sambuc
295*433d6423SLionel Sambuc /* File not writable */
296*433d6423SLionel Sambuc if (creat("drwx/r-x", 0777) != FAIL) e(22);
297*433d6423SLionel Sambuc else
298*433d6423SLionel Sambuc if (errno != EACCES) e(23);
299*433d6423SLionel Sambuc
300*433d6423SLionel Sambuc /* Try to creat a dir */
301*433d6423SLionel Sambuc if ((n = creat("dir", 040777)) != FAIL) {
302*433d6423SLionel Sambuc if (fstat(n, &stbf1) != OK) e(24);
303*433d6423SLionel Sambuc else if (stbf1.st_mode != (mode_t) 0100777)
304*433d6423SLionel Sambuc /* Cast because mode is negative :-(.
305*433d6423SLionel Sambuc * HACK DEBUG FIXME: this appears to duplicate
306*433d6423SLionel Sambuc * code in test17.c.
307*433d6423SLionel Sambuc */
308*433d6423SLionel Sambuc e(25);
309*433d6423SLionel Sambuc Remove(n, "dir");
310*433d6423SLionel Sambuc }
311*433d6423SLionel Sambuc
312*433d6423SLionel Sambuc /* We don't consider it to be a bug when creat * does not accept
313*433d6423SLionel Sambuc * tricky modes */
314*433d6423SLionel Sambuc
315*433d6423SLionel Sambuc /* File is an existing dir */
316*433d6423SLionel Sambuc if (creat("drwx", 0777) != FAIL) e(26);
317*433d6423SLionel Sambuc else
318*433d6423SLionel Sambuc if (errno != EISDIR) e(27);
319*433d6423SLionel Sambuc } /* test02 */
320*433d6423SLionel Sambuc
321*433d6423SLionel Sambuc /*****************************************************************************
322*433d6423SLionel Sambuc * test WRITE *
323*433d6423SLionel Sambuc ****************************************************************************/
test03()324*433d6423SLionel Sambuc void test03()
325*433d6423SLionel Sambuc {
326*433d6423SLionel Sambuc int n, n1;
327*433d6423SLionel Sambuc int fd[2];
328*433d6423SLionel Sambuc char a[ARSIZE];
329*433d6423SLionel Sambuc
330*433d6423SLionel Sambuc subtest = 3;
331*433d6423SLionel Sambuc init_array(a);
332*433d6423SLionel Sambuc
333*433d6423SLionel Sambuc /* Test write after a CREAT */
334*433d6423SLionel Sambuc if ((n = creat("file03", 0700)) != FF) e(1);
335*433d6423SLionel Sambuc else {
336*433d6423SLionel Sambuc write_standards(n, a); /* test simple writes, wrong input too */
337*433d6423SLionel Sambuc try_close(n, "'file03'");
338*433d6423SLionel Sambuc }
339*433d6423SLionel Sambuc
340*433d6423SLionel Sambuc /* Test write after an OPEN */
341*433d6423SLionel Sambuc if ((n = open("file03", W)) < 0) e(2);
342*433d6423SLionel Sambuc else
343*433d6423SLionel Sambuc write_standards(n, a); /* test simple writes, wrong input too */
344*433d6423SLionel Sambuc
345*433d6423SLionel Sambuc /* Test write after a DUP */
346*433d6423SLionel Sambuc if ((n1 = dup(n)) < 0) e(3);
347*433d6423SLionel Sambuc else {
348*433d6423SLionel Sambuc write_standards(n1, a);
349*433d6423SLionel Sambuc try_close(n1, "duplicated fd 'file03'");
350*433d6423SLionel Sambuc }
351*433d6423SLionel Sambuc
352*433d6423SLionel Sambuc /* Remove testfile */
353*433d6423SLionel Sambuc Remove(n, "file03");
354*433d6423SLionel Sambuc
355*433d6423SLionel Sambuc /* Test write after a PIPE */
356*433d6423SLionel Sambuc if (pipe(fd) < 0) e(4);
357*433d6423SLionel Sambuc else {
358*433d6423SLionel Sambuc write_standards(fd[1], a);
359*433d6423SLionel Sambuc try_close(fd[0], "'fd[0]'");
360*433d6423SLionel Sambuc try_close(fd[1], "'fd[1]'");
361*433d6423SLionel Sambuc }
362*433d6423SLionel Sambuc
363*433d6423SLionel Sambuc /* Last test: does write check protections ? */
364*433d6423SLionel Sambuc if ((n = open("drwx/r--", R)) < 0) e(5);
365*433d6423SLionel Sambuc else {
366*433d6423SLionel Sambuc if (write(n, a, ARSIZE) != FAIL) e(6);
367*433d6423SLionel Sambuc else
368*433d6423SLionel Sambuc if (errno != EBADF) e(7);
369*433d6423SLionel Sambuc try_close(n, "'drwx/r--'");
370*433d6423SLionel Sambuc }
371*433d6423SLionel Sambuc } /* test03 */
372*433d6423SLionel Sambuc
write_standards(filedes,a)373*433d6423SLionel Sambuc void write_standards(filedes, a)
374*433d6423SLionel Sambuc int filedes;
375*433d6423SLionel Sambuc char a[];
376*433d6423SLionel Sambuc {
377*433d6423SLionel Sambuc
378*433d6423SLionel Sambuc /* Write must return written account of numbers */
379*433d6423SLionel Sambuc if (write(filedes, a, ARSIZE) != ARSIZE) e(80);
380*433d6423SLionel Sambuc
381*433d6423SLionel Sambuc /* Try giving 'write' wrong input */
382*433d6423SLionel Sambuc /* Wrong filedes */
383*433d6423SLionel Sambuc if (write(-1, a, ARSIZE) != FAIL) e(81);
384*433d6423SLionel Sambuc else
385*433d6423SLionel Sambuc if (errno != EBADF) e(82);
386*433d6423SLionel Sambuc
387*433d6423SLionel Sambuc /* Wrong length (illegal) */
388*433d6423SLionel Sambuc #ifndef PDPNOHANG
389*433d6423SLionel Sambuc if (write(filedes, a, -ARSIZE) != FAIL) e(83);
390*433d6423SLionel Sambuc else
391*433d6423SLionel Sambuc if (errno != EINVAL) e(84);
392*433d6423SLionel Sambuc #endif
393*433d6423SLionel Sambuc } /* write_standards */
394*433d6423SLionel Sambuc
395*433d6423SLionel Sambuc
396*433d6423SLionel Sambuc /*****************************************************************************
397*433d6423SLionel Sambuc * test READ *
398*433d6423SLionel Sambuc ****************************************************************************/
test04()399*433d6423SLionel Sambuc void test04()
400*433d6423SLionel Sambuc {
401*433d6423SLionel Sambuc int n, n1, fd[2];
402*433d6423SLionel Sambuc char a[ARSIZE];
403*433d6423SLionel Sambuc
404*433d6423SLionel Sambuc subtest = 4;
405*433d6423SLionel Sambuc
406*433d6423SLionel Sambuc /* Test read after creat */
407*433d6423SLionel Sambuc if ((n = creat("file04", 0700)) != FF) e(1);
408*433d6423SLionel Sambuc else {
409*433d6423SLionel Sambuc /* Closing and opening needed before writing */
410*433d6423SLionel Sambuc try_close(n, "'file04'");
411*433d6423SLionel Sambuc if ((n = open("file04", RW)) < 0) e(2);
412*433d6423SLionel Sambuc
413*433d6423SLionel Sambuc init_array(a);
414*433d6423SLionel Sambuc
415*433d6423SLionel Sambuc if (write(n, a, ARSIZE) != ARSIZE) e(3);
416*433d6423SLionel Sambuc else {
417*433d6423SLionel Sambuc if (lseek(n, 0L, SEEK_SET) != 0) e(4);
418*433d6423SLionel Sambuc read_standards(n, a);
419*433d6423SLionel Sambuc read_more(n, a);
420*433d6423SLionel Sambuc }
421*433d6423SLionel Sambuc try_close(n, "'file04'");
422*433d6423SLionel Sambuc }
423*433d6423SLionel Sambuc
424*433d6423SLionel Sambuc /* Test read after OPEN */
425*433d6423SLionel Sambuc if ((n = open("file04", R)) < 0) e(5);
426*433d6423SLionel Sambuc else {
427*433d6423SLionel Sambuc read_standards(n, a);
428*433d6423SLionel Sambuc read_more(n, a);
429*433d6423SLionel Sambuc try_close(n, "'file04'");
430*433d6423SLionel Sambuc }
431*433d6423SLionel Sambuc
432*433d6423SLionel Sambuc /* Test read after DUP */
433*433d6423SLionel Sambuc if ((n = open("file04", R)) < 0) e(6);
434*433d6423SLionel Sambuc if ((n1 = dup(n)) < 0) e(7);
435*433d6423SLionel Sambuc else {
436*433d6423SLionel Sambuc read_standards(n1, a);
437*433d6423SLionel Sambuc read_more(n1, a);
438*433d6423SLionel Sambuc try_close(n1, "duplicated fd 'file04'");
439*433d6423SLionel Sambuc }
440*433d6423SLionel Sambuc
441*433d6423SLionel Sambuc /* Remove testfile */
442*433d6423SLionel Sambuc Remove(n, "file04");
443*433d6423SLionel Sambuc
444*433d6423SLionel Sambuc /* Test read after pipe */
445*433d6423SLionel Sambuc if (pipe(fd) < 0) e(8);
446*433d6423SLionel Sambuc else {
447*433d6423SLionel Sambuc if (write(fd[1], a, ARSIZE) != ARSIZE) {
448*433d6423SLionel Sambuc e(9);
449*433d6423SLionel Sambuc try_close(fd[1], "'fd[1]'");
450*433d6423SLionel Sambuc } else {
451*433d6423SLionel Sambuc try_close(fd[1], "'fd[1]'");
452*433d6423SLionel Sambuc read_standards(fd[0], a);
453*433d6423SLionel Sambuc }
454*433d6423SLionel Sambuc try_close(fd[0], "'fd[0]'");
455*433d6423SLionel Sambuc }
456*433d6423SLionel Sambuc
457*433d6423SLionel Sambuc /* Last test: try to read a read-protected file */
458*433d6423SLionel Sambuc if ((n = open("drwx/-wx", W)) < 0) e(10);
459*433d6423SLionel Sambuc else {
460*433d6423SLionel Sambuc if (read(n, a, ARSIZE) != FAIL) e(11);
461*433d6423SLionel Sambuc else
462*433d6423SLionel Sambuc if (errno != EBADF) e(12);
463*433d6423SLionel Sambuc try_close(n, "'/drwx/-wx'");
464*433d6423SLionel Sambuc }
465*433d6423SLionel Sambuc } /* test04 */
466*433d6423SLionel Sambuc
read_standards(filedes,a)467*433d6423SLionel Sambuc void read_standards(filedes, a)
468*433d6423SLionel Sambuc int filedes;
469*433d6423SLionel Sambuc char a[];
470*433d6423SLionel Sambuc {
471*433d6423SLionel Sambuc char b[ARSIZE];
472*433d6423SLionel Sambuc
473*433d6423SLionel Sambuc clear_array(b);
474*433d6423SLionel Sambuc if (read(filedes, b, ARSIZE) != ARSIZE) e(85);
475*433d6423SLionel Sambuc else if (comp_array(a, b, ARSIZE) != OK) e(86);
476*433d6423SLionel Sambuc else if (read(filedes, b, ARSIZE) != READ_EOF) e(87);
477*433d6423SLionel Sambuc
478*433d6423SLionel Sambuc /* Try giving read wrong input: wrong filedes */
479*433d6423SLionel Sambuc if (read(FAIL, b, ARSIZE) != FAIL) e(88);
480*433d6423SLionel Sambuc else
481*433d6423SLionel Sambuc if (errno != EBADF) e(89);
482*433d6423SLionel Sambuc
483*433d6423SLionel Sambuc /* Wrong length */
484*433d6423SLionel Sambuc if (read(filedes, b, -ARSIZE) != FAIL) e(90);
485*433d6423SLionel Sambuc else
486*433d6423SLionel Sambuc if (errno != EINVAL) e(91);
487*433d6423SLionel Sambuc } /* read_standards */
488*433d6423SLionel Sambuc
read_more(filedes,a)489*433d6423SLionel Sambuc void read_more(filedes, a)
490*433d6423SLionel Sambuc int filedes;
491*433d6423SLionel Sambuc char a[];
492*433d6423SLionel Sambuc /* Separated from read_standards() because the PIPE test * would fail. */
493*433d6423SLionel Sambuc {
494*433d6423SLionel Sambuc int i;
495*433d6423SLionel Sambuc char b[ARSIZE];
496*433d6423SLionel Sambuc
497*433d6423SLionel Sambuc if (lseek(filedes, (long) (ARSIZE / 2), SEEK_SET) != ARSIZE / 2) e(92);
498*433d6423SLionel Sambuc
499*433d6423SLionel Sambuc clear_array(b);
500*433d6423SLionel Sambuc if (read(filedes, b, ARSIZE) != ARSIZE / 2) e(93);
501*433d6423SLionel Sambuc
502*433d6423SLionel Sambuc for (i = 0; i < ARSIZE / 2; i++)
503*433d6423SLionel Sambuc if (b[i] != a[(ARSIZE / 2) + i]) e(94);
504*433d6423SLionel Sambuc }
505*433d6423SLionel Sambuc
506*433d6423SLionel Sambuc /*****************************************************************************
507*433d6423SLionel Sambuc * test OPEN/CLOSE *
508*433d6423SLionel Sambuc ****************************************************************************/
test05()509*433d6423SLionel Sambuc void test05()
510*433d6423SLionel Sambuc {
511*433d6423SLionel Sambuc int n, n1, mode, fd[2];
512*433d6423SLionel Sambuc char b[ARSIZE];
513*433d6423SLionel Sambuc
514*433d6423SLionel Sambuc subtest = 5;
515*433d6423SLionel Sambuc /* Test open after CREAT */
516*433d6423SLionel Sambuc if ((n = creat("file05", 0700)) != FF) e(1);
517*433d6423SLionel Sambuc else {
518*433d6423SLionel Sambuc if ((n1 = open("file05", RW)) != FF + 1) e(2);
519*433d6423SLionel Sambuc try_close(n1, "'file05' (open after creation)");
520*433d6423SLionel Sambuc
521*433d6423SLionel Sambuc try_close(n, "'file05'");
522*433d6423SLionel Sambuc if ((n = open("file05", R)) != FF) e(3);
523*433d6423SLionel Sambuc else
524*433d6423SLionel Sambuc try_close(n, "'file05' (open after closing)");
525*433d6423SLionel Sambuc
526*433d6423SLionel Sambuc /* Remove testfile */
527*433d6423SLionel Sambuc try_unlink("file05");
528*433d6423SLionel Sambuc }
529*433d6423SLionel Sambuc
530*433d6423SLionel Sambuc /* Test all possible modes, try_open not only opens file (sometimes) *
531*433d6423SLionel Sambuc * but closes files too (when opened) */
532*433d6423SLionel Sambuc if ((n = creat("file05", 0700)) < 0) e(6);
533*433d6423SLionel Sambuc else {
534*433d6423SLionel Sambuc try_close(n, "file05");
535*433d6423SLionel Sambuc for (mode = 0; mode <= 0700; mode += 0100) {
536*433d6423SLionel Sambuc if (chmod("file05", mode) != OK) e(7);
537*433d6423SLionel Sambuc
538*433d6423SLionel Sambuc if (mode <= 0100) {
539*433d6423SLionel Sambuc try_open("file05", R, FAIL);
540*433d6423SLionel Sambuc try_open("file05", W, FAIL);
541*433d6423SLionel Sambuc try_open("file05", RW, FAIL);
542*433d6423SLionel Sambuc } else if (mode >= 0200 && mode <= 0300) {
543*433d6423SLionel Sambuc try_open("file05", R, FAIL);
544*433d6423SLionel Sambuc try_open("file05", W, FF);
545*433d6423SLionel Sambuc try_open("file05", RW, FAIL);
546*433d6423SLionel Sambuc } else if (mode >= 0400 && mode <= 0500) {
547*433d6423SLionel Sambuc try_open("file05", R, FF);
548*433d6423SLionel Sambuc try_open("file05", W, FAIL);
549*433d6423SLionel Sambuc try_open("file05", RW, FAIL);
550*433d6423SLionel Sambuc } else {
551*433d6423SLionel Sambuc try_open("file05", R, FF);
552*433d6423SLionel Sambuc try_open("file05", W, FF);
553*433d6423SLionel Sambuc try_open("file05", RW, FF);
554*433d6423SLionel Sambuc }
555*433d6423SLionel Sambuc }
556*433d6423SLionel Sambuc }
557*433d6423SLionel Sambuc
558*433d6423SLionel Sambuc /* Test opening existing file */
559*433d6423SLionel Sambuc if ((n = open("drwx/rwx", R)) < 0) e(8);
560*433d6423SLionel Sambuc else { /* test close after DUP */
561*433d6423SLionel Sambuc if ((n1 = dup(n)) < 0) e(9);
562*433d6423SLionel Sambuc else {
563*433d6423SLionel Sambuc try_close(n1, "duplicated fd 'drwx/rwx'");
564*433d6423SLionel Sambuc
565*433d6423SLionel Sambuc if (read(n1, b, ARSIZE) != FAIL) e(10);
566*433d6423SLionel Sambuc else
567*433d6423SLionel Sambuc if (errno != EBADF) e(11);
568*433d6423SLionel Sambuc
569*433d6423SLionel Sambuc if (read(n, b, ARSIZE) == FAIL) e(12);/* should read an eof */
570*433d6423SLionel Sambuc }
571*433d6423SLionel Sambuc try_close(n, "'drwx/rwx'");
572*433d6423SLionel Sambuc }
573*433d6423SLionel Sambuc
574*433d6423SLionel Sambuc /* Test close after PIPE */
575*433d6423SLionel Sambuc if (pipe(fd) < 0) e(13);
576*433d6423SLionel Sambuc else {
577*433d6423SLionel Sambuc try_close(fd[1], "duplicated fd 'fd[1]'");
578*433d6423SLionel Sambuc
579*433d6423SLionel Sambuc /* Fd[1] really should be closed now; check */
580*433d6423SLionel Sambuc clear_array(b);
581*433d6423SLionel Sambuc if (read(fd[0], b, ARSIZE) != READ_EOF) e(14);
582*433d6423SLionel Sambuc try_close(fd[0], "duplicated fd 'fd[0]'");
583*433d6423SLionel Sambuc }
584*433d6423SLionel Sambuc
585*433d6423SLionel Sambuc /* Try to open a non-existing file */
586*433d6423SLionel Sambuc if (open("non-file", R) != FAIL) e(15);
587*433d6423SLionel Sambuc else
588*433d6423SLionel Sambuc if (errno != ENOENT) e(16);
589*433d6423SLionel Sambuc
590*433d6423SLionel Sambuc /* Dir does not exist */
591*433d6423SLionel Sambuc if (open("dzzz/file05", R) != FAIL) e(17);
592*433d6423SLionel Sambuc else
593*433d6423SLionel Sambuc if (errno != ENOENT) e(18);
594*433d6423SLionel Sambuc
595*433d6423SLionel Sambuc /* Dir is not searchable */
596*433d6423SLionel Sambuc if ((n = open("drw-/rwx", R)) != FAIL) e(19);
597*433d6423SLionel Sambuc else
598*433d6423SLionel Sambuc if (errno != EACCES) e(20);
599*433d6423SLionel Sambuc
600*433d6423SLionel Sambuc /* Unlink testfile */
601*433d6423SLionel Sambuc try_unlink("file05");
602*433d6423SLionel Sambuc
603*433d6423SLionel Sambuc /* File is not readable */
604*433d6423SLionel Sambuc if (open("drwx/-wx", R) != FAIL) e(21);
605*433d6423SLionel Sambuc else
606*433d6423SLionel Sambuc if (errno != EACCES) e(22);
607*433d6423SLionel Sambuc
608*433d6423SLionel Sambuc /* File is not writable */
609*433d6423SLionel Sambuc if (open("drwx/r-x", W) != FAIL) e(23);
610*433d6423SLionel Sambuc else
611*433d6423SLionel Sambuc if (errno != EACCES) e(24);
612*433d6423SLionel Sambuc
613*433d6423SLionel Sambuc /* Try opening more than MAXOPEN ('extra' (19-8-85)) files */
614*433d6423SLionel Sambuc if ((n = open_alot()) != MAXOPEN) e(25);
615*433d6423SLionel Sambuc else
616*433d6423SLionel Sambuc /* Maximum # of files opened now, another open should fail
617*433d6423SLionel Sambuc * because * all filedescriptors have already been used. */
618*433d6423SLionel Sambuc if (open("drwx/rwx", RW) != FAIL) e(26);
619*433d6423SLionel Sambuc else
620*433d6423SLionel Sambuc if (errno != EMFILE) e(27);
621*433d6423SLionel Sambuc if (close_alot(n) != n) e(28);
622*433d6423SLionel Sambuc
623*433d6423SLionel Sambuc /* Can close make mistakes ? */
624*433d6423SLionel Sambuc if (close(-1) != FAIL) e(29);
625*433d6423SLionel Sambuc else
626*433d6423SLionel Sambuc if (errno != EBADF) e(30);
627*433d6423SLionel Sambuc } /* test05 */
628*433d6423SLionel Sambuc
try_open(fname,mode,test)629*433d6423SLionel Sambuc void try_open(fname, mode, test)
630*433d6423SLionel Sambuc int mode, test;
631*433d6423SLionel Sambuc char *fname;
632*433d6423SLionel Sambuc {
633*433d6423SLionel Sambuc int n;
634*433d6423SLionel Sambuc
635*433d6423SLionel Sambuc if ((n = open(fname, mode)) != test) e(95);
636*433d6423SLionel Sambuc if (n != FAIL) try_close(n, fname); /* cleanup */
637*433d6423SLionel Sambuc } /* try_open */
638*433d6423SLionel Sambuc
639*433d6423SLionel Sambuc /*****************************************************************************
640*433d6423SLionel Sambuc * test LSEEK *
641*433d6423SLionel Sambuc ****************************************************************************/
test06()642*433d6423SLionel Sambuc void test06()
643*433d6423SLionel Sambuc {
644*433d6423SLionel Sambuc char a[ARSIZE], b[ARSIZE];
645*433d6423SLionel Sambuc int fd;
646*433d6423SLionel Sambuc
647*433d6423SLionel Sambuc subtest = 6;
648*433d6423SLionel Sambuc
649*433d6423SLionel Sambuc if ((fd = open("drwx/rwx", RW)) != FF) e(1);
650*433d6423SLionel Sambuc else {
651*433d6423SLionel Sambuc init_array(a);
652*433d6423SLionel Sambuc if (write(fd, a, 10) != 10) e(2);
653*433d6423SLionel Sambuc else {
654*433d6423SLionel Sambuc /* Lseek back to begin file */
655*433d6423SLionel Sambuc if (lseek(fd, 0L, SEEK_SET) != 0) e(3);
656*433d6423SLionel Sambuc else if (read(fd, b, 10) != 10) e(4);
657*433d6423SLionel Sambuc else if (comp_array(a, b, 10) != OK) e(5);
658*433d6423SLionel Sambuc
659*433d6423SLionel Sambuc /* Lseek to endoffile */
660*433d6423SLionel Sambuc if (lseek(fd, 0L, SEEK_END) != 10) e(6);
661*433d6423SLionel Sambuc else if (read(fd, b, 1) != READ_EOF) e(7);
662*433d6423SLionel Sambuc
663*433d6423SLionel Sambuc /* Lseek beyond file */
664*433d6423SLionel Sambuc if (lseek(fd, 10L, SEEK_CUR) != 20) e(8);
665*433d6423SLionel Sambuc else if (write(fd, a, 10) != 10) e(9);
666*433d6423SLionel Sambuc else {
667*433d6423SLionel Sambuc /* Lseek to begin second write */
668*433d6423SLionel Sambuc if (lseek(fd, 20L, SEEK_SET) != 20) e(10);
669*433d6423SLionel Sambuc if (read(fd, b, 10) != 10) e(11);
670*433d6423SLionel Sambuc else if (comp_array(a, b, 10) != OK) e(12);
671*433d6423SLionel Sambuc }
672*433d6423SLionel Sambuc }
673*433d6423SLionel Sambuc
674*433d6423SLionel Sambuc /* Lseek to position before begin of file */
675*433d6423SLionel Sambuc if (lseek(fd, -1L, 0) != FAIL) e(13);
676*433d6423SLionel Sambuc
677*433d6423SLionel Sambuc try_close(fd, "'drwx/rwx'");
678*433d6423SLionel Sambuc }
679*433d6423SLionel Sambuc
680*433d6423SLionel Sambuc /* Lseek on invalid filediscriptor */
681*433d6423SLionel Sambuc if (lseek(-1, 0L, SEEK_SET) != FAIL) e(14);
682*433d6423SLionel Sambuc else
683*433d6423SLionel Sambuc if (errno != EBADF) e(15);
684*433d6423SLionel Sambuc
685*433d6423SLionel Sambuc }
686*433d6423SLionel Sambuc
687*433d6423SLionel Sambuc /*****************************************************************************
688*433d6423SLionel Sambuc * test ACCESS *
689*433d6423SLionel Sambuc ****************************************************************************/
test07()690*433d6423SLionel Sambuc void test07()
691*433d6423SLionel Sambuc {
692*433d6423SLionel Sambuc subtest = 7;
693*433d6423SLionel Sambuc
694*433d6423SLionel Sambuc /* Check with proper parameters */
695*433d6423SLionel Sambuc if (access("drwx/rwx", RWX) != OK) e(1);
696*433d6423SLionel Sambuc
697*433d6423SLionel Sambuc if (access("./././drwx/././rwx", 0) != OK) e(2);
698*433d6423SLionel Sambuc
699*433d6423SLionel Sambuc /* Check 8 files with 8 different modes on 8 accesses */
700*433d6423SLionel Sambuc if (chdir("drwx") != OK) e(3);
701*433d6423SLionel Sambuc
702*433d6423SLionel Sambuc access_standards();
703*433d6423SLionel Sambuc
704*433d6423SLionel Sambuc if (chdir("..") != OK) e(4);
705*433d6423SLionel Sambuc
706*433d6423SLionel Sambuc /* Check several wrong combinations */
707*433d6423SLionel Sambuc /* File does not exist */
708*433d6423SLionel Sambuc if (access("non-file", 0) != FAIL) e(5);
709*433d6423SLionel Sambuc else
710*433d6423SLionel Sambuc if (errno != ENOENT) e(6);
711*433d6423SLionel Sambuc
712*433d6423SLionel Sambuc /* Non-searchable dir */
713*433d6423SLionel Sambuc if (access("drw-/rwx", 0) != FAIL) e(7);
714*433d6423SLionel Sambuc else
715*433d6423SLionel Sambuc if (errno != EACCES) e(8);
716*433d6423SLionel Sambuc
717*433d6423SLionel Sambuc /* Searchable dir, but wrong file-mode */
718*433d6423SLionel Sambuc if (access("drwx/--x", RWX) != FAIL) e(9);
719*433d6423SLionel Sambuc else
720*433d6423SLionel Sambuc if (errno != EACCES) e(10);
721*433d6423SLionel Sambuc
722*433d6423SLionel Sambuc } /* test07 */
723*433d6423SLionel Sambuc
access_standards()724*433d6423SLionel Sambuc void access_standards()
725*433d6423SLionel Sambuc {
726*433d6423SLionel Sambuc int i, mode = 0;
727*433d6423SLionel Sambuc
728*433d6423SLionel Sambuc for (i = 0; i < 8; i++)
729*433d6423SLionel Sambuc if (i == 0)
730*433d6423SLionel Sambuc try_access(fnames[mode], i, OK);
731*433d6423SLionel Sambuc else
732*433d6423SLionel Sambuc try_access(fnames[mode], i, FAIL);
733*433d6423SLionel Sambuc mode++;
734*433d6423SLionel Sambuc
735*433d6423SLionel Sambuc for (i = 0; i < 8; i++)
736*433d6423SLionel Sambuc if (i < 2)
737*433d6423SLionel Sambuc try_access(fnames[mode], i, OK);
738*433d6423SLionel Sambuc else
739*433d6423SLionel Sambuc try_access(fnames[mode], i, FAIL);
740*433d6423SLionel Sambuc mode++;
741*433d6423SLionel Sambuc
742*433d6423SLionel Sambuc for (i = 0; i < 8; i++)
743*433d6423SLionel Sambuc if (i == 0 || i == 2)
744*433d6423SLionel Sambuc try_access(fnames[mode], i, OK);
745*433d6423SLionel Sambuc else
746*433d6423SLionel Sambuc try_access(fnames[mode], i, FAIL);
747*433d6423SLionel Sambuc mode++;
748*433d6423SLionel Sambuc
749*433d6423SLionel Sambuc for (i = 0; i < 8; i++)
750*433d6423SLionel Sambuc if (i < 4)
751*433d6423SLionel Sambuc try_access(fnames[mode], i, OK);
752*433d6423SLionel Sambuc else
753*433d6423SLionel Sambuc try_access(fnames[mode], i, FAIL);
754*433d6423SLionel Sambuc mode++;
755*433d6423SLionel Sambuc
756*433d6423SLionel Sambuc for (i = 0; i < 8; i++)
757*433d6423SLionel Sambuc if (i == 0 || i == 4)
758*433d6423SLionel Sambuc try_access(fnames[mode], i, OK);
759*433d6423SLionel Sambuc else
760*433d6423SLionel Sambuc try_access(fnames[mode], i, FAIL);
761*433d6423SLionel Sambuc mode++;
762*433d6423SLionel Sambuc
763*433d6423SLionel Sambuc for (i = 0; i < 8; i++)
764*433d6423SLionel Sambuc if (i == 0 || i == 1 || i == 4 || i == 5)
765*433d6423SLionel Sambuc try_access(fnames[mode], i, OK);
766*433d6423SLionel Sambuc else
767*433d6423SLionel Sambuc try_access(fnames[mode], i, FAIL);
768*433d6423SLionel Sambuc mode++;
769*433d6423SLionel Sambuc
770*433d6423SLionel Sambuc for (i = 0; i < 8; i++)
771*433d6423SLionel Sambuc if (i % 2 == 0)
772*433d6423SLionel Sambuc try_access(fnames[mode], i, OK);
773*433d6423SLionel Sambuc else
774*433d6423SLionel Sambuc try_access(fnames[mode], i, FAIL);
775*433d6423SLionel Sambuc mode++;
776*433d6423SLionel Sambuc
777*433d6423SLionel Sambuc for (i = 0; i < 8; i++) try_access(fnames[mode], i, OK);
778*433d6423SLionel Sambuc } /* access_standards */
779*433d6423SLionel Sambuc
try_access(fname,mode,test)780*433d6423SLionel Sambuc void try_access(fname, mode, test)
781*433d6423SLionel Sambuc int mode, test;
782*433d6423SLionel Sambuc char *fname;
783*433d6423SLionel Sambuc {
784*433d6423SLionel Sambuc if (access(fname, mode) != test) e(96);
785*433d6423SLionel Sambuc } /* try_access */
786*433d6423SLionel Sambuc
787*433d6423SLionel Sambuc
788*433d6423SLionel Sambuc /* Err, make_and_fill_dirs, init_array, clear_array, comp_array,
789*433d6423SLionel Sambuc try_close, try_unlink, Remove, get_mode, check, open_alot,
790*433d6423SLionel Sambuc close_alot, clean_up_the_mess.
791*433d6423SLionel Sambuc */
792*433d6423SLionel Sambuc
793*433d6423SLionel Sambuc /*****************************************************************************
794*433d6423SLionel Sambuc * test READV/WRITEV *
795*433d6423SLionel Sambuc ****************************************************************************/
796*433d6423SLionel Sambuc #define TEST8_BUFSZCOUNT 3
797*433d6423SLionel Sambuc #define TEST8_BUFSZMAX 65536
798*433d6423SLionel Sambuc #define TEST8_IOVCOUNT 4
799*433d6423SLionel Sambuc
test08()800*433d6423SLionel Sambuc void test08()
801*433d6423SLionel Sambuc {
802*433d6423SLionel Sambuc char buffer_read[TEST8_IOVCOUNT * TEST8_BUFSZMAX];
803*433d6423SLionel Sambuc char buffer_write[TEST8_IOVCOUNT * TEST8_BUFSZMAX];
804*433d6423SLionel Sambuc struct iovec iovec_read[TEST8_IOVCOUNT];
805*433d6423SLionel Sambuc struct iovec iovec_write[TEST8_IOVCOUNT];
806*433d6423SLionel Sambuc int fd, i, j, k, l, m;
807*433d6423SLionel Sambuc ssize_t sz_read, sz_write;
808*433d6423SLionel Sambuc size_t sz_read_exp, sz_read_sum, sz_write_sum;
809*433d6423SLionel Sambuc
810*433d6423SLionel Sambuc subtest = 8;
811*433d6423SLionel Sambuc
812*433d6423SLionel Sambuc /* try various combinations of buffer sizes */
813*433d6423SLionel Sambuc for (i = 0; i <= TEST8_IOVCOUNT; i++)
814*433d6423SLionel Sambuc for (j = 0; j < power(TEST8_BUFSZCOUNT, i); j++)
815*433d6423SLionel Sambuc for (k = 0; k <= TEST8_IOVCOUNT; k++)
816*433d6423SLionel Sambuc for (l = 0; l < power(TEST8_BUFSZCOUNT, k); l++)
817*433d6423SLionel Sambuc {
818*433d6423SLionel Sambuc /* put data in the buffers */
819*433d6423SLionel Sambuc for (m = 0; m < sizeof(buffer_write); m++)
820*433d6423SLionel Sambuc {
821*433d6423SLionel Sambuc buffer_write[m] = m ^ (m >> 8);
822*433d6423SLionel Sambuc buffer_read[m] = ~buffer_write[m];
823*433d6423SLionel Sambuc }
824*433d6423SLionel Sambuc
825*433d6423SLionel Sambuc /* set up the vectors to point to the buffers */
826*433d6423SLionel Sambuc sz_read_sum = iovec_setup(j, iovec_read, buffer_read, i);
827*433d6423SLionel Sambuc sz_write_sum = iovec_setup(l, iovec_write, buffer_write, k);
828*433d6423SLionel Sambuc sz_read_exp = (sz_read_sum < sz_write_sum) ?
829*433d6423SLionel Sambuc sz_read_sum : sz_write_sum;
830*433d6423SLionel Sambuc
831*433d6423SLionel Sambuc /* test reading and writing */
832*433d6423SLionel Sambuc if ((fd = open("file08", O_RDWR | O_CREAT | O_TRUNC, 0644)) < 0) e(1);
833*433d6423SLionel Sambuc else {
834*433d6423SLionel Sambuc sz_write = writev(fd, iovec_write, k);
835*433d6423SLionel Sambuc if (sz_write != sz_write_sum) e(2);
836*433d6423SLionel Sambuc if (lseek(fd, 0, SEEK_SET) != 0) e(3);
837*433d6423SLionel Sambuc sz_read = readv(fd, iovec_read, i);
838*433d6423SLionel Sambuc if (sz_read != sz_read_exp) e(4);
839*433d6423SLionel Sambuc else {
840*433d6423SLionel Sambuc if (!iovec_is_equal(iovec_read, iovec_write, sz_read))
841*433d6423SLionel Sambuc e(5);
842*433d6423SLionel Sambuc }
843*433d6423SLionel Sambuc
844*433d6423SLionel Sambuc /* Remove testfile */
845*433d6423SLionel Sambuc Remove(fd, "file08");
846*433d6423SLionel Sambuc }
847*433d6423SLionel Sambuc }
848*433d6423SLionel Sambuc } /* test08 */
849*433d6423SLionel Sambuc
iovec_is_equal(struct iovec * x,struct iovec * y,size_t size)850*433d6423SLionel Sambuc static int iovec_is_equal(struct iovec *x, struct iovec *y, size_t size)
851*433d6423SLionel Sambuc {
852*433d6423SLionel Sambuc int xpos = 0, xvec = 0, ypos = 0, yvec = 0;
853*433d6423SLionel Sambuc
854*433d6423SLionel Sambuc /* compare byte by byte */
855*433d6423SLionel Sambuc while (size-- > 0)
856*433d6423SLionel Sambuc {
857*433d6423SLionel Sambuc /* skip over zero-byte buffers and those that have been completed */
858*433d6423SLionel Sambuc while (xpos >= x[xvec].iov_len)
859*433d6423SLionel Sambuc {
860*433d6423SLionel Sambuc xpos -= x[xvec++].iov_len;
861*433d6423SLionel Sambuc assert(xvec < TEST8_IOVCOUNT);
862*433d6423SLionel Sambuc }
863*433d6423SLionel Sambuc while (ypos >= y[yvec].iov_len)
864*433d6423SLionel Sambuc {
865*433d6423SLionel Sambuc ypos -= y[yvec++].iov_len;
866*433d6423SLionel Sambuc assert(yvec < TEST8_IOVCOUNT);
867*433d6423SLionel Sambuc }
868*433d6423SLionel Sambuc
869*433d6423SLionel Sambuc /* compare */
870*433d6423SLionel Sambuc if (((char *) x[xvec].iov_base)[xpos++] !=
871*433d6423SLionel Sambuc ((char *) y[yvec].iov_base)[ypos++])
872*433d6423SLionel Sambuc return 0;
873*433d6423SLionel Sambuc }
874*433d6423SLionel Sambuc
875*433d6423SLionel Sambuc /* no difference found */
876*433d6423SLionel Sambuc return 1;
877*433d6423SLionel Sambuc }
878*433d6423SLionel Sambuc
iovec_setup(int pattern,struct iovec * iovec,char * buffer,int count)879*433d6423SLionel Sambuc static size_t iovec_setup(int pattern, struct iovec *iovec, char *buffer, int count)
880*433d6423SLionel Sambuc {
881*433d6423SLionel Sambuc static const size_t bufsizes[TEST8_BUFSZCOUNT] = { 0, 1, TEST8_BUFSZMAX };
882*433d6423SLionel Sambuc int i;
883*433d6423SLionel Sambuc size_t sum = 0;
884*433d6423SLionel Sambuc
885*433d6423SLionel Sambuc /* the pattern specifies each buffer */
886*433d6423SLionel Sambuc for (i = 0; i < TEST8_IOVCOUNT; i++)
887*433d6423SLionel Sambuc {
888*433d6423SLionel Sambuc iovec->iov_base = buffer;
889*433d6423SLionel Sambuc sum += iovec->iov_len = bufsizes[pattern % TEST8_BUFSZCOUNT];
890*433d6423SLionel Sambuc
891*433d6423SLionel Sambuc iovec++;
892*433d6423SLionel Sambuc buffer += TEST8_BUFSZMAX;
893*433d6423SLionel Sambuc pattern /= TEST8_BUFSZCOUNT;
894*433d6423SLionel Sambuc }
895*433d6423SLionel Sambuc
896*433d6423SLionel Sambuc return sum;
897*433d6423SLionel Sambuc }
898*433d6423SLionel Sambuc
power(int base,int exponent)899*433d6423SLionel Sambuc static int power(int base, int exponent)
900*433d6423SLionel Sambuc {
901*433d6423SLionel Sambuc int result = 1;
902*433d6423SLionel Sambuc
903*433d6423SLionel Sambuc /* compute base^exponent */
904*433d6423SLionel Sambuc while (exponent-- > 0)
905*433d6423SLionel Sambuc result *= base;
906*433d6423SLionel Sambuc
907*433d6423SLionel Sambuc return result;
908*433d6423SLionel Sambuc }
909*433d6423SLionel Sambuc
910*433d6423SLionel Sambuc
911*433d6423SLionel Sambuc /*****************************************************************************
912*433d6423SLionel Sambuc * *
913*433d6423SLionel Sambuc * MAKE_AND_FILL_DIRS *
914*433d6423SLionel Sambuc * *
915*433d6423SLionel Sambuc *****************************************************************************/
916*433d6423SLionel Sambuc
make_and_fill_dirs()917*433d6423SLionel Sambuc void make_and_fill_dirs()
918*433d6423SLionel Sambuc /* Create 8 dir.'s: "d---", "d--x", "d-w-", "d-wx", "dr--", "dr-x", *
919*433d6423SLionel Sambuc * "drw-", "drwx". * Then create 8 files
920*433d6423SLionel Sambuc * in "drwx", and some needed files in other dirs. */
921*433d6423SLionel Sambuc {
922*433d6423SLionel Sambuc int mode, i;
923*433d6423SLionel Sambuc
924*433d6423SLionel Sambuc for (i = 0; i < 8; i++) {
925*433d6423SLionel Sambuc mkdir(dir[i], 0700);
926*433d6423SLionel Sambuc chown(dir[i], USER_ID, GROUP_ID);
927*433d6423SLionel Sambuc }
928*433d6423SLionel Sambuc setuid(USER_ID);
929*433d6423SLionel Sambuc setgid(GROUP_ID);
930*433d6423SLionel Sambuc
931*433d6423SLionel Sambuc for (mode = 0; mode < 8; mode++) put_file_in_dir("drwx", mode);
932*433d6423SLionel Sambuc
933*433d6423SLionel Sambuc put_file_in_dir("d-wx", RWX);
934*433d6423SLionel Sambuc put_file_in_dir("dr-x", RWX);
935*433d6423SLionel Sambuc put_file_in_dir("drw-", RWX);
936*433d6423SLionel Sambuc
937*433d6423SLionel Sambuc chmod_8_dirs(8); /* 8 means; 8 different modes */
938*433d6423SLionel Sambuc
939*433d6423SLionel Sambuc } /* make_and_fill_dirs */
940*433d6423SLionel Sambuc
put_file_in_dir(dirname,mode)941*433d6423SLionel Sambuc void put_file_in_dir(dirname, mode)
942*433d6423SLionel Sambuc char *dirname;
943*433d6423SLionel Sambuc int mode;
944*433d6423SLionel Sambuc /* Fill directory 'dirname' with file with mode 'mode'. */
945*433d6423SLionel Sambuc {
946*433d6423SLionel Sambuc int nr;
947*433d6423SLionel Sambuc
948*433d6423SLionel Sambuc if (chdir(dirname) != OK) e(97);
949*433d6423SLionel Sambuc else {
950*433d6423SLionel Sambuc /* Creat the file */
951*433d6423SLionel Sambuc if ((nr = creat(fnames[mode], mode * 0100)) < 0) e(98);
952*433d6423SLionel Sambuc else
953*433d6423SLionel Sambuc try_close(nr, fnames[mode]);
954*433d6423SLionel Sambuc
955*433d6423SLionel Sambuc if (chdir("..") != OK) e(99);
956*433d6423SLionel Sambuc }
957*433d6423SLionel Sambuc } /* put_file_in_dir */
958*433d6423SLionel Sambuc
959*433d6423SLionel Sambuc /*****************************************************************************
960*433d6423SLionel Sambuc * *
961*433d6423SLionel Sambuc * MISCELLANEOUS *
962*433d6423SLionel Sambuc * *
963*433d6423SLionel Sambuc *(all about arrays, 'try_close', 'try_unlink', 'Remove', 'get_mode') *
964*433d6423SLionel Sambuc * *
965*433d6423SLionel Sambuc *****************************************************************************/
966*433d6423SLionel Sambuc
init_array(a)967*433d6423SLionel Sambuc void init_array(a)
968*433d6423SLionel Sambuc char *a;
969*433d6423SLionel Sambuc {
970*433d6423SLionel Sambuc int i;
971*433d6423SLionel Sambuc
972*433d6423SLionel Sambuc i = 0;
973*433d6423SLionel Sambuc while (i++ < ARSIZE) *a++ = 'a' + (i % 26);
974*433d6423SLionel Sambuc } /* init_array */
975*433d6423SLionel Sambuc
clear_array(b)976*433d6423SLionel Sambuc void clear_array(b)
977*433d6423SLionel Sambuc char *b;
978*433d6423SLionel Sambuc {
979*433d6423SLionel Sambuc int i;
980*433d6423SLionel Sambuc
981*433d6423SLionel Sambuc i = 0;
982*433d6423SLionel Sambuc while (i++ < ARSIZE) *b++ = '0';
983*433d6423SLionel Sambuc
984*433d6423SLionel Sambuc } /* clear_array */
985*433d6423SLionel Sambuc
comp_array(a,b,range)986*433d6423SLionel Sambuc int comp_array(a, b, range)
987*433d6423SLionel Sambuc char *a, *b;
988*433d6423SLionel Sambuc int range;
989*433d6423SLionel Sambuc {
990*433d6423SLionel Sambuc assert(range >= 0 && range <= ARSIZE);
991*433d6423SLionel Sambuc
992*433d6423SLionel Sambuc while (range-- && (*a++ == *b++));
993*433d6423SLionel Sambuc if (*--a == *--b)
994*433d6423SLionel Sambuc return(OK);
995*433d6423SLionel Sambuc else
996*433d6423SLionel Sambuc return(FAIL);
997*433d6423SLionel Sambuc } /* comp_array */
998*433d6423SLionel Sambuc
try_close(filedes,name)999*433d6423SLionel Sambuc void try_close(filedes, name)
1000*433d6423SLionel Sambuc int filedes;
1001*433d6423SLionel Sambuc char *name;
1002*433d6423SLionel Sambuc {
1003*433d6423SLionel Sambuc if (close(filedes) != OK) e(100);
1004*433d6423SLionel Sambuc } /* try_close */
1005*433d6423SLionel Sambuc
try_unlink(fname)1006*433d6423SLionel Sambuc void try_unlink(fname)
1007*433d6423SLionel Sambuc char *fname;
1008*433d6423SLionel Sambuc {
1009*433d6423SLionel Sambuc if (unlink(fname) != 0) e(101);
1010*433d6423SLionel Sambuc } /* try_unlink */
1011*433d6423SLionel Sambuc
Remove(fdes,fname)1012*433d6423SLionel Sambuc void Remove(fdes, fname)
1013*433d6423SLionel Sambuc int fdes;
1014*433d6423SLionel Sambuc char *fname;
1015*433d6423SLionel Sambuc {
1016*433d6423SLionel Sambuc try_close(fdes, fname);
1017*433d6423SLionel Sambuc try_unlink(fname);
1018*433d6423SLionel Sambuc } /* Remove */
1019*433d6423SLionel Sambuc
get_mode(name)1020*433d6423SLionel Sambuc int get_mode(name)
1021*433d6423SLionel Sambuc char *name;
1022*433d6423SLionel Sambuc {
1023*433d6423SLionel Sambuc struct stat stbf1;
1024*433d6423SLionel Sambuc
1025*433d6423SLionel Sambuc if (stat(name, &stbf1) != OK) {
1026*433d6423SLionel Sambuc e(102);
1027*433d6423SLionel Sambuc return(stbf1.st_mode); /* return a mode which will cause *
1028*433d6423SLionel Sambuc * error in the calling function *
1029*433d6423SLionel Sambuc * (file/dir bit) */
1030*433d6423SLionel Sambuc } else
1031*433d6423SLionel Sambuc return(stbf1.st_mode & 07777); /* take last 4 bits */
1032*433d6423SLionel Sambuc } /* get_mode */
1033*433d6423SLionel Sambuc
1034*433d6423SLionel Sambuc
1035*433d6423SLionel Sambuc /*****************************************************************************
1036*433d6423SLionel Sambuc * *
1037*433d6423SLionel Sambuc * ALOT-functions *
1038*433d6423SLionel Sambuc * *
1039*433d6423SLionel Sambuc *****************************************************************************/
1040*433d6423SLionel Sambuc
open_alot()1041*433d6423SLionel Sambuc int open_alot()
1042*433d6423SLionel Sambuc {
1043*433d6423SLionel Sambuc int i;
1044*433d6423SLionel Sambuc
1045*433d6423SLionel Sambuc for (i = 0; i < MAXOPEN; i++)
1046*433d6423SLionel Sambuc if (open(file[i], R) == FAIL) break;
1047*433d6423SLionel Sambuc
1048*433d6423SLionel Sambuc if (i == 0)
1049*433d6423SLionel Sambuc e(103);
1050*433d6423SLionel Sambuc return(i);
1051*433d6423SLionel Sambuc } /* open_alot */
1052*433d6423SLionel Sambuc
close_alot(number)1053*433d6423SLionel Sambuc int close_alot(number)
1054*433d6423SLionel Sambuc int number;
1055*433d6423SLionel Sambuc {
1056*433d6423SLionel Sambuc int i, count = 0;
1057*433d6423SLionel Sambuc
1058*433d6423SLionel Sambuc if (number > MAXOPEN) e(104);
1059*433d6423SLionel Sambuc else
1060*433d6423SLionel Sambuc for (i = FF; i < number + FF; i++)
1061*433d6423SLionel Sambuc if (close(i) != OK) count++;
1062*433d6423SLionel Sambuc
1063*433d6423SLionel Sambuc return(number - count); /* return number of closed files */
1064*433d6423SLionel Sambuc } /* close_alot */
1065*433d6423SLionel Sambuc
1066*433d6423SLionel Sambuc /*****************************************************************************
1067*433d6423SLionel Sambuc * *
1068*433d6423SLionel Sambuc * CLEAN UP THE MESS *
1069*433d6423SLionel Sambuc * *
1070*433d6423SLionel Sambuc *****************************************************************************/
1071*433d6423SLionel Sambuc
clean_up_the_mess()1072*433d6423SLionel Sambuc void clean_up_the_mess()
1073*433d6423SLionel Sambuc {
1074*433d6423SLionel Sambuc int i;
1075*433d6423SLionel Sambuc char dirname[6];
1076*433d6423SLionel Sambuc
1077*433d6423SLionel Sambuc /* First remove 'alot' files */
1078*433d6423SLionel Sambuc for (i = 0; i < MAXOPEN; i++) try_unlink(file[i]);
1079*433d6423SLionel Sambuc
1080*433d6423SLionel Sambuc /* Unlink the files in dir 'drwx' */
1081*433d6423SLionel Sambuc if (chdir("drwx") != OK) e(105);
1082*433d6423SLionel Sambuc else {
1083*433d6423SLionel Sambuc for (i = 0; i < 8; i++) try_unlink(fnames[i]);
1084*433d6423SLionel Sambuc if (chdir("..") != OK) e(106);
1085*433d6423SLionel Sambuc }
1086*433d6423SLionel Sambuc
1087*433d6423SLionel Sambuc /* Before unlinking files in some dirs, make them writable */
1088*433d6423SLionel Sambuc chmod_8_dirs(RWX);
1089*433d6423SLionel Sambuc
1090*433d6423SLionel Sambuc /* Unlink files in other dirs */
1091*433d6423SLionel Sambuc try_unlink("d-wx/rwx");
1092*433d6423SLionel Sambuc try_unlink("dr-x/rwx");
1093*433d6423SLionel Sambuc try_unlink("drw-/rwx");
1094*433d6423SLionel Sambuc
1095*433d6423SLionel Sambuc /* Unlink dirs */
1096*433d6423SLionel Sambuc for (i = 0; i < 8; i++) {
1097*433d6423SLionel Sambuc strcpy(dirname, "d");
1098*433d6423SLionel Sambuc strcat(dirname, fnames[i]);
1099*433d6423SLionel Sambuc /* 'dirname' contains the directoryname */
1100*433d6423SLionel Sambuc rmdir(dirname);
1101*433d6423SLionel Sambuc }
1102*433d6423SLionel Sambuc
1103*433d6423SLionel Sambuc /* FINISH */
1104*433d6423SLionel Sambuc } /* clean_up_the_mess */
1105*433d6423SLionel Sambuc
chmod_8_dirs(sw)1106*433d6423SLionel Sambuc void chmod_8_dirs(sw)
1107*433d6423SLionel Sambuc int sw; /* if switch == 8, give all different
1108*433d6423SLionel Sambuc * mode,else the same mode */
1109*433d6423SLionel Sambuc {
1110*433d6423SLionel Sambuc int mode;
1111*433d6423SLionel Sambuc int i;
1112*433d6423SLionel Sambuc
1113*433d6423SLionel Sambuc if (sw == 8)
1114*433d6423SLionel Sambuc mode = 0;
1115*433d6423SLionel Sambuc else
1116*433d6423SLionel Sambuc mode = sw;
1117*433d6423SLionel Sambuc
1118*433d6423SLionel Sambuc for (i = 0; i < 8; i++) {
1119*433d6423SLionel Sambuc chmod(dir[i], 040000 + mode * 0100);
1120*433d6423SLionel Sambuc if (sw == 8) mode++;
1121*433d6423SLionel Sambuc }
1122*433d6423SLionel Sambuc }
1123*433d6423SLionel Sambuc
1124