1 /*
2 *
3 * Copyright (c) International Business Machines Corp., 2001
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
13 * the GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 /*
21 * NAME
22 * dup203.c
23 *
24 * DESCRIPTION
25 * Testcase to check the basic functionality of dup2().
26 *
27 * ALGORITHM
28 * 1. Attempt to dup2() on an open file descriptor.
29 * 2. Attempt to dup2() on a close file descriptor.
30 *
31 * USAGE: <for command-line>
32 * dup203 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
33 * where, -c n : Run n copies concurrently.
34 * -f : Turn off functionality Testing.
35 * -i n : Execute test n times.
36 * -I x : Execute test for x seconds.
37 * -P x : Pause for x seconds between iterations.
38 * -t : Turn on syscall timing.
39 *
40 * HISTORY
41 * 07/2001 Ported by Wayne Boyer
42 *
43 * RESTRICTIONS
44 * NONE
45 */
46
47 #include <fcntl.h>
48 #include <sys/param.h>
49 #include <errno.h>
50 #include <string.h>
51 #include "test.h"
52 #include "safe_macros.h"
53
54 void setup(void);
55 void cleanup(void);
56
57 char *TCID = "dup203";
58 int TST_TOTAL = 1;
59
main(int ac,char ** av)60 int main(int ac, char **av)
61 {
62 int fd0, fd1, fd2, rval;
63 char filename0[40], filename1[40];
64 char buf[40];
65
66 int lc;
67
68 tst_parse_opts(ac, av, NULL, NULL);
69
70 setup();
71
72 for (lc = 0; TEST_LOOPING(lc); lc++) {
73
74 tst_count = 0;
75 //block1:
76 tst_resm(TINFO, "Enter block 1");
77 tst_resm(TINFO, "Test duping over an open fd");
78
79 sprintf(filename0, "dup202.file0.%d\n", getpid());
80 sprintf(filename1, "dup202.file1.%d\n", getpid());
81 unlink(filename0);
82 unlink(filename1);
83
84 if ((fd0 = creat(filename0, 0666)) == -1)
85 tst_brkm(TBROK, cleanup, "cannot create first file");
86 if (write(fd0, filename0, strlen(filename0)) == -1)
87 tst_brkm(TBROK, cleanup, "filename0: write(2) failed");
88
89 if ((fd1 = creat(filename1, 0666)) == -1)
90 tst_brkm(TBROK, cleanup, "Cannot create second file");
91 if (write(fd1, filename1, strlen(filename1)) == -1)
92 tst_brkm(TBROK, cleanup, "filename1: write(2) failed");
93
94 SAFE_CLOSE(cleanup, fd0);
95 if ((fd0 = open(filename0, O_RDONLY)) == -1)
96 tst_brkm(TBROK, cleanup, "open(2) on filename0 failed");
97
98 SAFE_CLOSE(cleanup, fd1);
99 if ((fd1 = open(filename1, O_RDONLY)) == -1)
100 tst_brkm(TBROK, cleanup, "open(2) on filename1 failed");
101
102 TEST(dup2(fd0, fd1));
103
104 if ((fd2 = TEST_RETURN) == -1) {
105 tst_resm(TFAIL, "call failed unexpectedly");
106 } else {
107 if (fd1 != fd2) {
108 tst_resm(TFAIL, "file descriptors don't match");
109 break;
110 }
111
112 memset(buf, 0, sizeof(buf));
113 if (read(fd2, buf, sizeof(buf)) == -1)
114 tst_brkm(TBROK, cleanup, "read(2) failed");
115 if (strcmp(buf, filename0) != 0)
116 tst_resm(TFAIL, "read from file got bad data");
117 tst_resm(TPASS, "dup2 test 1 functionality is correct");
118 }
119
120 close(fd0);
121 close(fd1);
122 close(fd2);
123 unlink(filename0);
124 unlink(filename1);
125
126 tst_resm(TINFO, "Exit block 1");
127
128 //block2:
129 tst_resm(TINFO, "Enter block 2");
130 tst_resm(TINFO, "Test close on exec flag");
131
132 sprintf(filename0, "dup02.%d\n", getpid());
133 unlink(filename0);
134
135 if ((fd0 = creat(filename0, 0666)) == -1) {
136 tst_brkm(TBROK, cleanup, "Cannot create first file");
137 }
138 if (fcntl(fd0, F_SETFD, 1) == -1) {
139 tst_brkm(TBROK, cleanup, "setting close on exec flag "
140 "on fd0 failed");
141 }
142
143 if ((fd2 = creat(filename1, 0666)) == -1) {
144 tst_brkm(TBROK, cleanup, "Cannot create second file");
145 }
146
147 /* SAFE_CLOSE() sets the fd to -1 avoid it here */
148 rval = fd2;
149 SAFE_CLOSE(cleanup, rval);
150
151 TEST(dup2(fd0, fd2));
152
153 if ((fd1 = TEST_RETURN) == -1) {
154 tst_resm(TFAIL, "call failed unexpectedly");
155 } else {
156 if (fd1 != fd2) {
157 tst_resm(TFAIL, "bad dup2 descriptor %d", fd1);
158 break;
159 }
160
161 if ((rval = fcntl(fd1, F_GETFD, 0)) != 0) {
162 tst_resm(TBROK | TERRNO,
163 "fcntl F_GETFD on fd1 failed; expected a "
164 "return value of 0x0, got %#x", rval);
165 break;
166 }
167 if ((rval = (fcntl(fd0, F_GETFL, 0) & O_ACCMODE)) !=
168 O_WRONLY) {
169 tst_resm(TFAIL, "fctnl F_GETFL bad rval on fd0 "
170 "Expected %#x got %#x", O_WRONLY,
171 rval);
172 }
173 tst_resm(TPASS, "dup2 test 2 functionality is correct");
174 }
175
176 close(fd0);
177 close(fd1);
178
179 unlink(filename0);
180 unlink(filename1);
181 tst_resm(TINFO, "Exit block 2");
182 }
183
184 cleanup();
185 tst_exit();
186 }
187
188 /*
189 * setup() - performs all ONE TIME setup for this test.
190 */
setup(void)191 void setup(void)
192 {
193
194 tst_sig(NOFORK, DEF_HANDLER, cleanup);
195
196 TEST_PAUSE;
197
198 tst_tmpdir();
199 }
200
201 /*
202 * cleanup() - performs all ONE TIME cleanup for this test at
203 * completion or premature exit.
204 */
cleanup(void)205 void cleanup(void)
206 {
207 tst_rmdir();
208 }
209