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;
50 unsigned int i;
51 int lc;
52
53 tst_parse_opts(ac, av, NULL, NULL);
54
55 setup();
56
57 /* check for looping state if -i option is given */
58 for (lc = 0; TEST_LOOPING(lc); lc++) {
59
60 tst_count = 0;
61
62 mypid = getpid();
63 for (i = 0; i < 8; i++) {
64 sprintf(fname, "./fcntl%d.%d", i, mypid);
65 if ((fd[i] =
66 open(fname, O_WRONLY | O_CREAT, 0666)) == -1)
67 tst_resm(TBROK | TERRNO, "open failed");
68 fd2[i] = fd[i];
69 }
70
71 close(fd[2]);
72 close(fd[3]);
73 close(fd[4]);
74 close(fd[5]);
75
76 if ((fd[2] = fcntl(fd[1], F_DUPFD, 1)) == -1)
77 tst_resm(TFAIL | TERRNO, "fcntl(.., 1) failed");
78
79 if (fd[2] < fd2[2])
80 tst_resm(TFAIL, "new fd has unexpected value: "
81 "got %d, expected greater than %d", fd[2], 5);
82
83 if ((fd[4] = fcntl(fd[1], F_DUPFD, fd2[3])) < 0)
84 tst_resm(TFAIL | TERRNO, "fcntl(.., fd2[3]) failed");
85
86 if (fd[4] < fd2[3])
87 tst_resm(TFAIL, "new fd has unexpected value, got %d, "
88 "expect greater than %d", fd[4], fd2[3]);
89
90 if ((fd[8] = fcntl(fd[1], F_DUPFD, fd2[5])) < 0)
91 tst_resm(TFAIL | TERRNO, "fcntl(.., fd2[5]) failed");
92
93 if (fd[8] != fd2[5])
94 tst_resm(TFAIL, "new fd has unexpected value: "
95 "got %d, expected %d", fd[8], fd2[5]);
96 /* //block1: */
97 flags = fcntl(fd[2], F_GETFL, 0);
98 if ((flags & O_WRONLY) == 0)
99 tst_resm(TFAIL, "unexpected flag 0x%x, expected 0x%x",
100 flags, O_WRONLY);
101
102 /* Check setting of no_delay flag */
103 if (fcntl(fd[2], F_SETFL, O_NDELAY) == -1)
104 tst_resm(TBROK | TERRNO, "fcntl(.., O_NDELAY) failed");
105
106 flags = fcntl(fd[2], F_GETFL, 0);
107 if ((flags & (O_NDELAY | O_WRONLY)) == 0)
108 tst_resm(TFAIL, "unexpected flag 0x%x, expected 0x%x",
109 flags, O_NDELAY | O_WRONLY);
110
111 /* Check of setting append flag */
112 if (fcntl(fd[2], F_SETFL, O_APPEND) == -1)
113 tst_resm(TFAIL | TERRNO, "fcntl(.., O_APPEND) failed");
114
115 flags = fcntl(fd[2], F_GETFL, 0);
116 if ((flags & (O_APPEND | O_WRONLY)) == 0)
117 tst_resm(TFAIL, "unexpected flag ox%x, expected 0x%x",
118 flags, O_APPEND | O_WRONLY);
119
120 /* Check setting flags together */
121 if (fcntl(fd[2], F_SETFL, O_NDELAY | O_APPEND) < 0)
122 tst_resm(TFAIL, "fcntl(.., O_NDELAY|O_APPEND) failed");
123
124 flags = fcntl(fd[2], F_GETFL, 0);
125 if ((flags & (O_NDELAY | O_APPEND | O_WRONLY)) == 0)
126 tst_resm(TFAIL, "unexpected flag 0x%x, expected 0x%x",
127 flags,
128 O_NDELAY | O_APPEND | O_SYNC | O_WRONLY);
129
130 /* Check that flags are not cummulative */
131 if (fcntl(fd[2], F_SETFL, 0) == -1)
132 tst_resm(TFAIL, "fcntl(.., 0) failed");
133
134 flags = fcntl(fd[2], F_GETFL, 0);
135 if ((flags & O_WRONLY) == 0)
136 tst_resm(TFAIL, "unexpected flag 0x%x, expected 0x%x",
137 flags, O_WRONLY);
138
139 /* //block2: */
140 /*
141 * Check ability to set (F_SETFD) the close on exec flag
142 */
143 if ((flags = fcntl(fd[2], F_GETFD, 0)) < 0)
144 tst_resm(TFAIL | TERRNO,
145 "fcntl(.., F_GETFD, ..) #1 failed");
146 if (flags != 0)
147 tst_resm(TFAIL, "unexpected flags got 0x%x expected "
148 "0x%x", flags, 0);
149 if ((flags = fcntl(fd[2], F_SETFD, 1)) == -1)
150 tst_resm(TFAIL, "fcntl(.., F_SETFD, ..) failed");
151 if ((flags = fcntl(fd[2], F_GETFD, 0)) == -1)
152 tst_resm(TFAIL | TERRNO,
153 "fcntl(.., F_GETFD, ..) #2 failed");
154 if (flags != 1)
155 tst_resm(TFAIL, "unexpected flags, got 0x%x, "
156 "expected 0x%x", flags, 1);
157
158 for (i = 0; i < ARRAY_SIZE(fd); i++)
159 close(fd[i]);
160 for (i = 0; i < 8; i++) {
161 sprintf(fname, "./fcntl%u.%d", i, mypid);
162 if ((unlink(fname)) == -1)
163 tst_resm(TFAIL | TERRNO,
164 "unlinking %s failed", fname);
165 }
166 }
167 cleanup();
168 tst_exit();
169 }
170
171 /*
172 * setup
173 * performs all ONE TIME setup for this test
174 */
setup(void)175 void setup(void)
176 {
177 tst_sig(FORK, DEF_HANDLER, cleanup);
178 umask(0);
179 TEST_PAUSE;
180 tst_tmpdir();
181 }
182
cleanup(void)183 void cleanup(void)
184 {
185 tst_rmdir();
186
187 }
188