1 /*
2  * NAME
3  *	fcntl01.c
4  *
5  * DESCRIPTION
6  *	Test F_DUPFD, F_SETFL cmds of fcntl
7  *
8  * CALLS
9  *	fcntl
10  *
11  * ALGORITHM
12  *
13  *	1. Testing F_DUPFD cmd with arg less than, equal to, and greater
14  *	   than the next available file descriptor.
15  *
16  *	2. Checking F_SETFL cmd with each valid flag (O_NDELAY, O_APPEND).
17  *
18  *	3. Checking, setting and reading `close on exec' flag.
19  *
20  * USAGE
21  *	fcntl01
22  *
23  * HISTORY
24  *	07/2001 Ported by Wayne Boyer
25  *	09/2002 added fd2 array to remove statid fds
26  *
27  * RESTRICTIONS
28  *	None
29  *
30  */
31 
32 #include <fcntl.h>
33 #include <errno.h>
34 #include <sys/types.h>
35 #include <sys/stat.h>
36 #include "test.h"
37 
38 void setup(void);
39 void cleanup(void);
40 
41 char *TCID = "fcntl01";
42 int TST_TOTAL = 1;
43 
main(int ac,char ** av)44 int main(int ac, char **av)
45 {
46 	int flags;
47 	char fname[40];
48 	int fd[10], fd2[10];
49 	int mypid, i;
50 	int lc;
51 
52 	tst_parse_opts(ac, av, NULL, NULL);
53 
54 	setup();
55 
56 	/* check for looping state if -i option is given */
57 	for (lc = 0; TEST_LOOPING(lc); lc++) {
58 
59 		tst_count = 0;
60 
61 		mypid = getpid();
62 		for (i = 0; i < 8; i++) {
63 			sprintf(fname, "./fcntl%d.%d", i, mypid);
64 			if ((fd[i] =
65 			     open(fname, O_WRONLY | O_CREAT, 0666)) == -1)
66 				tst_resm(TBROK | TERRNO, "open failed");
67 			fd2[i] = fd[i];
68 		}
69 
70 		close(fd[2]);
71 		close(fd[3]);
72 		close(fd[4]);
73 		close(fd[5]);
74 
75 		if ((fd[2] = fcntl(fd[1], F_DUPFD, 1)) == -1)
76 			tst_resm(TFAIL | TERRNO, "fcntl(.., 1) failed");
77 
78 		if (fd[2] < fd2[2])
79 			tst_resm(TFAIL, "new fd has unexpected value: "
80 				 "got %d, expected greater than %d", fd[2], 5);
81 
82 		if ((fd[4] = fcntl(fd[1], F_DUPFD, fd2[3])) < 0)
83 			tst_resm(TFAIL | TERRNO, "fcntl(.., fd2[3]) failed");
84 
85 		if (fd[4] < fd2[3])
86 			tst_resm(TFAIL, "new fd has unexpected value, got %d, "
87 				 "expect greater than %d", fd[4], fd2[3]);
88 
89 		if ((fd[8] = fcntl(fd[1], F_DUPFD, fd2[5])) < 0)
90 			tst_resm(TFAIL | TERRNO, "fcntl(.., fd2[5]) failed");
91 
92 		if (fd[8] != fd2[5])
93 			tst_resm(TFAIL, "new fd has unexpected value: "
94 				 "got %d, expected %d", fd[8], fd2[5]);
95 /* //block1: */
96 		flags = fcntl(fd[2], F_GETFL, 0);
97 		if ((flags & O_WRONLY) == 0)
98 			tst_resm(TFAIL, "unexpected flag 0x%x, expected 0x%x",
99 				 flags, O_WRONLY);
100 
101 		/* Check setting of no_delay flag */
102 		if (fcntl(fd[2], F_SETFL, O_NDELAY) == -1)
103 			tst_resm(TBROK | TERRNO, "fcntl(.., O_NDELAY) failed");
104 
105 		flags = fcntl(fd[2], F_GETFL, 0);
106 		if ((flags & (O_NDELAY | O_WRONLY)) == 0)
107 			tst_resm(TFAIL, "unexpected flag 0x%x, expected 0x%x",
108 				 flags, O_NDELAY | O_WRONLY);
109 
110 		/* Check of setting append flag */
111 		if (fcntl(fd[2], F_SETFL, O_APPEND) == -1)
112 			tst_resm(TFAIL | TERRNO, "fcntl(.., O_APPEND) failed");
113 
114 		flags = fcntl(fd[2], F_GETFL, 0);
115 		if ((flags & (O_APPEND | O_WRONLY)) == 0)
116 			tst_resm(TFAIL, "unexpected flag ox%x, expected 0x%x",
117 				 flags, O_APPEND | O_WRONLY);
118 
119 		/* Check setting flags together */
120 		if (fcntl(fd[2], F_SETFL, O_NDELAY | O_APPEND) < 0)
121 			tst_resm(TFAIL, "fcntl(.., O_NDELAY|O_APPEND) failed");
122 
123 		flags = fcntl(fd[2], F_GETFL, 0);
124 		if ((flags & (O_NDELAY | O_APPEND | O_WRONLY)) == 0)
125 			tst_resm(TFAIL, "unexpected flag 0x%x, expected 0x%x",
126 				 flags,
127 				 O_NDELAY | O_APPEND | O_SYNC | O_WRONLY);
128 
129 		/* Check that flags are not cummulative */
130 		if (fcntl(fd[2], F_SETFL, 0) == -1)
131 			tst_resm(TFAIL, "fcntl(.., 0) failed");
132 
133 		flags = fcntl(fd[2], F_GETFL, 0);
134 		if ((flags & O_WRONLY) == 0)
135 			tst_resm(TFAIL, "unexpected flag 0x%x, expected 0x%x",
136 				 flags, O_WRONLY);
137 
138 /* //block2: */
139 		/*
140 		 * Check ability to set (F_SETFD) the close on exec flag
141 		 */
142 		if ((flags = fcntl(fd[2], F_GETFD, 0)) < 0)
143 			tst_resm(TFAIL | TERRNO,
144 				 "fcntl(.., F_GETFD, ..) #1 failed");
145 		if (flags != 0)
146 			tst_resm(TFAIL, "unexpected flags got 0x%x expected "
147 				 "0x%x", flags, 0);
148 		if ((flags = fcntl(fd[2], F_SETFD, 1)) == -1)
149 			tst_resm(TFAIL, "fcntl(.., F_SETFD, ..) failed");
150 		if ((flags = fcntl(fd[2], F_GETFD, 0)) == -1)
151 			tst_resm(TFAIL | TERRNO,
152 				 "fcntl(.., F_GETFD, ..) #2 failed");
153 		if (flags != 1)
154 			tst_resm(TFAIL, "unexpected flags, got 0x%x, "
155 				 "expected 0x%x", flags, 1);
156 
157 		for (i = 0; i < ARRAY_SIZE(fd); i++)
158 			close(fd[i]);
159 		for (i = 0; i < 8; i++) {
160 			sprintf(fname, "./fcntl%d.%d", i, mypid);
161 			if ((unlink(fname)) == -1)
162 				tst_resm(TFAIL | TERRNO,
163 					 "unlinking %s failed", fname);
164 		}
165 	}
166 	cleanup();
167 	tst_exit();
168 }
169 
170 /*
171  * setup
172  *	performs all ONE TIME setup for this test
173  */
setup(void)174 void setup(void)
175 {
176 	tst_sig(FORK, DEF_HANDLER, cleanup);
177 	umask(0);
178 	TEST_PAUSE;
179 	tst_tmpdir();
180 }
181 
cleanup(void)182 void cleanup(void)
183 {
184 	tst_rmdir();
185 
186 }
187