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