xref: /minix3/minix/tests/test29.c (revision 433d6423c39e34ec4b79c950597bb2d236f886be)
1*433d6423SLionel Sambuc /* test29: dup() dup2()		Author: Jan-Mark Wams (jms@cs.vu.nl) */
2*433d6423SLionel Sambuc 
3*433d6423SLionel Sambuc /* The definition of ``dup2()'' is realy a big mess! For:
4*433d6423SLionel Sambuc **
5*433d6423SLionel Sambuc ** (1) if fildes2 is less than zero or greater than {OPEN_MAX}
6*433d6423SLionel Sambuc **     errno has to set to [EBADF]. But if fildes2 equals {OPEN_MAX}
7*433d6423SLionel Sambuc **     errno has to be set to [EINVAL]. And ``fcntl(F_DUPFD...)'' always
8*433d6423SLionel Sambuc **     returns [EINVAL] if fildes2 is out of range!
9*433d6423SLionel Sambuc **
10*433d6423SLionel Sambuc ** (2) if the number of file descriptors would exceed {OPEN_MAX}, or no
11*433d6423SLionel Sambuc **     file descriptors above fildes2 are available, errno has to be set
12*433d6423SLionel Sambuc **     to [EMFILE]. But this can never occur!
13*433d6423SLionel Sambuc */
14*433d6423SLionel Sambuc 
15*433d6423SLionel Sambuc #include <sys/types.h>
16*433d6423SLionel Sambuc #include <sys/stat.h>
17*433d6423SLionel Sambuc #include <sys/wait.h>
18*433d6423SLionel Sambuc #include <stdlib.h>
19*433d6423SLionel Sambuc #include <unistd.h>
20*433d6423SLionel Sambuc #include <string.h>
21*433d6423SLionel Sambuc #include <fcntl.h>
22*433d6423SLionel Sambuc #include <limits.h>
23*433d6423SLionel Sambuc #include <errno.h>
24*433d6423SLionel Sambuc #include <time.h>
25*433d6423SLionel Sambuc #include <stdio.h>
26*433d6423SLionel Sambuc 
27*433d6423SLionel Sambuc int max_error = 	4;
28*433d6423SLionel Sambuc #include "common.h"
29*433d6423SLionel Sambuc 
30*433d6423SLionel Sambuc #define ITERATIONS     10
31*433d6423SLionel Sambuc 
32*433d6423SLionel Sambuc #define System(cmd)	if (system(cmd) != 0) printf("``%s'' failed\n", cmd)
33*433d6423SLionel Sambuc #define Chdir(dir)	if (chdir(dir) != 0) printf("Can't goto %s\n", dir)
34*433d6423SLionel Sambuc #define Stat(a,b)	if (stat(a,b) != 0) printf("Can't stat %s\n", a)
35*433d6423SLionel Sambuc 
36*433d6423SLionel Sambuc #define IS_CLOEXEC(fd)	((fcntl(fd, F_GETFD) & FD_CLOEXEC) == FD_CLOEXEC)
37*433d6423SLionel Sambuc #define SET_CLOEXEC(fd)	fcntl(fd, F_SETFD, FD_CLOEXEC)
38*433d6423SLionel Sambuc 
39*433d6423SLionel Sambuc 
40*433d6423SLionel Sambuc int superuser;
41*433d6423SLionel Sambuc 
42*433d6423SLionel Sambuc void test29a(void);
43*433d6423SLionel Sambuc void test29b(void);
44*433d6423SLionel Sambuc void test29c(void);
45*433d6423SLionel Sambuc 
main(int argc,char * argv[])46*433d6423SLionel Sambuc int main(int argc, char *argv[])
47*433d6423SLionel Sambuc {
48*433d6423SLionel Sambuc   int i, m = 0xFFFF;
49*433d6423SLionel Sambuc 
50*433d6423SLionel Sambuc   sync();
51*433d6423SLionel Sambuc   if (argc == 2) m = atoi(argv[1]);
52*433d6423SLionel Sambuc 
53*433d6423SLionel Sambuc   start(29);
54*433d6423SLionel Sambuc   superuser = (geteuid() == 0);
55*433d6423SLionel Sambuc 
56*433d6423SLionel Sambuc   for (i = 0; i < ITERATIONS; i++) {
57*433d6423SLionel Sambuc 	if (m & 0001) test29a();
58*433d6423SLionel Sambuc 	if (m & 0002) test29b();
59*433d6423SLionel Sambuc 	if (m & 0004) test29c();
60*433d6423SLionel Sambuc   }
61*433d6423SLionel Sambuc   quit();
62*433d6423SLionel Sambuc 
63*433d6423SLionel Sambuc   return(-1);	/* Unreachable */
64*433d6423SLionel Sambuc }
65*433d6423SLionel Sambuc 
test29a()66*433d6423SLionel Sambuc void test29a()
67*433d6423SLionel Sambuc {
68*433d6423SLionel Sambuc   int fd1, fd2, fd3, fd4, fd5;
69*433d6423SLionel Sambuc   struct flock flock;
70*433d6423SLionel Sambuc 
71*433d6423SLionel Sambuc   subtest = 1;
72*433d6423SLionel Sambuc 
73*433d6423SLionel Sambuc   /* Basic checking. */
74*433d6423SLionel Sambuc   if ((fd1 = dup(0)) != 3) e(1);
75*433d6423SLionel Sambuc   if ((fd2 = dup(0)) != 4) e(2);
76*433d6423SLionel Sambuc   if ((fd3 = dup(0)) != 5) e(3);
77*433d6423SLionel Sambuc   if ((fd4 = dup(0)) != 6) e(4);
78*433d6423SLionel Sambuc   if ((fd5 = dup(0)) != 7) e(5);
79*433d6423SLionel Sambuc   if (close(fd2) != 0) e(6);
80*433d6423SLionel Sambuc   if (close(fd4) != 0) e(7);
81*433d6423SLionel Sambuc   if ((fd2 = dup(0)) != 4) e(8);
82*433d6423SLionel Sambuc   if ((fd4 = dup(0)) != 6) e(9);
83*433d6423SLionel Sambuc   if (close(fd1) != 0) e(10);
84*433d6423SLionel Sambuc   if (close(fd3) != 0) e(11);
85*433d6423SLionel Sambuc   if (close(fd5) != 0) e(12);
86*433d6423SLionel Sambuc   if ((fd1 = dup(0)) != 3) e(13);
87*433d6423SLionel Sambuc   if ((fd3 = dup(0)) != 5) e(14);
88*433d6423SLionel Sambuc   if ((fd5 = dup(0)) != 7) e(15);
89*433d6423SLionel Sambuc   if (close(fd1) != 0) e(16);
90*433d6423SLionel Sambuc   if (close(fd2) != 0) e(17);
91*433d6423SLionel Sambuc   if (close(fd3) != 0) e(18);
92*433d6423SLionel Sambuc   if (close(fd4) != 0) e(19);
93*433d6423SLionel Sambuc   if (close(fd5) != 0) e(20);
94*433d6423SLionel Sambuc 
95*433d6423SLionel Sambuc   /* FD_CLOEXEC should be cleared. */
96*433d6423SLionel Sambuc   if ((fd1 = dup(0)) != 3) e(21);
97*433d6423SLionel Sambuc   if (SET_CLOEXEC(fd1) == -1) e(22);
98*433d6423SLionel Sambuc   if (!IS_CLOEXEC(fd1)) e(23);
99*433d6423SLionel Sambuc   if ((fd2 = dup(fd1)) != 4) e(24);
100*433d6423SLionel Sambuc   if ((fd3 = dup(fd2)) != 5) e(25);
101*433d6423SLionel Sambuc   if (IS_CLOEXEC(fd2)) e(26);
102*433d6423SLionel Sambuc   if (IS_CLOEXEC(fd3)) e(27);
103*433d6423SLionel Sambuc   if (SET_CLOEXEC(fd2) == -1) e(28);
104*433d6423SLionel Sambuc   if (!IS_CLOEXEC(fd2)) e(29);
105*433d6423SLionel Sambuc   if (IS_CLOEXEC(fd3)) e(30);
106*433d6423SLionel Sambuc   if (close(fd1) != 0) e(31);
107*433d6423SLionel Sambuc   if (close(fd2) != 0) e(32);
108*433d6423SLionel Sambuc   if (close(fd3) != 0) e(33);
109*433d6423SLionel Sambuc 
110*433d6423SLionel Sambuc   /* Locks should be shared, so we can lock again. */
111*433d6423SLionel Sambuc   System("echo 'Hallo' > file");
112*433d6423SLionel Sambuc   if ((fd1 = open("file", O_RDWR)) != 3) e(34);
113*433d6423SLionel Sambuc   flock.l_whence = SEEK_SET;
114*433d6423SLionel Sambuc   flock.l_start = 0;
115*433d6423SLionel Sambuc   flock.l_len = 10;
116*433d6423SLionel Sambuc   flock.l_type = F_WRLCK;
117*433d6423SLionel Sambuc   if (fcntl(fd1, F_SETLK, &flock) == -1) e(35);
118*433d6423SLionel Sambuc   if (fcntl(fd1, F_SETLK, &flock) == -1) e(36);
119*433d6423SLionel Sambuc   if ((fd2 = dup(fd1)) != 4) e(37);
120*433d6423SLionel Sambuc   if (fcntl(fd1, F_SETLK, &flock) == -1) e(38);
121*433d6423SLionel Sambuc   if (fcntl(fd1, F_GETLK, &flock) == -1) e(39);
122*433d6423SLionel Sambuc #if 0 /* XXX - see test7.c */
123*433d6423SLionel Sambuc   if (flock.l_type != F_WRLCK) e(40);
124*433d6423SLionel Sambuc   if (flock.l_pid != getpid()) e(41);
125*433d6423SLionel Sambuc #endif /* 0 */
126*433d6423SLionel Sambuc   flock.l_type = F_WRLCK;
127*433d6423SLionel Sambuc   if (fcntl(fd2, F_GETLK, &flock) == -1) e(42);
128*433d6423SLionel Sambuc #if 0 /* XXX - see test7.c */
129*433d6423SLionel Sambuc   if (flock.l_type != F_WRLCK) e(43);
130*433d6423SLionel Sambuc   if (flock.l_pid != getpid()) e(44);
131*433d6423SLionel Sambuc #endif /* 0 */
132*433d6423SLionel Sambuc   if (close(fd1) != 0) e(45);
133*433d6423SLionel Sambuc   if (close(fd2) != 0) e(46);
134*433d6423SLionel Sambuc 
135*433d6423SLionel Sambuc   System("rm -rf ../DIR_29/*");
136*433d6423SLionel Sambuc }
137*433d6423SLionel Sambuc 
test29b()138*433d6423SLionel Sambuc void test29b()
139*433d6423SLionel Sambuc {
140*433d6423SLionel Sambuc   int fd;
141*433d6423SLionel Sambuc   char buf[32];
142*433d6423SLionel Sambuc 
143*433d6423SLionel Sambuc   subtest = 2;
144*433d6423SLionel Sambuc 
145*433d6423SLionel Sambuc   /* Test file called ``file''. */
146*433d6423SLionel Sambuc   System("echo 'Hallo!' > file");
147*433d6423SLionel Sambuc 
148*433d6423SLionel Sambuc   /* Check dup2() call with the same fds. Should have no effect. */
149*433d6423SLionel Sambuc   if ((fd = open("file", O_RDONLY)) != 3) e(1);
150*433d6423SLionel Sambuc   if (read(fd, buf, 2) != 2) e(2);
151*433d6423SLionel Sambuc   if (strncmp(buf, "Ha", 2) != 0) e(3);
152*433d6423SLionel Sambuc   if (dup2(fd, fd) != fd) e(4);
153*433d6423SLionel Sambuc   if (read(fd, buf, 2) != 2) e(5);
154*433d6423SLionel Sambuc   if (strncmp(buf, "ll", 2) != 0) e(6);
155*433d6423SLionel Sambuc   if (dup2(fd, fd) != fd) e(7);
156*433d6423SLionel Sambuc   if (read(fd, buf, 2) != 2) e(8);
157*433d6423SLionel Sambuc   if (strncmp(buf, "o!", 2) != 0) e(9);
158*433d6423SLionel Sambuc   if (close(fd) != 0) e(10);
159*433d6423SLionel Sambuc 
160*433d6423SLionel Sambuc   /* If dup2() call fails, the fildes2 argument has to stay open. */
161*433d6423SLionel Sambuc   if ((fd = open("file", O_RDONLY)) != 3) e(11);
162*433d6423SLionel Sambuc   if (read(fd, buf, 2) != 2) e(12);
163*433d6423SLionel Sambuc   if (strncmp(buf, "Ha", 2) != 0) e(13);
164*433d6423SLionel Sambuc   if (dup2(OPEN_MAX + 3, fd) != -1) e(14);
165*433d6423SLionel Sambuc   if (errno != EBADF) e(15);
166*433d6423SLionel Sambuc   if (read(fd, buf, 2) != 2) e(16);
167*433d6423SLionel Sambuc   if (strncmp(buf, "ll", 2) != 0) e(17);
168*433d6423SLionel Sambuc   if (dup2(-4, fd) != -1) e(18);
169*433d6423SLionel Sambuc   if (errno != EBADF) e(19);
170*433d6423SLionel Sambuc   if (read(fd, buf, 2) != 2) e(20);
171*433d6423SLionel Sambuc   if (strncmp(buf, "o!", 2) != 0) e(21);
172*433d6423SLionel Sambuc   if (close(fd) != 0) e(22);
173*433d6423SLionel Sambuc 
174*433d6423SLionel Sambuc   System("rm -rf ../DIR_29/*");
175*433d6423SLionel Sambuc }
176*433d6423SLionel Sambuc 
test29c()177*433d6423SLionel Sambuc void test29c()
178*433d6423SLionel Sambuc {
179*433d6423SLionel Sambuc   int i;
180*433d6423SLionel Sambuc 
181*433d6423SLionel Sambuc   subtest = 3;
182*433d6423SLionel Sambuc 
183*433d6423SLionel Sambuc   /* Check bad arguments to dup() and dup2(). */
184*433d6423SLionel Sambuc   for (i = -OPEN_MAX; i < OPEN_MAX * 2; i++) {
185*433d6423SLionel Sambuc 
186*433d6423SLionel Sambuc 	/* ``i'' is a valid and open fd. */
187*433d6423SLionel Sambuc 	if (i >= 0 && i < 3) continue;
188*433d6423SLionel Sambuc 
189*433d6423SLionel Sambuc 	/* If ``i'' is a valid fd it is not open. */
190*433d6423SLionel Sambuc 	if (dup(i) != -1) e(1);
191*433d6423SLionel Sambuc 	if (errno != EBADF) e(2);
192*433d6423SLionel Sambuc 
193*433d6423SLionel Sambuc 	/* ``i'' Is OPEN_MAX. */
194*433d6423SLionel Sambuc 	if (i == OPEN_MAX) {
195*433d6423SLionel Sambuc 		if (dup2(0, i) != -1) e(3);
196*433d6423SLionel Sambuc 		if (errno != EINVAL) e(4);
197*433d6423SLionel Sambuc 	}
198*433d6423SLionel Sambuc 
199*433d6423SLionel Sambuc 	/* ``i'' Is out of range. */
200*433d6423SLionel Sambuc 	if (i < 0 || i > OPEN_MAX) {
201*433d6423SLionel Sambuc 		if (dup2(0, i) != -1) e(5);
202*433d6423SLionel Sambuc 		if (errno != EBADF) e(6);
203*433d6423SLionel Sambuc 	}
204*433d6423SLionel Sambuc   }
205*433d6423SLionel Sambuc 
206*433d6423SLionel Sambuc   System("rm -rf ../DIR_29/*");
207*433d6423SLionel Sambuc }
208